class TestAuthentication(TestCase): def setUp(self): self.ws = WebSocket(sslopt={'check_hostname': False}) self.ws.connect(url='wss://sim.smogon.com/showdown/websocket') msg = '' while not msg.startswith('|challstr|'): msg = self.ws.recv() self.challstr = msg[msg.find('|challstr|') + len('|challstr|'):] self.ws.settimeout(.5) def test_auth_temp_user(self): username = generate_username() assertion = auth_temp_user(self.challstr, username) login_cmd = f'|/trn {username},0,{assertion}' self.ws.send(login_cmd) self._username_in_msg(username) def test_login(self): with open('ts_auth.txt', 'r') as file: username, password = file.read().splitlines() assertion = login(self.challstr, username, password) login_cmd = f'|/trn {username},0,{assertion}' self.ws.send(login_cmd) self._username_in_msg(username) def _username_in_msg(self, username): msg = '' while not msg.startswith('|updateuser|'): msg = self.ws.recv() self.assertIn(username, msg) def tearDown(self): self.ws.close()
async def get_data_from_local_cache(ws: websocket.WebSocket, data: str): nonce = secrets.token_urlsafe(20).replace("-", "_") # reconstruct the localStorage object that discord has hidden from me to extract games # code borrowed from https://stackoverflow.com/a/53773662/6508769 TYSM for the answer it saved me :P # modified to not modify the client and not to break any TOS msg = runtime_evaluate_json(f""" (function () {{ function g_{nonce}() {{ const iframe = document.createElement('iframe'); document.body.append(iframe); const pd = Object.getOwnPropertyDescriptor(iframe.contentWindow, 'localStorage'); iframe.remove(); return pd; }}; return g_{nonce}().get.apply().{data} }})()""") log.debug("DISCORD_LOCAL_STORAGE_REQUEST: " + str(msg)) ws.send(msg) while True: resp = ws.recv() if 'result' in json.loads(resp): resp_dict = json.loads(resp) break if LOG_SENSITIVE_DATA: log.debug(f"DISCORD_RESPONSE_FOR_{data}: {str(resp_dict)}") return resp_dict['result']['result']['value']
def test(self, port=None, prefix="", scheme="http"): """ kosmos `j.tools.packages.webinterface.test()' :return: """ base_url = "0.0.0.0" if port: base_url = base_url + f":{port}" if prefix: base_url = base_url + f"/{prefix}" url = f"{scheme}://{base_url}" j.servers.threebot.start(background=True) gedis_client = j.clients.gedis.get( name="default", host="127.0.0.1", port=8901, package_name="zerobot.packagemanager" ) gedis_client.actors.package_manager.package_add( j.core.tools.text_replace( "{DIR_BASE}/code/github/threefoldtech/jumpscaleX_core/JumpscaleCore/servers/gedis/pytests/test_package" ) ) gedis_client.reload() print("testing gedis http") assert ( j.clients.http.post( f"{url}/zerobot/test_package/actors/actor/echo", data=b'{"args":{"_input":"hello world"}}', headers={"Content-Type": "application/json"}, ) .read() .decode() == "hello world" ) print("gedis http OK") print("testing gedis websocker") from websocket import WebSocket import ssl ws = WebSocket(sslopt={"cert_reqs": ssl.CERT_NONE}) ws.connect(f"wss://{base_url}/gedis/websocket") assert ws.connected payload = """{ "namespace": "default", "actor": "echo", "command": "actor.echo", "args": {"_input": "hello world"}, "headers": {"response_type":"json"} }""" ws.send(payload) assert ws.recv() == "hello world" print("gedis websocket OK") print("tearDown") gedis_client.actors.package_manager.package_delete("zerobot.test_package") j.servers.threebot.default.stop()
def get_gluware_version(addr): message = None ssl_cert_off = {"cert_reqs": CERT_NONE} # Turn off SSL certificate checking ws = WebSocket(sslopt=ssl_cert_off) try: ws.connect( 'wss://{address}/ControlApi/socket.io/?EIO=3&transport=websocket'. format(address=addr)) except ws_exception.WebSocketBadStatusException as con_error: print('Connection error: {info}'.format(info=con_error)) return ws.send( '421["request",{"service":"DocsService","method":"getVersion","payload":{}}]' ) while True: message = ws.recv() #print(message) if not message: print('Empty message') return if 'gluware_version' in message: break json_string = message[4:-1] json_payload = loads(json_string)['payload'] payload = loads(json_payload) return payload['gluware_version']['semver']
def _heartbeat(self, ws: websocket.WebSocket) -> None: while True: time.sleep(self._HEARTBEAT_SEC) try: ws.send('{"op":"ping"}') except Exception: break
class Slack(object): """Simple class which just allows sending of messages via Slack""" base_url = "https://slack.com/api/" def __init__(self, token=irakli_is_bad): self.token = token response = requests.get(Slack.base_url + 'rtm.start', params={"token": token}) body = response.json() self.channels = {c["name"]: c for c in chain(body["channels"], body["groups"])} url = body["url"] self.socket = WebSocket() self.socket.connect(url) self.socket.settimeout(5) self.message_id = 0 def send_message(self, channel_name, text): """Send a message TODO:? Verify success """ message = json.dumps({"id": self.message_id, "type": "message", "channel": self.channels[channel_name]["id"], "text": text}) self.message_id += 1 self.socket.send(message) def close(self): self.socket.close()
def obs_ws_connect(buffer_queue, host, port, password): ws = WebSocket() try: ws.connect(f'ws://{host}:{port}') ws.send(json.dumps({ "request-type": "GetAuthRequired", "message-id": "1" })) res = json.loads(ws.recv()) if res['status'] != 'ok': buffer_queue.put(('ERR', res['error'])) return None if res.get('authRequired'): sec = base64.b64encode(hashlib.sha256((password + res['salt']).encode('utf-8')).digest()) auth = base64.b64encode(hashlib.sha256(sec + res['challenge'].encode('utf-8')).digest()).decode('utf-8') ws.send(json.dumps({"request-type": "Authenticate", "message-id": '2', "auth": auth})) res = json.loads(ws.recv()) if res['status'] != 'ok': self.buffer_queue.put(('ERR', res['error'])) return None return ws except socket.error as error: buffer_queue.put(('ERR', error)) return None
def send_transaction(self, message: ExonumMessage) -> str: """ Sends a transaction into an Exonum node via WebSocket. Example: >>> response = client.send_websocket_transaction(message) >>> print(response) {"result":"success","response":{"tx_hash":"48b7d71d388f3c2dfa665bcf837e1fa0417ca559fb0163533ea72de6319e61ca"}} Parameters ---------- message: ExonumMessage Prepared and signed an Exonum message. Returns ------- result: str Result of the WebSocket request. If a transaction is correct and it is accepted, it will contain a JSON with a hash of the transaction. """ body_raw = message.signed_raw() if body_raw is None: logger.critical("Attempt to send an unsigned message through websocket.") raise RuntimeError("Attempt to send an unsigned message.") data = json.dumps({"type": "transaction", "payload": {"tx_body": body_raw.hex()}}) ws_client = WebSocket() ws_client.connect(self._address) ws_client.send(data) response = ws_client.recv() ws_client.close() return response
def proxy_socket(ws, path): # create connection to the remote: keep_headers = ['cookie'] request_headers = { name: value for (name, value) in request.headers.items() if name.lower() in keep_headers } pws = WebSocket(enable_multithread=True) pws.connect(f"ws://{SITE_NAME}flexx/ws/{path}", header=request_headers) # start remote handler: remote_handler_thread = threading.Thread(target=remote_handler, args=(ws, pws)) remote_handler_thread.start() # pws = create_connection(f"ws://{SITE_NAME}flexx/{request.full_path}", header=request_headers, class_=MyWebSocket) while not ws.closed: message = ws.receive() if isinstance(message, (bytearray, bytes)): opcode = ABNF.OPCODE_BINARY elif isinstance(message, str): opcode = ABNF.OPCODE_TEXT elif message is None: assert ws.closed break else: raise ValueError('Unknown message type') pws.send(message, opcode=opcode) pws.close() return
def send_message(msg_type, data): panel_config = load_config() ws = WebSocket() ws.connect("ws://" + panel_config['uri'][0] + "/core") message = '{"type": "' + msg_type + '", "data":' + data + '}' ws.send(message) ws.recv() ws.close()
def test_echo(server): ws = WebSocket() ws.connect(f'ws://127.0.0.1:{server}') ws.send('Hello World!') data = json.loads(ws.recv()) assert {'msg': 'Hello World!', 'id': 1} == data data = json.loads(ws.recv()) assert {'msg': 'Hello World!', 'id': 1} == data
class Websocket(Transport): name = 'websocket' def __init__(self, *args, **kwargs): super(Websocket, self).__init__(*args, **kwargs) self.scheme = 'ws' self.connection = WebSocket() self.reading = False self.writing = False self.read_loop = None def get_uri(self): query = {'EIO': '3', 'transport': self.name} if self.client and self.client.sid: query['sid'] = self.client.sid querystring = urllib.parse.urlencode(query) return '%s://%s:%d%s/?%s' % (self.scheme, self.hostname, self.port, self.path, querystring) def loop_read(self): while self.state in ['opening', 'open']: if self.state == 'opening': self.handle_open() packet = self.read() packet = self.parser.decode_packet(packet) self.handle_packet(packet) def do_open(self): self.connection.connect(self.get_uri()) self.read_loop = self.client.start_loop(self.loop_read) def do_close(self): def close(): self.send([Packet(Packet.CLOSE)]) self.client.stop_loop(self.read_loop) if self.state == 'open': close() else: self.once('open', close) def do_send(self, packets): for packet in packets: enc_packet = self.parser.encode_packet(packet) self.write(enc_packet) def read(self): self.reading = True packet = self.connection.recv() return packet def write(self, packet): self.writing = True logger.debug('Sending payload: %s' % repr(packet)) self.connection.send(packet)
class WebSocketApp(object): """ Higher level of APIs are provided. The interface is like JavaScript WebSocket object. """ def __init__(self, url, on_open = None, on_message = None, on_error = None, on_close = None, symbol='btc_cny'): """ url: websocket url. on_open: callable object which is called at opening websocket. this function has one argument. The arugment is this class object. on_message: callbale object which is called when recieved data. on_message has 2 arguments. The 1st arugment is this class object. The passing 2nd arugment is utf-8 string which we get from the server. on_error: callable object which is called when we get error. on_error has 2 arguments. The 1st arugment is this class object. The passing 2nd arugment is exception object. on_close: callable object which is called when closed the connection. this function has one argument. The arugment is this class object. """ self.url = url self.sock = WebSocket() self.sock.connect(self.url) self.symbol = ''.join(symbol.split('_')) self.send("{'event':'addChannel','channel':'ok_%s_depth'}" % self.symbol) def send(self, data): """ send message. data must be utf-8 string or unicode. """ self.sock.send(data) def close(self): """ close websocket connection. """ self.sock.close() def depth(self, symbol='btc_cny'): try: data = self.sock.recv() resp = json.loads(data) return resp[0]['data'] except Exception as e: logging.info("except[%s]" % e) def _run_with_no_err(self, callback, *args): if callback: try: callback(self, *args) except Exception as e: if logger.isEnabledFor(logging.DEBUG): logger.error(e)
def test_socket(self): mock_socket = MockSocket() c = WebSocket('ws://localhost:1234/', MockSocketFactory(mock_socket)) c.connect() c.send("Rock it with HTML5 WebSocket") msg = c.receive() c.close() print(msg)
def unsubscribe(subscription_id: str, web_socket: websocket.WebSocket) -> None: global websocket_app # Send the close messaging through the websocket deregister = {"type": "stop", "id": subscription_id} end_sub = json.dumps(deregister) print(">> " + end_sub) web_socket.send(end_sub) websocket_app.close() websocket_app.keep_running = False
def init_instrument_subscription(instrument_id: str, ws: WebSocket): instrument_data = {"type": "instrument", "id": instrument_id} ws.send(f'sub 1 {json.dumps(instrument_data)}') response = ws.recv() print(response) index = response.split(" ", 1)[0].strip() assert 1 == int(index) code = response.split(" ", 2)[1].strip() assert 'A' == code body = json.loads(response.split(" ", 2)[2]) validator = Draft6Validator(instrument.INSTRUMENT_TOPIC_SCHEMA) validator.validate(body)
def TESTSocketandRequest(token): ws_url = "ws://{}:{}/connectToServer".format(base_url, port) ws = WebSocket() print('*Connecting Socket*') ws.connect(ws_url) print('*Sending Login Token To Authenticate Socket Gateway*') ws.send(dumps({"tok": token})) print('*Socket Connection Status*', ws.recv()) print('Simulating A Demo Requests') TESTRequest() print('Request Submitted') return loads(ws.recv())
class Gateway: def __init__(self, url): self.url = url self.ws = WebSocket() self.close_reason = None self.limiter = GatewayRateLimiter() def __iter__(self): try: self.ws.connect(self.url) except WebSocketError as e: logger.debug("Exception connecting to gateway.", exc_info=True) self.close_reason = CloseReason.exception(e) while self.ws.connected: try: with self.ws.readlock: opcode, data = self.ws.recv_data() except WebSocketError as e: logger.debug("Exception receiving gateway data.", exc_info=True) self.close_reason = CloseReason.exception(e) break if data and opcode == ABNF.OPCODE_CLOSE: self.close_reason = CloseReason.parse(data) break if data and opcode == ABNF.OPCODE_TEXT: decoded_data = data.decode("utf-8") logger.debug("Gateway payload received: %s", decoded_data) yield JsonObject(json.loads(decoded_data)) logger.info("Gateway Closed: %s", self.close_reason) def send(self, data): self.limiter.on_send() payload = json.dumps(data) logger.debug("Gateway payload sent: %s", payload) try: self.ws.send(payload) except WebSocketError: logger.debug("Error sending payload.", exc_info=True) raise NetworkError def close(self, status=1000): # An error is output be websocket-client for non-1000 statuses. # During normal operation we use non-1000 statuses and don't want an error logged. with suppress_logging("websocket"): self.ws.close(status=status)
def on_message(ws: websocket.WebSocket, message: str) -> None: # Socket Event Callbacks, used in WebSocketApp Constructor global timeout_timer global timeout_interval global graphql_subscription global sts_credentials global host global data_handler_function print("### message ###") print("<< " + message) message_object = json.loads(message) message_type = message_object["type"] if message_type == "ka": reset_timer(ws) elif message_type == "connection_ack": timeout_interval = int( json.dumps(message_object["payload"]["connectionTimeoutMs"])) iam_header = _generate_iam_header( canonical_uri="/graphql", request_parameters=json.dumps(graphql_subscription), security_token=sts_credentials["Credentials"]["SessionToken"], aws_access_key=sts_credentials["Credentials"]["AccessKeyId"], aws_secret_key=sts_credentials["Credentials"]["SecretAccessKey"], ) register = { "id": SUBSCRIPTION_ID, "type": "start", "payload": { "data": json.dumps(graphql_subscription), "extensions": { "authorization": iam_header }, }, } start_sub = json.dumps(register) print(">> " + start_sub) ws.send(start_sub) elif message_type == "data": data_handler_function(ws, message) elif message_object["type"] == "error": print("Error from AppSync: " + message_object["payload"])
def sendMsg(w: WebSocket, lock: Lock, msg: Union[str, dict], logg: Logger): try: with lock: if isinstance(msg, dict): msg = dumps(msg, ensure_ascii=False, separators=(',', ':')) if logg: logg.write(f"send Msg to WebSocket: {msg}", currentframe(), "Send Msg To WebSocket") print(msg) w.send(msg) return True except: if logg: logg.write(format_exc(), currentframe(), "Can't send msg to websocket") return False
def _send_command( connection: websocket.WebSocket, command: Union[SamsungTVCommand, Dict[str, Any]], delay: float, ) -> None: if isinstance(command, SamsungTVSleepCommand): time.sleep(command.delay) return if isinstance(command, SamsungTVCommand): payload = command.get_payload() else: payload = json.dumps(command) _LOGGING.debug("SamsungTVWS websocket command: %s", payload) connection.send(payload) time.sleep(delay)
def callback(self, instance, value): print('O switch', instance, 'is', value) app = App.get_running_app() client = WebSocket(sslopt={"cert_reqs": ssl.CERT_NONE}) try: app.start(1000, 0) client.connect(address.ADDRESS_WEBSOCKET) time.sleep(5) client.send(app.gps_location + "\n" + app.username) except Exception as e: print(e) finally: app.stop() client.close() value = False
def pi_boot_fn(): def my_msg_handler(msg): print 'Got "%s"!' % msg socket = WebSocket('ws://localhost:8888/enginebus/were', onmessage=my_msg_handler) socket.onopen = lambda: socket.send('Hello world!') try: asyncore.loop() except KeyboardInterrupt: socket.close()
class Gateway: def __init__(self, url): self.url = url self.ws = WebSocket() def __iter__(self): self.ws.connect(self.url) for data in self.ws: if data: yield data if not self.ws.connected: break def send(self, data): self.ws.send(data) def close(self): self.ws.close()
class WSS: url: str = settings.WEB_SOCKET_SERVER wss: WebSocket = field(init=False) def __post_init__(self): self.wss = WebSocket() def connect(self): self.wss.connect(self.url) message = "Открываем соединение с Web Socket Server" logger.debug(message) self.wss.send(message) def publish(self, message: str, is_mute=False) -> None: is_test = settings.TEST is False is_debug = settings.DEBUG is False is_wss_mute = is_mute is False if is_test and is_debug and is_wss_mute: if self.wss.sock is None: self.connect() self.wss.send(message) def close(self): try: message = "Закрываем соеденение с Web Socket Server" self.wss.send(message) logger.debug(message) self.wss.close() except WebSocketConnectionClosedException: pass
class Client(): _instance = None @staticmethod def Get(): if Client._instance is None: Client._instance = Client() return Client._instance def __init__(self): self.socket = WebSocket() self.userId = random.randint(0, 65536) def Start(self): import configReader serverIp = configReader.ConfigReader.GetVariable('SERVER_IP') serverPort = configReader.ConfigReader.GetVariable('PORT') self.socket.connect('ws://' + serverIp + ':' + serverPort + '/') messageData = {'user_id' : self.userId} message = '[playerJoined, ' + json.dumps(messageData) + ']' self.socket.send(message) engine.Engine.Get().Start() self.Close() def GetMessage(self): messageData = self.socket.recv() return json.loads(messageData) def SendPlayerMovedMessage(self, factor): messageData = {'user_id' : self.userId, 'factor' : factor} message = '[playerMoved, ' + json.dumps(messageData) + ']' self.socket.send(message) def SendPlayerTurnedMessage(self, factor): messageData = {'user_id' : self.userId, 'factor' : factor} message = '[playerTurned, ' + json.dumps(messageData) + ']' self.socket.send(message) def SendPlayerFiredMessage(self): messageData = {'user_id' : self.userId} message = '[playerFired, ' + json.dumps(messageData) + ']' self.socket.send(message) def Close(self): self.socket.close()
def update(): db = MongoClient('213.183.48.116').golos ws = WebSocket() ws.connect('wss://api.golos.cf') print('Starting update') for post in db.posts.find(): ws.send( dumps({ "id": 1, "method": "get_content", "params": [post['author'], post['permlink']] })) ids = post['id'] response = eval(ws.recv())['result'] db.posts.update({'id': ids}, { '$set': { 'reward': response['pending_payout_value'], 'votes': response['net_votes'], 'comments': response['children'] } }) print('Updated post' + str(ids))
def test_websocket(app: Flask, aio: AioHTTP): """Test for websocket""" @app.route('/echo') @websocket def echo(): while True: msg = yield from aio.ws.receive_msg() if msg.tp == aiohttp.MsgType.text: aio.ws.send_str(msg.data) elif msg.tp == aiohttp.MsgType.close: break elif msg.tp == aiohttp.MsgType.error: break with Server(app, aio) as server: ws = WebSocket() ws.connect(server.ws_url('/echo')) try: ws.send('foo') assert 'foo' == ws.recv() finally: ws.close()
class UDPLikeWebSocketClient: def __init__(self, url) -> None: self.ws = WebSocket() self.url = url def try_to_connect(self): try: self.ws.connect(url=self.url) except ConnectionRefusedError: pass def try_to_send(self, d): try: self.ws.send(extend_dumps(d)) except BrokenPipeError: self.ws.close() def silent_send(self, channel, msg): if not self.ws.connected: self.try_to_connect() if not self.ws.connected: return self.try_to_send(dict(msg=msg, channel=channel))
def main(addr): """ Get gluware version with websocket :param addr: ip address of host (str) :return: version (str) """ # Turn off SSL certificate checking ssl_cert_off = {"cert_reqs": CERT_NONE} ws = WebSocket(sslopt=ssl_cert_off) try: ws.connect( 'wss://{address}/ControlApi/socket.io/?EIO=3&transport=websocket'. format(address=addr)) except ws_exception.WebSocketBadStatusException: return except Exception: return ws.send( '421["request",{"service":"DocsService","method":"getVersion","payload":{}}]' ) while True: message = ws.recv() if not message: return if 'gluware_version' in message: break json_string = message[4:-1] json_payload = loads(json_string)['payload'] payload = loads(json_payload) return payload['gluware_version']['semver']
def socket_main(self): port = 7001 try: self.server.bind(('', port)) self.server.listen(100) except Exception as e: print(e) exit() self.socket_list.add(self.server) while True: r, w, e = select(self.socket_list, [], []) for sock in r: if sock == self.server: conn, addr = sock.accept() if WebSocket.handshake(conn): self.socket_list.add(conn) else: data = WebSocket.recv(sock) if not data: self.socket_list.remove(sock) else: WebSocket.send(conn, data)
async def open_friends_page(ws: websocket.WebSocket): # Simulate the user clicking on the "Home" button. msg = runtime_evaluate_json( r"document.querySelector('a[aria-label=\"Home\"][href]').click()") ws.send(msg) ws.recv() # Simulate the user clicking on the "Friends" button. msg = runtime_evaluate_json( r"document.querySelector(\"a[href='/channels/@me']\").click()") ws.send(msg) ws.recv() # Navigates to the PersonWaving icon, goes up two elements, and then selects the second button (All) to show all of # the user's friends. msg = runtime_evaluate_json( r"document.querySelectorAll(\"svg[name='PersonWaving']\")[1].parentElement." r"parentElement.querySelectorAll(\"div[role='button']\")[2].click()") ws.send(msg) ws.recv()
class WdbRequest(object, Bdb): """Wdb debugger main class""" __metaclass__ = MetaWdbRequest def __init__(self, port, skip=None): MetaWdbRequest._last_inst = self try: Bdb.__init__(self, skip=skip) except TypeError: Bdb.__init__(self) self.begun = False self.connected = False self.make_web_socket(port) breaks_per_file_lno = Breakpoint.bplist.values() for bps in breaks_per_file_lno: breaks = list(bps) for bp in breaks: args = bp.file, bp.line, bp.temporary, bp.cond self.set_break(*args) log.info('Resetting break %s' % repr(args)) def make_web_socket(self, port): log.info('Creating WebSocket') self.ws = WebSocket('0.0.0.0', port) def wsgi_trace(self, app, environ, start_response): def wsgi_with_trace(environ, start_response): self.quitting = 0 self.begun = False self.reset() frame = sys._getframe() while frame: frame.f_trace = self.trace_dispatch self.botframe = frame frame = frame.f_back self.stopframe = sys._getframe().f_back self.stoplineno = -1 sys.settrace(self.trace_dispatch) try: appiter = app(environ, start_response) except BdbQuit: sys.settrace(None) start_response('200 OK', [('Content-Type', 'text/html')]) yield '<h1>BdbQuit</h1><p>Wdb was interrupted</p>' else: for item in appiter: yield item hasattr(appiter, 'close') and appiter.close() sys.settrace(None) self.ws.force_close() MetaWdbRequest._last_inst = None return wsgi_with_trace(environ, start_response) def get_file(self, filename, html_escape=True): checkcache(filename) file_ = ''.join(getlines(filename)) if not html_escape: return file_ return escape(file_) def handle_connection(self): if self.connected: try: self.send('Ping') except: log.exception('Ping Failed') self.connected = False if not self.connected: self.ws.wait_for_connect() self.connected = True def get_trace(self, frame, tb, w_code=None): frames = [] stack, current = self.get_stack(frame, tb) for i, (frame, lno) in enumerate(stack): code = frame.f_code filename = code.co_filename if filename == '<wdb>' and w_code: line = w_code else: checkcache(filename) line = getline(filename, lno, frame.f_globals) line = line and line.strip() startlnos = dis.findlinestarts(code) lastlineno = list(startlnos)[-1][1] frames.append({ 'file': filename, 'function': code.co_name, 'flno': code.co_firstlineno, 'llno': lastlineno, 'lno': lno, 'code': escape(line), 'level': i }) return stack, frames, current def interaction( self, frame, tb=None, exception='Wdb', exception_description='Set Trace'): if not self.ws: raise BdbQuit() try: self._interaction( frame, tb, exception, exception_description) except WsError: log.exception('Websocket Error during interaction. Starting again') self.handle_connection() self.interaction( frame, tb, exception, exception_description) def send(self, data): self.ws.send(data) def receive(self): message = None while not message: rv = self.ws.receive() if rv == 'CLOSED': raise WsError message = rv return message def _interaction( self, frame, tb, exception, exception_description): log.debug('Interaction for %r %r %r %r' % ( frame, tb, exception, exception_description)) stack, trace, current_index = self.get_trace(frame, tb) current = trace[current_index] locals_ = map(lambda x: x[0].f_locals, stack) if self.begun: self.send('Trace|%s' % dump({ 'trace': trace, 'cwd': os.getcwd() })) current_file = current['file'] self.send('Check|%s' % dump({ 'name': current_file, 'sha512': sha512(self.get_file(current_file)).hexdigest() })) else: self.begun = True while True: message = self.receive() if '|' in message: pipe = message.index('|') cmd = message[:pipe] data = message[pipe + 1:] else: cmd = message data = '' log.debug('Cmd %s #Data %d' % (cmd, len(data))) if cmd == 'Start': self.send('Init|%s' % dump({ 'cwd': os.getcwd() })) self.send('Title|%s' % dump({ 'title': exception, 'subtitle': exception_description })) self.send('Trace|%s' % dump({ 'trace': trace })) current_file = current['file'] self.send('Check|%s' % dump({ 'name': current_file, 'sha512': sha512(self.get_file(current_file)).hexdigest() })) elif cmd == 'Select': current_index = int(data) current = trace[current_index] current_file = current['file'] self.send('Check|%s' % dump({ 'name': current_file, 'sha512': sha512(self.get_file(current_file)).hexdigest() })) elif cmd == 'File': current_file = current['file'] self.send('Select|%s' % dump({ 'frame': current, 'breaks': self.get_file_breaks(current_file), 'file': self.get_file(current_file), 'name': current_file, 'sha512': sha512(self.get_file(current_file)).hexdigest() })) elif cmd == 'NoFile': self.send('Select|%s' % dump({ 'frame': current, 'breaks': self.get_file_breaks(current['file']) })) elif cmd == 'Inspect': try: thing = reverse_id(int(data)) except: continue self.send('Dump|%s' % dump({ 'for': escape(repr(thing)), 'val': dmp(thing)})) elif cmd == 'Dump': globals_ = dict(stack[current_index][0].f_globals) try: thing = eval(data, globals_, locals_[current_index]) except: continue self.send('Dump|%s' % dump({ 'for': escape(repr(thing)), 'val': dmp(thing)})) elif cmd == 'Trace': self.send('Trace|%s' % dump({ 'trace': trace })) elif cmd == 'Eval': globals_ = dict(stack[current_index][0].f_globals) # Hack for function scope eval globals_.update(locals_[current_index]) globals_.setdefault('_pprint', pprint) globals_.setdefault('_dump', dmp) with capture_output() as (out, err): try: compiled_code = compile(data, '<stdin>', 'single') exec compiled_code in globals_, locals_[current_index] except Exception: type_, value, tb = exc_info() print '%s: %s' % (type_.__name__, str(value)) self.send('Print|%s' % dump({ 'result': escape('\n'.join(out) + '\n'.join(err)) })) elif cmd == 'Ping': self.send('Pong') elif cmd == 'Step': if hasattr(self, 'botframe'): self.set_step() break elif cmd == 'Next': if hasattr(self, 'botframe'): self.set_next(stack[current_index][0]) break elif cmd == 'Continue': if hasattr(self, 'botframe'): self.set_continue() break elif cmd == 'Return': if hasattr(self, 'botframe'): self.set_return(stack[current_index][0]) break elif cmd == 'Until': if hasattr(self, 'botframe'): self.set_until(stack[current_index][0]) break elif cmd in ('TBreak', 'Break'): if ':' in data: fn, lno = data.split(':') else: fn, lno = current['file'], data cond = None if ',' in lno: lno, cond = lno.split(',') cond = cond.lstrip() lno = int(lno) rv = self.set_break(fn, lno, int(cmd == 'TBreak'), cond) if rv is not None: for path in sys.path: rv = self.set_break( os.path.join(path, fn), lno, int(cmd == 'TBreak'), cond) if rv is None: break if rv is None: log.info('Break set at %s:%d [%s]' % (fn, lno, rv)) if fn == current['file']: self.send('BreakSet|%s' % dump({ 'lno': lno, 'cond': cond })) else: self.send('BreakSet|%s' % dump({})) else: self.send('Log|%s' % dump({ 'message': rv })) elif cmd == 'Unbreak': lno = int(data) current_file = current['file'] log.info('Break unset at %s:%d' % (current_file, lno)) self.clear_break(current_file, lno) self.send('BreakUnset|%s' % dump({'lno': lno})) elif cmd == 'Jump': lno = int(data) if current_index != len(trace) - 1: log.error('Must be at bottom frame') continue try: stack[current_index][0].f_lineno = lno except ValueError: log.error('Jump failed') continue trace[current_index]['lno'] = lno self.send('Trace|%s' % dump({ 'trace': trace })) self.send('Select|%s' % dump({ 'frame': current, 'breaks': self.get_file_breaks(current['file']) })) elif cmd == 'Complete': current_file = current['file'] file_ = self.get_file(current_file, False).decode('utf-8') lines = file_.split(u'\n') lno = trace[current_index]['lno'] line_before = lines[lno - 1] indent = len(line_before) - len(line_before.lstrip()) segments = data.split(u'\n') for segment in reversed(segments): line = u' ' * indent + segment lines.insert(lno - 1, line) script = Script( u'\n'.join(lines), lno - 1 + len(segments), len(segments[-1]) + indent, '') try: completions = script.complete() except: self.send('Log|%s' % dump({ 'message': 'Completion failed for %s' % '\n'.join(reversed(segments)) })) else: fun = script.get_in_function_call() self.send('Suggest|%s' % dump({ 'params': { 'params': [p.get_code().replace('\n', '') for p in fun.params], 'index': fun.index, 'module': fun.module.path, 'call_name': fun.call_name} if fun else None, 'completions': [{ 'base': comp.word[ :len(comp.word) - len(comp.complete)], 'complete': comp.complete, 'description': comp.description } for comp in completions if comp.word.endswith( comp.complete)] })) elif cmd == 'Quit': if hasattr(self, 'botframe'): self.set_continue() raise BdbQuit() break else: log.warn('Unknown command %s' % cmd) def user_call(self, frame, argument_list): """This method is called when there is the remote possibility that we ever need to stop in this function.""" if self.stop_here(frame): fun = frame.f_code.co_name log.info('Calling: %r' % fun) self.handle_connection() self.send('Echo|%s' % dump({ 'for': '__call__', 'val': fun})) self.interaction(frame) def user_line(self, frame): """This function is called when we stop or break at this line.""" log.info('Stopping at line %r:%d' % ( frame.f_code.co_filename, frame.f_lineno)) self.handle_connection() log.debug('User Line Interaction for %r' % frame) self.interaction(frame) def user_return(self, frame, return_value): """This function is called when a return trap is set here.""" frame.f_locals['__return__'] = return_value log.info('Returning from %r with value: %r' % ( frame.f_code.co_name, return_value)) self.handle_connection() self.send('Echo|%s' % dump({ 'for': '__return__', 'val': return_value })) self.interaction(frame) def user_exception(self, frame, exc_info): """This function is called if an exception occurs, but only if we are to stop at or just below this level.""" log.error('Exception', exc_info=exc_info) type_, value, tb = exc_info frame.f_locals['__exception__'] = type_, value exception = type_.__name__ exception_description = str(value) self.handle_connection() self.send('Echo|%s' % dump({ 'for': '__exception__', 'val': '%s: %s' % ( exception, exception_description)})) if not self.begun: frame = None self.interaction(frame, tb, exception, exception_description) def do_clear(self, arg): log.info('Closing %r' % arg) self.clear_bpbynumber(arg) def dispatch_exception(self, frame, arg): self.user_exception(frame, arg) if self.quitting: raise BdbQuit return self.trace_dispatch def recursive(self, g, l): # Inspect curent debugger vars through pdb sys.settrace(None) from pdb import Pdb p = Pdb() sys.call_tracing(p.run, ('1/0', g, l)) sys.settrace(self.trace_dispatch) self.lastcmd = p.lastcmd
def socket_send_all(self, data): for sock in self.socket_list: if sock != self.server: WebSocket.send(sock, data)
def send(self, payload, opcode=1): if self.connected: try: WebSocket.send(self, payload, opcode) except socket.error: pass
class Wdb(object, Bdb): """Wdb debugger main class""" __metaclass__ = MetaWdb @property def html(self): with open(os.path.join(RES_PATH, 'wdb.html')) as f: return f.read() def __init__(self, app, skip=None): try: Bdb.__init__(self, skip=skip) except TypeError: Bdb.__init__(self) self.begun = False self.app = app self.ws = WebSocket('0.0.0.0', randint(10000, 60000)) self.connected = False tries = 1 while self.ws == 'FAIL' and tries < 10: tries += 1 self.ws = WebSocket('0.0.0.0', randint(10000, 60000)) def __call__(self, environ, start_response): path = environ.get('PATH_INFO', '') if path.startswith('/__wdb/'): filename = path.replace('/__wdb/', '') log.debug('Getting static "%s"' % filename) return self.static_request( environ, start_response, filename) elif 'text/html' in environ.get('HTTP_ACCEPT', ''): log.debug('Sending fake page (%s) for %s' % ( environ['HTTP_ACCEPT'], path)) return self.first_request(environ, start_response) else: log.debug('Sending real page (%s) for %s' % ( environ.get('HTTP_ACCEPT', ''), path)) return self.handled_request(environ, start_response) def static_request(self, environ, start_response, filename): start_response('200 OK', [('Content-Type', guess_type(filename)[0])]) with open(os.path.join(RES_PATH, filename)) as f: yield f.read() def handled_request(self, environ, start_response): self.quitting = 0 appiter = None try: appiter = self.app(environ, start_response) for item in appiter: yield item if hasattr(appiter, 'close'): appiter.close() except Exception: log.exception('wdb') if hasattr(appiter, 'close'): appiter.close() self.handle_connection() type_, value, tb = exc_info() exception = type_.__name__ exception_description = str(value) self.interaction(None, tb, exception, exception_description) try: start_response('500 INTERNAL SERVER ERROR', [ ('Content-Type', 'text/html')]) yield ( '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">' '<title>500 Internal Server Error</title>' '<h1>Internal Server Error</h1>' '<p>There was an error in your request.</p>') except: pass def first_request(self, environ, start_response): post = 'null' if environ.get('REQUEST_METHOD', '') == 'POST': post = {} body = '' try: length = int(environ.get('CONTENT_LENGTH', '0')) except ValueError: pass else: body = environ['wsgi.input'].read(length) post['enctype'] = environ.get('CONTENT_TYPE', '') if not 'multipart/form-data' in post['enctype']: post['data'] = parse_qs(body) else: post['data'] = body post = dump(post) start_response('200 OK', [('Content-Type', 'text/html')]) yield self.html%dict(port=self.ws.port, post=post) def get_file(self, filename): checkcache(filename) return escape(''.join(getlines(filename))) # WDB def handle_connection(self): if self.connected: ret = None try: self.ws.send('Ping') ret = self.ws.receive() except: log.exception('Ping Failed') self.connected = ret == 'Pong' if not self.connected: self.ws.wait_for_connect() self.connected = True def get_trace(self, frame, tb, w_code=None): frames = [] stack, current = self.get_stack(frame, tb) for i, (frame, lno) in enumerate(stack): code = frame.f_code filename = code.co_filename if filename == '<wdb>' and w_code: line = w_code else: checkcache(filename) line = getline(filename, lno, frame.f_globals) line = line and line.strip() frames.append({ 'file': filename, 'function': code.co_name, 'flno': code.co_firstlineno, 'lno': lno, 'code': escape(line), 'level': i }) return stack, frames, current def interaction( self, frame, tb=None, exception='Wdb', exception_description='Set Trace'): try: self._interaction( frame, tb, exception, exception_description) except WsError: log.exception('Websocket Error during interaction. Starting again') self.handle_connection() self.interaction( frame, tb, exception, exception_description) def _interaction( self, frame, tb, exception, exception_description): stack, trace, current_index = self.get_trace(frame, tb) current = trace[current_index] locals = stack[current_index][0].f_locals if self.begun: self.ws.send('Trace|%s' % dump({ 'trace': trace })) current_file = current['file'] self.ws.send('Check|%s' % dump({ 'name': current_file, 'sha512': sha512(self.get_file(current_file)).hexdigest() })) else: self.begun = True while True: message = self.ws.receive() if '|' in message: pipe = message.index('|') cmd = message[:pipe] data = message[pipe + 1:] else: cmd = message data = '' log.info('Cmd %s #Data %d' % (cmd, len(data))) if cmd == 'Start': self.ws.send('Title|%s' % dump({ 'title': exception, 'subtitle': exception_description })) self.ws.send('Trace|%s' % dump({ 'trace': trace })) current_file = current['file'] self.ws.send('Check|%s' % dump({ 'name': current_file, 'sha512': sha512(self.get_file(current_file)).hexdigest() })) elif cmd == 'Select': current_index = int(data) current = trace[current_index] current_file = current['file'] locals = stack[current_index][0].f_locals self.ws.send('Check|%s' % dump({ 'name': current_file, 'sha512': sha512(self.get_file(current_file)).hexdigest() })) elif cmd == 'File': current_file = current['file'] self.ws.send('File|%s' % dump({ 'file': self.get_file(current_file), 'name': current_file, 'sha512': sha512(self.get_file(current_file)).hexdigest() })) self.ws.send('Select|%s' % dump({ 'frame': current })) elif cmd == 'NoFile': self.ws.send('Select|%s' % dump({ 'frame': current })) elif cmd == 'Inspect': thing = reverse_id(int(data)) self.ws.send('Dump|%s' % dump({ 'for': escape(repr(thing)), 'val': escape(pformat(dict( (key, getattr(thing, key)) for key in dir(thing)))) })) elif cmd == 'Trace': self.ws.send('Trace|%s' % dump(trace)) elif cmd == 'Eval': globals = dict(stack[current_index][0].f_globals) # Hack for function scope eval globals.update(locals) globals.setdefault('pprint', pprint) with capture_output() as (out, err): try: compiled_code = compile(data, '<stdin>', 'single') exec compiled_code in globals, locals except Exception: type_, value, tb = exc_info() print '%s: %s' % (type_.__name__, str(value)) self.ws.send('Print|%s' % dump({ 'result': escape('\n'.join(out) + '\n'.join(err)) })) elif cmd == 'Ping': self.ws.send('Pong') elif cmd == 'Step': if hasattr(self, 'botframe'): self.set_step() break elif cmd == 'Next': if hasattr(self, 'botframe'): self.set_next(stack[current_index][0]) break elif cmd == 'Continue': if hasattr(self, 'botframe'): self.set_continue() break elif cmd == 'Return': if hasattr(self, 'botframe'): self.set_return(stack[current_index][0]) break elif cmd == 'Quit': if hasattr(self, 'botframe'): self.set_continue() self.ws.close() break else: log.warn('Unknown command %s' % cmd) def user_call(self, frame, argument_list): """This method is called when there is the remote possibility that we ever need to stop in this function.""" if self.stop_here(frame): log.warn('CALL') self.handle_connection() self.ws.send('Echo|%s' % dump({ 'for': '__call__', 'val': frame.f_code.co_name})) # self.interaction(frame, first_step=False) def user_line(self, frame): """This function is called when we stop or break at this line.""", if self.stop_here(frame): log.warn('LINE') self.handle_connection() self.interaction(frame) def user_return(self, frame, return_value): """This function is called when a return trap is set here.""" if self.stop_here(frame): log.warn('RETURN') frame.f_locals['__return__'] = return_value self.handle_connection() self.ws.send('Echo|%s' % dump({ 'for': '__return__', 'val': return_value })) self.interaction(frame) def user_exception(self, frame, exc_info): """This function is called if an exception occurs, but only if we are to stop at or just below this level.""" log.error('EXCEPTION', exc_info=exc_info) type_, value, tb = exc_info frame.f_locals['__exception__'] = type_, value exception = type_.__name__ exception_description = str(value) self.handle_connection() self.ws.send('Echo|%s' % dump({ 'for': '__exception__', 'val': '%s: %s' % ( exception, exception_description)})) self.interaction(frame, tb, exception, exception_description)
class WSClient: def __init__(self, configuration, url, headers): """A websocket client with support for channels. Exec command uses different channels for different streams. for example, 0 is stdin, 1 is stdout and 2 is stderr. Some other API calls like port forwarding can forward different pods' streams to different channels. """ enableTrace(False) header = [] self._connected = False self._channels = {} self._all = "" # We just need to pass the Authorization, ignore all the other # http headers we get from the generated code if headers and 'authorization' in headers: header.append("authorization: %s" % headers['authorization']) if headers and 'sec-websocket-protocol' in headers: header.append("sec-websocket-protocol: %s" % headers['sec-websocket-protocol']) else: header.append("sec-websocket-protocol: v4.channel.k8s.io") if url.startswith('wss://') and configuration.verify_ssl: ssl_opts = { 'cert_reqs': ssl.CERT_REQUIRED, 'ca_certs': configuration.ssl_ca_cert or certifi.where(), } if configuration.assert_hostname is not None: ssl_opts['check_hostname'] = configuration.assert_hostname else: ssl_opts = {'cert_reqs': ssl.CERT_NONE} if configuration.cert_file: ssl_opts['certfile'] = configuration.cert_file if configuration.key_file: ssl_opts['keyfile'] = configuration.key_file self.sock = WebSocket(sslopt=ssl_opts, skip_utf8_validation=False) self.sock.connect(url, header=header) self._connected = True def peek_channel(self, channel, timeout=0): """Peek a channel and return part of the input, empty string otherwise.""" self.update(timeout=timeout) if channel in self._channels: return self._channels[channel] return "" def read_channel(self, channel, timeout=0): """Read data from a channel.""" if channel not in self._channels: ret = self.peek_channel(channel, timeout) else: ret = self._channels[channel] if channel in self._channels: del self._channels[channel] return ret def readline_channel(self, channel, timeout=None): """Read a line from a channel.""" if timeout is None: timeout = float("inf") start = time.time() while self.is_open() and time.time() - start < timeout: if channel in self._channels: data = self._channels[channel] if "\n" in data: index = data.find("\n") ret = data[:index] data = data[index+1:] if data: self._channels[channel] = data else: del self._channels[channel] return ret self.update(timeout=(timeout - time.time() + start)) def write_channel(self, channel, data): """Write data to a channel.""" self.sock.send(chr(channel) + data) def peek_stdout(self, timeout=0): """Same as peek_channel with channel=1.""" return self.peek_channel(STDOUT_CHANNEL, timeout=timeout) def read_stdout(self, timeout=None): """Same as read_channel with channel=1.""" return self.read_channel(STDOUT_CHANNEL, timeout=timeout) def readline_stdout(self, timeout=None): """Same as readline_channel with channel=1.""" return self.readline_channel(STDOUT_CHANNEL, timeout=timeout) def peek_stderr(self, timeout=0): """Same as peek_channel with channel=2.""" return self.peek_channel(STDERR_CHANNEL, timeout=timeout) def read_stderr(self, timeout=None): """Same as read_channel with channel=2.""" return self.read_channel(STDERR_CHANNEL, timeout=timeout) def readline_stderr(self, timeout=None): """Same as readline_channel with channel=2.""" return self.readline_channel(STDERR_CHANNEL, timeout=timeout) def read_all(self): """Return buffered data received on stdout and stderr channels. This is useful for non-interactive call where a set of command passed to the API call and their result is needed after the call is concluded. Should be called after run_forever() or update() TODO: Maybe we can process this and return a more meaningful map with channels mapped for each input. """ out = self._all self._all = "" self._channels = {} return out def is_open(self): """True if the connection is still alive.""" return self._connected def write_stdin(self, data): """The same as write_channel with channel=0.""" self.write_channel(STDIN_CHANNEL, data) def update(self, timeout=0): """Update channel buffers with at most one complete frame of input.""" if not self.is_open(): return if not self.sock.connected: self._connected = False return r, _, _ = select.select( (self.sock.sock, ), (), (), timeout) if r: op_code, frame = self.sock.recv_data_frame(True) if op_code == ABNF.OPCODE_CLOSE: self._connected = False return elif op_code == ABNF.OPCODE_BINARY or op_code == ABNF.OPCODE_TEXT: data = frame.data if six.PY3: data = data.decode("utf-8") if len(data) > 1: channel = ord(data[0]) data = data[1:] if data: if channel in [STDOUT_CHANNEL, STDERR_CHANNEL]: # keeping all messages in the order they received for # non-blocking call. self._all += data if channel not in self._channels: self._channels[channel] = data else: self._channels[channel] += data def run_forever(self, timeout=None): """Wait till connection is closed or timeout reached. Buffer any input received during this time.""" if timeout: start = time.time() while self.is_open() and time.time() - start < timeout: self.update(timeout=(timeout - time.time() + start)) else: while self.is_open(): self.update(timeout=None) def close(self, **kwargs): """ close websocket connection. """ self._connected = False if self.sock: self.sock.close(**kwargs)
class WdbRequest(object, Bdb): """Wdb debugger main class""" __metaclass__ = MetaWdbRequest def __init__(self, ports, skip=None): MetaWdbRequest._last_inst = self self.obj_cache = {} try: Bdb.__init__(self, skip=skip) except TypeError: Bdb.__init__(self) self.begun = False self.connected = False self.make_web_socket(ports) breaks_per_file_lno = Breakpoint.bplist.values() for bps in breaks_per_file_lno: breaks = list(bps) for bp in breaks: args = bp.file, bp.line, bp.temporary, bp.cond self.set_break(*args) log.info("Resetting break %s" % repr(args)) def better_repr(self, obj): try: if isinstance(obj, basestring): raise TypeError() iter(obj) except TypeError: self.obj_cache[id(obj)] = obj return '<a href="%d" class="inspect">%s</a>' % (id(obj), escape(repr(obj))) if isinstance(obj, dict): if type(obj) != dict: dict_repr = type(obj).__name__ + "({" closer = "})" else: dict_repr = "{" closer = "}" dict_repr += ", ".join([repr(key) + ": " + self.better_repr(val) for key, val in obj.items()]) dict_repr += closer return dict_repr if type(obj) == list: iter_repr = "[" closer = "]" elif type(obj) == set: iter_repr = "{" closer = "}" elif type(obj) == tuple: iter_repr = "(" closer = ")" else: iter_repr = escape(obj.__class__.__name__) + "([" closer = "])" iter_repr += ", ".join([self.better_repr(val) for val in obj]) iter_repr += closer return iter_repr @contextmanager def capture_output(self, with_hook=True): self.hooked = "" def display_hook(obj): # That's some dirty hack self.hooked += self.better_repr(obj) stdout, stderr = sys.stdout, sys.stderr if with_hook: d_hook = sys.displayhook sys.displayhook = display_hook sys.stdout, sys.stderr = StringIO(), StringIO() out, err = [], [] try: yield out, err finally: out.extend(sys.stdout.getvalue().splitlines()) err.extend(sys.stderr.getvalue().splitlines()) if with_hook: sys.displayhook = d_hook sys.stdout, sys.stderr = stdout, stderr def dmp(self, thing): return dict( (escape(key), {"val": self.better_repr(getattr(thing, key)), "type": type(getattr(thing, key)).__name__}) for key in dir(thing) ) def make_web_socket(self, ports): log.info("Creating WebSocket") for port in ports: self.ws = WebSocket("0.0.0.0", port) if self.ws.status == "OK": return time.sleep(0.100) raise WsError("No port could be opened") def wsgi_trace(self, app, environ, start_response): def wsgi_with_trace(environ, start_response): self.quitting = 0 self.begun = False self.reset() frame = sys._getframe() while frame: frame.f_trace = self.trace_dispatch self.botframe = frame frame = frame.f_back self.stopframe = sys._getframe().f_back self.stoplineno = -1 sys.settrace(self.trace_dispatch) try: appiter = app(environ, start_response) except BdbQuit: sys.settrace(None) start_response("200 OK", [("Content-Type", "text/html")]) yield "<h1>BdbQuit</h1><p>Wdb was interrupted</p>" else: for item in appiter: yield item hasattr(appiter, "close") and appiter.close() sys.settrace(None) self.ws.force_close() return wsgi_with_trace(environ, start_response) def get_file(self, filename, html_escape=True): checkcache(filename) file_ = "".join(getlines(filename)) if not html_escape: return file_ return escape(file_) def handle_connection(self): if self.connected: try: self.send("Ping") except: log.exception("Ping Failed") self.connected = False if not self.connected: self.ws.wait_for_connect() self.connected = True def get_trace(self, frame, tb, w_code=None): frames = [] stack, current = self.get_stack(frame, tb) for i, (frame, lno) in enumerate(stack): code = frame.f_code filename = code.co_filename if filename == "<wdb>" and w_code: line = w_code else: checkcache(filename) line = getline(filename, lno, frame.f_globals) line = line and line.strip() startlnos = dis.findlinestarts(code) lastlineno = list(startlnos)[-1][1] frames.append( { "file": filename, "function": code.co_name, "flno": code.co_firstlineno, "llno": lastlineno, "lno": lno, "code": escape(line), "level": i, } ) return stack, frames, current def handle_exc(self): type_, value = exc_info()[:2] return '<a title="%s">%s: %s</a>' % ( escape(traceback.format_exc().replace('"', "'")), escape(type_.__name__), escape(str(value)), ) def interaction(self, frame, tb=None, exception="Wdb", exception_description="Set Trace"): if not self.ws: raise BdbQuit() try: self._interaction(frame, tb, exception, exception_description) except WsError: log.exception("Websocket Error during interaction. Starting again") self.handle_connection() self.interaction(frame, tb, exception, exception_description) def send(self, data): self.ws.send(data) def receive(self): message = None while not message: rv = self.ws.receive() if rv == "CLOSED": raise WsError message = rv return message def _interaction(self, frame, tb, exception, exception_description): log.debug("Interaction for %r %r %r %r" % (frame, tb, exception, exception_description)) stack, trace, current_index = self.get_trace(frame, tb) current = trace[current_index] locals_ = map(lambda x: x[0].f_locals, stack) if self.begun: self.send("Trace|%s" % dump({"trace": trace, "cwd": os.getcwd()})) current_file = current["file"] self.send( "Check|%s" % dump({"name": current_file, "sha512": sha512(self.get_file(current_file)).hexdigest()}) ) else: self.begun = True while True: try: message = self.receive() if "|" in message: pipe = message.index("|") cmd = message[:pipe] data = message[pipe + 1 :] else: cmd = message data = "" def fail(title=None, message=None): if message is None: message = self.handle_exc() else: message = escape(message) self.send("Echo|%s" % dump({"for": escape(title or "%s failed" % cmd), "val": message})) log.debug("Cmd %s #Data %d" % (cmd, len(data))) if cmd == "Start": self.send("Init|%s" % dump({"cwd": os.getcwd()})) self.send("Title|%s" % dump({"title": exception, "subtitle": exception_description})) self.send("Trace|%s" % dump({"trace": trace})) current_file = current["file"] self.send( "Check|%s" % dump({"name": current_file, "sha512": sha512(self.get_file(current_file)).hexdigest()}) ) elif cmd == "Select": current_index = int(data) current = trace[current_index] current_file = current["file"] self.send( "Check|%s" % dump({"name": current_file, "sha512": sha512(self.get_file(current_file)).hexdigest()}) ) elif cmd == "File": current_file = current["file"] self.send( "Select|%s" % dump( { "frame": current, "breaks": self.get_file_breaks(current_file), "file": self.get_file(current_file), "name": current_file, "sha512": sha512(self.get_file(current_file)).hexdigest(), } ) ) elif cmd == "NoFile": self.send("Select|%s" % dump({"frame": current, "breaks": self.get_file_breaks(current["file"])})) elif cmd == "Inspect": try: thing = self.obj_cache.get(int(data)) except Exception: fail() continue self.send("Dump|%s" % dump({"for": escape(repr(thing)), "val": self.dmp(thing)})) elif cmd == "Dump": globals_ = dict(stack[current_index][0].f_globals) try: thing = eval(data, globals_, locals_[current_index]) except Exception: fail() continue else: self.send( "Dump|%s" % dump({"for": escape(u"%s ⟶ %s " % (data, repr(thing))), "val": self.dmp(thing)}) ) elif cmd == "Trace": self.send("Trace|%s" % dump({"trace": trace})) elif cmd == "Eval": redir = None raw_data = data = data.strip() if "!>" in data: data, redir = data.split("!>") data = data.strip() redir = redir.strip() elif data.startswith("!<"): filename = data[2:].strip() try: with open(filename, "r") as f: data = f.read() except Exception: fail("Unable to read from file %s" % filename) continue globals_ = dict(stack[current_index][0].f_globals) # Hack for function scope eval globals_.update(locals_[current_index]) globals_.setdefault("_pprint", pprint) with self.capture_output(with_hook=redir is None) as (out, err): try: compiled_code = compile(data, "<stdin>", "single") l = locals_[current_index] exec compiled_code in globals_, l except Exception: self.hooked = self.handle_exc() if redir: try: with open(redir, "w") as f: f.write("\n".join(out) + "\n".join(err) + "\n") except Exception: fail("Unable to write to file %s" % redir) continue self.send( "Print|%s" % dump({"for": escape(raw_data), "result": escape("Written to file %s" % redir)}) ) else: self.send( "Print|%s" % dump( { "for": escape(raw_data), "result": self.hooked + escape("\n".join(out) + "\n".join(err)), } ) ) elif cmd == "Ping": self.send("Pong") elif cmd == "Step": if hasattr(self, "botframe"): self.set_step() break elif cmd == "Next": if hasattr(self, "botframe"): self.set_next(stack[current_index][0]) break elif cmd == "Continue": if hasattr(self, "botframe"): self.set_continue() break elif cmd == "Return": if hasattr(self, "botframe"): self.set_return(stack[current_index][0]) break elif cmd == "Until": if hasattr(self, "botframe"): self.set_until(stack[current_index][0]) break elif cmd in ("TBreak", "Break"): break_fail = lambda x: fail("Break on %s failed" % data, message=x) if ":" in data: fn, lno = data.split(":") else: fn, lno = current["file"], data cond = None if "," in lno: lno, cond = lno.split(",") cond = cond.lstrip() try: lno = int(lno) except: break_fail("Wrong breakpoint format must be " "[file:]lno[,cond].") continue line = getline(fn, lno, stack[current_index][0].f_globals) if not line: break_fail("Line does not exist") continue line = line.strip() if not line or (line[0] == "#") or (line[:3] == '"""') or line[:3] == "'''": break_fail("Blank line or comment") continue first_rv = rv = self.set_break(fn, lno, int(cmd == "TBreak"), cond) if rv is not None: for path in sys.path: rv = self.set_break(os.path.join(path, fn), lno, int(cmd == "TBreak"), cond) if rv is None: break if rv is None: log.info("Break set at %s:%d [%s]" % (fn, lno, rv)) if fn == current["file"]: self.send("BreakSet|%s" % dump({"lno": lno, "cond": cond})) else: self.send("BreakSet|%s" % dump({})) else: break_fail(first_rv) elif cmd == "Unbreak": lno = int(data) current_file = current["file"] log.info("Break unset at %s:%d" % (current_file, lno)) self.clear_break(current_file, lno) self.send("BreakUnset|%s" % dump({"lno": lno})) elif cmd == "Jump": lno = int(data) if current_index != len(trace) - 1: log.error("Must be at bottom frame") continue try: stack[current_index][0].f_lineno = lno except ValueError: fail() continue trace[current_index]["lno"] = lno self.send("Trace|%s" % dump({"trace": trace})) self.send("Select|%s" % dump({"frame": current, "breaks": self.get_file_breaks(current["file"])})) elif cmd == "Complete": current_file = current["file"] file_ = self.get_file(current_file, False).decode("utf-8") lines = file_.split(u"\n") lno = trace[current_index]["lno"] line_before = lines[lno - 1] indent = len(line_before) - len(line_before.lstrip()) segments = data.split(u"\n") for segment in reversed(segments): line = u" " * indent + segment lines.insert(lno - 1, line) script = Script(u"\n".join(lines), lno - 1 + len(segments), len(segments[-1]) + indent, "") try: completions = script.complete() except: log.exception("Completion failed") self.send( "Log|%s" % dump({"message": "Completion failed for %s" % "\n".join(reversed(segments))}) ) else: fun = script.get_in_function_call() self.send( "Suggest|%s" % dump( { "params": { "params": [p.get_code().replace("\n", "") for p in fun.params], "index": fun.index, "module": fun.module.path, "call_name": fun.call_name, } if fun else None, "completions": [ { "base": comp.word[: len(comp.word) - len(comp.complete)], "complete": comp.complete, "description": comp.description, } for comp in completions if comp.word.endswith(comp.complete) ], } ) ) elif cmd == "Quit": if hasattr(self, "botframe"): self.set_continue() raise BdbQuit() break else: log.warn("Unknown command %s" % cmd) except BdbQuit: raise except Exception: try: exc = self.handle_exc() type_, value = exc_info()[:2] link = ( '<a href="https://github.com/Kozea/wdb/issues/new?' 'title=%s&body=%s&labels=defect" class="nogood">' "Please click here to report it on Github</a>" ) % ( quote("%s: %s" % (type_.__name__, str(value))), quote("```\n%s\n```\n" % traceback.format_exc()), ) self.send( "Echo|%s" % dump({"for": escape("Error in Wdb, this is bad"), "val": exc + "<br>" + link}) ) except: self.send( "Echo|%s" % dump( { "for": escape("Too many errors"), "val": escape("Don't really know what to say. " "Maybe it will work tomorrow."), } ) ) continue def user_call(self, frame, argument_list): """This method is called when there is the remote possibility that we ever need to stop in this function.""" if self.stop_here(frame): fun = frame.f_code.co_name log.info("Calling: %r" % fun) self.handle_connection() self.send("Echo|%s" % dump({"for": "__call__", "val": fun})) self.interaction(frame) def user_line(self, frame): """This function is called when we stop or break at this line.""" log.info("Stopping at line %r:%d" % (frame.f_code.co_filename, frame.f_lineno)) self.handle_connection() log.debug("User Line Interaction for %r" % frame) self.interaction(frame) def user_return(self, frame, return_value): """This function is called when a return trap is set here.""" frame.f_locals["__return__"] = return_value log.info("Returning from %r with value: %r" % (frame.f_code.co_name, return_value)) self.handle_connection() self.send("Echo|%s" % dump({"for": "__return__", "val": return_value})) self.interaction(frame) def user_exception(self, frame, exc_info): """This function is called if an exception occurs, but only if we are to stop at or just below this level.""" log.error("Exception", exc_info=exc_info) type_, value, tb = exc_info frame.f_locals["__exception__"] = type_, value exception = type_.__name__ exception_description = str(value) self.handle_connection() self.send( "Echo|%s" % dump({"for": "__exception__", "val": escape("%s: %s") % (exception, exception_description)}) ) if not self.begun: frame = None self.interaction(frame, tb, exception, exception_description) def do_clear(self, arg): log.info("Closing %r" % arg) self.clear_bpbynumber(arg) def dispatch_exception(self, frame, arg): self.user_exception(frame, arg) if self.quitting: raise BdbQuit return self.trace_dispatch def recursive(self, g, l): # Inspect curent debugger vars through pdb sys.settrace(None) from pdb import Pdb p = Pdb() sys.call_tracing(p.run, ("1/0", g, l)) sys.settrace(self.trace_dispatch) self.lastcmd = p.lastcmd
false = False null = None #connecting to db for posts and blockchain websocket db = MongoClient().golos ws = WebSocket() ws.connect('wss://api.golos.cf') print('Sending for 100') #Sending query to fetch last 100 posts ws.send( json.dumps({ "id": 6, "method": "get_discussions_by_created", "params": [{ "tag": "", "limit": "100" }] })) post = eval(ws.recv())['result'] #get needed params and dump in db for i in post: ids = i['id'] try: tags = eval(i['json_metadata'])['tags'] except: tags = [] write = dump = { 'id': ids,
class WdbRequest(object, Bdb): """Wdb debugger main class""" __metaclass__ = MetaWdbRequest def __init__(self, ports, skip=None): MetaWdbRequest._last_inst = self self.obj_cache = {} try: Bdb.__init__(self, skip=skip) except TypeError: Bdb.__init__(self) self.begun = False self.connected = False self.make_web_socket(ports) breaks_per_file_lno = Breakpoint.bplist.values() for bps in breaks_per_file_lno: breaks = list(bps) for bp in breaks: args = bp.file, bp.line, bp.temporary, bp.cond self.set_break(*args) log.info('Resetting break %s' % repr(args)) def safe_repr(self, obj): try: return repr(obj) except Exception as e: return '??? Broken repr (%s: %s)' % (type(e).__name__, e) def safe_better_repr(self, obj): try: rv = self.better_repr(obj) except Exception: rv = None if rv: return rv self.obj_cache[id(obj)] = obj return '<a href="%d" class="inspect">%s</a>' % ( id(obj), escape(repr(obj))) def better_repr(self, obj): if isinstance(obj, dict): if type(obj) != dict: dict_repr = type(obj).__name__ + '({' closer = '})' else: dict_repr = '{' closer = '}' dict_repr += ', '.join([ self.safe_repr(key) + ': ' + self.safe_better_repr(val) for key, val in obj.items()]) dict_repr += closer return dict_repr if any([ isinstance(obj, list), isinstance(obj, set), isinstance(obj, tuple)]): if type(obj) == list: iter_repr = '[' closer = ']' elif type(obj) == set: iter_repr = '{' closer = '}' elif type(obj) == tuple: iter_repr = '(' closer = ')' else: iter_repr = escape(obj.__class__.__name__) + '([' closer = '])' iter_repr += ', '.join([self.safe_better_repr(val) for val in obj]) iter_repr += closer return iter_repr @contextmanager def capture_output(self, with_hook=True): self.hooked = '' def display_hook(obj): # That's some dirty hack self.hooked += self.safe_better_repr(obj) stdout, stderr = sys.stdout, sys.stderr if with_hook: d_hook = sys.displayhook sys.displayhook = display_hook sys.stdout, sys.stderr = StringIO(), StringIO() out, err = [], [] try: yield out, err finally: out.extend(sys.stdout.getvalue().splitlines()) err.extend(sys.stderr.getvalue().splitlines()) if with_hook: sys.displayhook = d_hook sys.stdout, sys.stderr = stdout, stderr def dmp(self, thing): def safe_getattr(key): try: return getattr(thing, key) except Exception as e: return 'Error getting attr "%s" from "%s" (%s: %s)' % ( key, thing, type(e).__name__, e) return dict( (escape(key), { 'val': self.safe_better_repr(safe_getattr(key)), 'type': type(safe_getattr(key)).__name__ }) for key in dir(thing) ) def make_web_socket(self, ports): log.info('Creating WebSocket') for port in ports: self.ws = WebSocket('0.0.0.0', port) if self.ws.status == 'OK': return time.sleep(.100) raise WsError('No port could be opened') def wsgi_trace(self, app, environ, start_response): def wsgi_with_trace(environ, start_response): self.quitting = 0 self.begun = False self.reset() frame = sys._getframe() while frame: frame.f_trace = self.trace_dispatch self.botframe = frame frame = frame.f_back self.stopframe = sys._getframe().f_back self.stoplineno = -1 sys.settrace(self.trace_dispatch) try: appiter = app(environ, start_response) except BdbQuit: sys.settrace(None) start_response('200 OK', [('Content-Type', 'text/html')]) yield '<h1>BdbQuit</h1><p>Wdb was interrupted</p>' else: for item in appiter: yield item hasattr(appiter, 'close') and appiter.close() sys.settrace(None) self.ws.force_close() return wsgi_with_trace(environ, start_response) def get_file(self, filename, html_escape=True): checkcache(filename) file_ = ''.join(getlines(filename)) if not html_escape: return file_ return escape(file_) def handle_connection(self): if self.connected: try: self.send('Ping') except: log.exception('Ping Failed') self.connected = False if not self.connected: self.ws.wait_for_connect() self.connected = True def get_trace(self, frame, tb, w_code=None): frames = [] stack, current = self.get_stack(frame, tb) for i, (frame, lno) in enumerate(stack): code = frame.f_code filename = code.co_filename if filename == '<wdb>' and w_code: line = w_code else: checkcache(filename) line = getline(filename, lno, frame.f_globals) line = line and line.strip() startlnos = dis.findlinestarts(code) lastlineno = list(startlnos)[-1][1] frames.append({ 'file': filename, 'function': code.co_name, 'flno': code.co_firstlineno, 'llno': lastlineno, 'lno': lno, 'code': escape(line), 'level': i }) return stack, frames, current def handle_exc(self): type_, value = exc_info()[:2] return '<a title="%s">%s: %s</a>' % ( escape(traceback.format_exc().replace('"', '\'')), escape(type_.__name__), escape(str(value))) def interaction( self, frame, tb=None, exception='Wdb', exception_description='Set Trace'): if not self.ws: raise BdbQuit() try: self._interaction( frame, tb, exception, exception_description) except WsError: log.exception('Websocket Error during interaction. Starting again') self.handle_connection() self.interaction( frame, tb, exception, exception_description) def send(self, data): self.ws.send(data) def receive(self): message = None while not message: rv = self.ws.receive() if rv == 'CLOSED': raise WsError message = rv return message def _interaction( self, frame, tb, exception, exception_description): log.debug('Interaction for %r %r %r %r' % ( frame, tb, exception, exception_description)) stack, trace, current_index = self.get_trace(frame, tb) current = trace[current_index] locals_ = map(lambda x: x[0].f_locals, stack) if self.begun: self.send('Trace|%s' % dump({ 'trace': trace, 'cwd': os.getcwd() })) current_file = current['file'] self.send('Check|%s' % dump({ 'name': current_file, 'sha512': sha512(self.get_file(current_file)).hexdigest() })) else: self.begun = True while True: try: message = self.receive() if '|' in message: pipe = message.index('|') cmd = message[:pipe] data = message[pipe + 1:] else: cmd = message data = '' def fail(title=None, message=None): if message is None: message = self.handle_exc() else: message = escape(message) self.send('Echo|%s' % dump({ 'for': escape(title or '%s failed' % cmd), 'val': message })) log.debug('Cmd %s #Data %d' % (cmd, len(data))) if cmd == 'Start': self.send('Init|%s' % dump({ 'cwd': os.getcwd() })) self.send('Title|%s' % dump({ 'title': exception, 'subtitle': exception_description })) self.send('Trace|%s' % dump({ 'trace': trace })) current_file = current['file'] self.send('Check|%s' % dump({ 'name': current_file, 'sha512': sha512( self.get_file(current_file)).hexdigest() })) elif cmd == 'Select': current_index = int(data) current = trace[current_index] current_file = current['file'] self.send('Check|%s' % dump({ 'name': current_file, 'sha512': sha512( self.get_file(current_file)).hexdigest() })) elif cmd == 'File': current_file = current['file'] self.send('Select|%s' % dump({ 'frame': current, 'breaks': self.get_file_breaks(current_file), 'file': self.get_file(current_file), 'name': current_file, 'sha512': sha512( self.get_file(current_file)).hexdigest() })) elif cmd == 'NoFile': self.send('Select|%s' % dump({ 'frame': current, 'breaks': self.get_file_breaks(current['file']) })) elif cmd == 'Inspect': try: thing = self.obj_cache.get(int(data)) except Exception: fail() continue self.send('Dump|%s' % dump({ 'for': escape(repr(thing)), 'val': self.dmp(thing)})) elif cmd == 'Dump': globals_ = dict(stack[current_index][0].f_globals) try: thing = eval(data, globals_, locals_[current_index]) except Exception: fail() continue else: self.send('Dump|%s' % dump({ 'for': escape(u'%s ⟶ %s ' % (data, repr(thing))), 'val': self.dmp(thing)})) elif cmd == 'Trace': self.send('Trace|%s' % dump({ 'trace': trace })) elif cmd == 'Eval': redir = None raw_data = data = data.strip() if '!>' in data: data, redir = data.split('!>') data = data.strip() redir = redir.strip() elif data.startswith('!<'): filename = data[2:].strip() try: with open(filename, 'r') as f: data = f.read() except Exception: fail('Unable to read from file %s' % filename) continue globals_ = dict(stack[current_index][0].f_globals) # Hack for function scope eval globals_.update(locals_[current_index]) globals_.setdefault('_pprint', pprint) with self.capture_output( with_hook=redir is None) as (out, err): try: compiled_code = compile(data, '<stdin>', 'single') l = locals_[current_index] exec compiled_code in globals_, l except Exception: self.hooked = self.handle_exc() if redir: try: with open(redir, 'w') as f: f.write('\n'.join(out) + '\n'.join(err) + '\n') except Exception: fail('Unable to write to file %s' % redir) continue self.send('Print|%s' % dump({ 'for': escape(raw_data), 'result': escape('Written to file %s' % redir) })) else: self.send('Print|%s' % dump({ 'for': escape(raw_data), 'result': self.hooked + escape( '\n'.join(out) + '\n'.join(err)) })) elif cmd == 'Ping': self.send('Pong') elif cmd == 'Step': if hasattr(self, 'botframe'): self.set_step() break elif cmd == 'Next': if hasattr(self, 'botframe'): self.set_next(stack[current_index][0]) break elif cmd == 'Continue': if hasattr(self, 'botframe'): self.set_continue() break elif cmd == 'Return': if hasattr(self, 'botframe'): self.set_return(stack[current_index][0]) break elif cmd == 'Until': if hasattr(self, 'botframe'): self.set_until(stack[current_index][0]) break elif cmd in ('TBreak', 'Break'): break_fail = lambda x: fail( 'Break on %s failed' % data, message=x) if ':' in data: fn, lno = data.split(':') else: fn, lno = current['file'], data cond = None if ',' in lno: lno, cond = lno.split(',') cond = cond.lstrip() try: lno = int(lno) except: break_fail( 'Wrong breakpoint format must be ' '[file:]lno[,cond].') continue line = getline( fn, lno, stack[current_index][0].f_globals) if not line: break_fail('Line does not exist') continue line = line.strip() if ((not line or (line[0] == '#') or (line[:3] == '"""') or line[:3] == "'''")): break_fail('Blank line or comment') continue first_rv = rv = self.set_break( fn, lno, int(cmd == 'TBreak'), cond) if rv is not None: for path in sys.path: rv = self.set_break( os.path.join(path, fn), lno, int(cmd == 'TBreak'), cond) if rv is None: break if rv is None: log.info('Break set at %s:%d [%s]' % (fn, lno, rv)) if fn == current['file']: self.send('BreakSet|%s' % dump({ 'lno': lno, 'cond': cond })) else: self.send('BreakSet|%s' % dump({})) else: break_fail(first_rv) elif cmd == 'Unbreak': lno = int(data) current_file = current['file'] log.info('Break unset at %s:%d' % (current_file, lno)) self.clear_break(current_file, lno) self.send('BreakUnset|%s' % dump({'lno': lno})) elif cmd == 'Jump': lno = int(data) if current_index != len(trace) - 1: log.error('Must be at bottom frame') continue try: stack[current_index][0].f_lineno = lno except ValueError: fail() continue trace[current_index]['lno'] = lno self.send('Trace|%s' % dump({ 'trace': trace })) self.send('Select|%s' % dump({ 'frame': current, 'breaks': self.get_file_breaks(current['file']) })) elif cmd == 'Complete': current_file = current['file'] file_ = self.get_file(current_file, False).decode('utf-8') lines = file_.split(u'\n') lno = trace[current_index]['lno'] line_before = lines[lno - 1] indent = len(line_before) - len(line_before.lstrip()) segments = data.split(u'\n') for segment in reversed(segments): line = u' ' * indent + segment lines.insert(lno - 1, line) script = Script( u'\n'.join(lines), lno - 1 + len(segments), len(segments[-1]) + indent, '') try: completions = script.complete() except: log.exception('Completion failed') self.send('Log|%s' % dump({ 'message': 'Completion failed for %s' % '\n'.join(reversed(segments)) })) else: fun = script.get_in_function_call() self.send('Suggest|%s' % dump({ 'params': { 'params': [p.get_code().replace('\n', '') for p in fun.params], 'index': fun.index, 'module': fun.module.path, 'call_name': fun.call_name} if fun else None, 'completions': [{ 'base': comp.word[ :len(comp.word) - len(comp.complete)], 'complete': comp.complete, 'description': comp.description } for comp in completions if comp.word.endswith( comp.complete)] })) elif cmd == 'Quit': if hasattr(self, 'botframe'): self.set_continue() raise BdbQuit() break else: log.warn('Unknown command %s' % cmd) except BdbQuit: raise except Exception: try: exc = self.handle_exc() type_, value = exc_info()[:2] link = ('<a href="https://github.com/Kozea/wdb/issues/new?' 'title=%s&body=%s&labels=defect" class="nogood">' 'Please click here to report it on Github</a>') % ( quote('%s: %s' % (type_.__name__, str(value))), quote('```\n%s\n```\n' % traceback.format_exc())) self.send('Echo|%s' % dump({ 'for': escape('Error in Wdb, this is bad'), 'val': exc + '<br>' + link })) except: self.send('Echo|%s' % dump({ 'for': escape('Too many errors'), 'val': escape("Don't really know what to say. " "Maybe it will work tomorrow.") })) continue def user_call(self, frame, argument_list): """This method is called when there is the remote possibility that we ever need to stop in this function.""" if self.stop_here(frame): fun = frame.f_code.co_name log.info('Calling: %r' % fun) self.handle_connection() self.send('Echo|%s' % dump({ 'for': '__call__', 'val': fun})) self.interaction(frame) def user_line(self, frame): """This function is called when we stop or break at this line.""" log.info('Stopping at line %r:%d' % ( frame.f_code.co_filename, frame.f_lineno)) self.handle_connection() log.debug('User Line Interaction for %r' % frame) self.interaction(frame) def user_return(self, frame, return_value): """This function is called when a return trap is set here.""" frame.f_locals['__return__'] = return_value log.info('Returning from %r with value: %r' % ( frame.f_code.co_name, return_value)) self.handle_connection() self.send('Echo|%s' % dump({ 'for': '__return__', 'val': return_value })) self.interaction(frame) def user_exception(self, frame, exc_info): """This function is called if an exception occurs, but only if we are to stop at or just below this level.""" log.error('Exception', exc_info=exc_info) type_, value, tb = exc_info frame.f_locals['__exception__'] = type_, value exception = type_.__name__ exception_description = str(value) self.handle_connection() self.send('Echo|%s' % dump({ 'for': '__exception__', 'val': escape('%s: %s') % ( exception, exception_description)})) if not self.begun: frame = None self.interaction(frame, tb, exception, exception_description) def do_clear(self, arg): log.info('Closing %r' % arg) self.clear_bpbynumber(arg) def dispatch_exception(self, frame, arg): self.user_exception(frame, arg) if self.quitting: raise BdbQuit return self.trace_dispatch def recursive(self, g, l): # Inspect curent debugger vars through pdb sys.settrace(None) from pdb import Pdb p = Pdb() sys.call_tracing(p.run, ('1/0', g, l)) sys.settrace(self.trace_dispatch) self.lastcmd = p.lastcmd