import os import sys import gluon.dal import gluon.html import gluon.validators import code from gluon.debug import communicate, web_debugger, dbg_debugger from gluon._compat import thread from gluon.fileutils import open_file import pydoc if DEMO_MODE or MULTI_USER_MODE: session.flash = T('disabled in demo mode') redirect(URL('default', 'site')) FE = 10 ** 9 def index(): app = request.args(0) or 'admin' reset() # read buffer data = communicate() return dict(app=app, data=data) def callback(): app = request.args[0] command = request.vars.statement session['debug_commands:' + app].append(command) output = communicate(command) k = len(session['debug_commands:' + app]) - 1 return '[%i] %s%s\n' % (k + 1, command, output) def reset(): app = request.args(0) or 'admin' session['debug_commands:' + app] = [] return 'done' # new implementation using dbg def interact(): app = request.args(0) or 'admin' reset() # process all pending messages in the frontend web_debugger.run() # if debugging, filename and lineno should have valid values filename = web_debugger.filename lineno = web_debugger.lineno if filename: # prevent IOError 2 on some circuntances (EAFP instead of os.access) try: lines = open_file(filename, 'r').readlines() except: lines = "" lines = dict([(i + 1, l) for (i, l) in enumerate( [l.strip("\n").strip("\r") for l in lines])]) filename = os.path.basename(filename) else: lines = {} if filename: web_debugger.set_burst(2) env = web_debugger.do_environment() f_locals = env['locals'] f_globals = {} for name, value in env['globals'].items(): if name not in gluon.html.__all__ and \ name not in gluon.validators.__all__: f_globals[name] = pydoc.text.repr(value) else: f_locals = {} f_globals = {} response.headers['refresh'] = "3" if web_debugger.exception_info: response.flash = T('"User Exception" debug mode. ' 'An error ticket could be issued!') return dict(app=app, data="", filename=web_debugger.filename, lines=lines, lineno=lineno, f_globals=f_globals, f_locals=f_locals, exception=web_debugger.exception_info) def step(): web_debugger.do_step() redirect(URL("interact")) def next(): web_debugger.do_next() redirect(URL("interact")) def cont(): web_debugger.do_continue() redirect(URL("interact")) def ret(): web_debugger.do_return() redirect(URL("interact")) def stop(): web_debugger.do_quit() redirect(URL("interact")) def execute(): app = request.args[0] command = request.vars.statement session['debug_commands:' + app].append(command) try: output = web_debugger.do_exec(command) if output is None: output = "" except Exception as e: output = T("Exception %s") % str(e) k = len(session['debug_commands:' + app]) - 1 return '[%i] %s%s\n' % (k + 1, command, output) def breakpoints(): "Add or remove breakpoints" # Get all .py files files = listdir(apath('', r=request), '.*\.py$') files = [filename for filename in files if filename and 'languages' not in filename and not filename.startswith("admin") and not filename.startswith("examples")] form = SQLFORM.factory( Field('filename', requires=IS_IN_SET(files), label=T("Filename")), Field('lineno', 'integer', label=T("Line number"), requires=IS_NOT_EMPTY()), Field('temporary', 'boolean', label=T("Temporary"), comment=T("deleted after first hit")), Field('condition', 'string', label=T("Condition"), comment=T("honored only if the expression evaluates to true")), ) if form.accepts(request.vars, session): filename = os.path.join(request.env['applications_parent'], 'applications', form.vars.filename) err = dbg_debugger.do_set_breakpoint(filename, form.vars.lineno, form.vars.temporary, form.vars.condition) response.flash = T("Set Breakpoint on %s at line %s: %s") % ( filename, form.vars.lineno, err or T('successful')) for item in request.vars: if item[:7] == 'delete_': dbg_debugger.do_clear(item[7:]) breakpoints = [{'number': bp[0], 'filename': os.path.basename(bp[1]), 'path': bp[1], 'lineno': bp[2], 'temporary': bp[3], 'enabled': bp[4], 'hits': bp[5], 'condition': bp[6]} for bp in dbg_debugger.do_list_breakpoint()] return dict(breakpoints=breakpoints, form=form) def toggle_breakpoint(): "Set or clear a breakpoint" lineno = None ok = None try: filename = os.path.join(request.env['applications_parent'], 'applications', request.vars.filename) # normalize path name: replace slashes, references, etc... filename = os.path.normpath(os.path.normcase(filename)) if not request.vars.data: # ace send us the line number! lineno = int(request.vars.sel_start) + 1 else: # editarea send us the offset, manually check the cursor pos start = 0 sel_start = int(request.vars.sel_start) for lineno, line in enumerate(request.vars.data.split("\n")): if sel_start <= start: break start += len(line) + 1 else: lineno = None if lineno is not None: for bp in dbg_debugger.do_list_breakpoint(): no, bp_filename, bp_lineno, temporary, enabled, hits, cond = bp # normalize path name: replace slashes, references, etc... bp_filename = os.path.normpath(os.path.normcase(bp_filename)) if filename == bp_filename and lineno == bp_lineno: err = dbg_debugger.do_clear_breakpoint(filename, lineno) response.flash = T("Removed Breakpoint on %s at line %s", ( filename, lineno)) ok = False break else: err = dbg_debugger.do_set_breakpoint(filename, lineno) response.flash = T("Set Breakpoint on %s at line %s: %s") % ( filename, lineno, err or T('successful')) ok = True else: response.flash = T("Unable to determine the line number!") except Exception as e: session.flash = str(e) return response.json({'ok': ok, 'lineno': lineno}) def list_breakpoints(): "Return a list of linenumbers for current breakpoints" breakpoints = [] ok = False try: filename = os.path.join(request.env['applications_parent'], 'applications', request.vars.filename) # normalize path name: replace slashes, references, etc... filename = os.path.normpath(os.path.normcase(filename)) for bp in dbg_debugger.do_list_breakpoint(): no, bp_filename, bp_lineno, temporary, enabled, hits, cond = bp # normalize path name: replace slashes, references, etc... bp_filename = os.path.normpath(os.path.normcase(bp_filename)) if filename == bp_filename: breakpoints.append(bp_lineno) ok = True except Exception as e: session.flash = str(e) return response.json({'ok': ok, 'breakpoints': breakpoints})