def add_save_file(page, parent, hidden_save_id, textarea_id): """Inserts the widget required to browse for and save a local Python file. This is intended to be used to save a file from the editor. """ input_id = "input_" + hidden_save_id js_saved_script = """save_html_file(document.getElementById('%s').value, '%s');""" % ( input_id, textarea_id, ) SubElement(parent, "br") SubElement(parent, "input", name="url", size="60", id=input_id) SubElement(parent, "br") btn = SubElement(parent, "button", onclick=js_saved_script) btn.text = _("Save file") js_script = """document.getElementById('%s').value=file;""" % input_id insert_file_browser( page, parent, hidden_save_id, "/jquery_file_tree_all", _("Select a file to save"), js_script, "save_file" ) btn = SubElement( parent, "button", onclick="c=getElementById('%s');c.style.visibility='hidden';c.style.zIndex=-1;" % hidden_save_id, ) btn.text = _("Cancel") return
def analyzer_widget_callback(page, elem, uid): """Handles embedding suitable code into the page in order to display and run the analyzer""" vlam = elem.attrib["title"] log_id = extract_log_id(vlam) if log_id: t = 'analyzer' config[page.username]['logging_uids'][uid] = (log_id, t) elem.attrib['title'] = "python" analyzercode, show_vlam = plugin['services'].style(page, elem, None, vlam) elem.attrib['title'] = vlam if log_id: config['log'][log_id] = [tostring(markup)] wrap_in_div(elem, uid, vlam, "analyzer", show_vlam) #insert_markup(elem, uid, vlam, markup, "analyzer") # call the insert_editor_subwidget service to insert an editor: plugin['services'].insert_editor_subwidget(page, elem, uid, analyzercode) #some spacing: SubElement(elem, "br") # use the insert_analyzer_button service as any plugin can do insert_analyzer_button(page, elem, uid) SubElement(elem, "br") # finally, an output subwidget: plugin['services'].insert_io_subwidget(page, elem, uid)
def insert_file_browser(page, elem, uid, action, title, js_script, klass): '''inserts a file tree object in a page.''' if 'display' not in config[page.username]['page_security_level'](page.url): if not page.includes("jquery_file_tree"): page.add_include("jquery_file_tree") page.insert_js_file("/javascript/jquery.filetree.js") page.insert_css_file("/css/jquery.filetree.css") else: return tree_id = "tree_" + uid root = local_browser_root # use value specified in config.py by default if not os.path.exists(root): root = os.path.splitdrive(__file__)[0] + "/" # use base directory js_code = """$(document).ready( function() { $('#%s').fileTree({ root: '%s', script: '%s', expandSpeed: -1, collapseSpeed: -1, multiFolder: false }, function(file) { %s }); }); """ % (tree_id, root, action, js_script) page.add_js_code(js_code) elem.text = title elem.attrib['class'] = klass file_div = SubElement(elem, 'div') file_div.attrib['id'] = tree_id file_div.attrib['class'] = "filetree_window" return
def expected_output_process(dummy, elem, uid): """Displays and saves a copy of the expected output""" vlam = elem.attrib["title"] name = extract_name(vlam) expected_output = elem.text # We assume that the author has written the expected output as # <pre ...> # starts on this line... # </pre> # When doing so, the newline at the end of the opening <pre...> needs # to be discarded so that it can be compared with the real output. if expected_output.startswith("\r\n"): expected_output = expected_output[2:] elif expected_output.startswith("\n\r"): expected_output = expected_output[2:] elif expected_output.startswith("\n"): expected_output = expected_output[1:] # which we store expected_outputs[name] = expected_output # reset the original element to use it as a container. For those # familiar with dealing with ElementTree Elements, in other context, # note that the style_pycode() method extracted all of the existing # text, removing any original markup (and other elements), so that we # do not need to save either the "text" attribute or the "tail" one # before resetting the element. elem.clear() elem.tag = "div" elem.attrib["id"] = "div_" + uid elem.attrib['class'] = "test_output" # Create a title h4 = SubElement(elem, 'h4') h4.text = "Expected output; name= %s" % name # a container with the expected output pre = SubElement(elem, "pre") pre.text = expected_output
def add_browsing_to_menu(dummy): '''adds a menu item allowing the user to go the the browsers page''' menu_item = Element("li") link = SubElement(menu_item, 'a', href="/docs/basic_tutorial/browsing.html") link.text = _("Browsing") additional_menu_items['browsing'] = menu_item
def add_configuration_to_menu(page): '''adds a menu item allowing the user to choose the preferences''' menu_item = Element("li") link = SubElement(menu_item, 'a', href="/docs/basic_tutorial/preferences.html") link.text = _("Preferences") additional_menu_items['preferences'] = menu_item
def create_empty_menu(): # tested '''creates the basic menu structure including only the title''' menu = Element('div') menu.attrib['class'] = "crunchy_menu" _ul = SubElement(menu, "ul") _li = SubElement(_ul, "li") _li.text = _("Crunchy Menu") menu_items = SubElement(_li, "ul") return menu, menu_items
def add_button(info_container, nb_sites): '''adds button for site approval or removal''' approve_btn = SubElement(info_container, "button", onclick = "app_approve(%d)" % nb_sites) approve_btn.text = _("Approve") SubElement(info_container, "span").text = " " deny_btn = SubElement(info_container, "button", onclick="app_remove_all()") deny_btn.text = _("Remove all") return
def insert_traceback(page, elem, tb): '''inserts a traceback, nicely styled.''' pre = SubElement(elem, "pre") vlam = "pytb" pre.attrib['title'] = vlam pre.text = tb dummy, dummy = plugin['services'].style(page, pre, None, vlam) # prevent any further processing pre.attrib["title"] = "no_vlam" return
def insert_analyzer_button(page, elem, uid): """inserts an Elementtree that is an button to make a report on the code quality. Return the inserted button """ # Form to select the analyzer SubElement(elem, "br") form1 = SubElement(elem, "form", name="form1_" + uid) span = SubElement(form1, "span") span.text = _("Analyzer: ") span.attrib["class"] = "analyzer" select = SubElement(form1, "select", id="analyzer_" + uid) analyzer_names = configuration.options["analyzer"] for name in analyzer_names: if name is None: analyzer = str(None) else: analyzer = name.replace("analyzer_", "") option = SubElement(select, "option", value=analyzer) option.text = analyzer if analyzer == str(config[page.username]["analyzer"]): option.attrib["selected"] = "selected" SubElement(elem, "br") if "display" not in config[page.username]["page_security_level"](page.url): if not page.includes("analyzer_included"): page.add_include("analyzer_included") page.add_js_code(analyzer_jscode) btn = SubElement(elem, "button") btn.text = _("Analyze the code") btn.attrib["onclick"] = "exec_analyzer('%s')" % uid # add the display of the score add_scoring(page, btn, uid)
def add_load_file(page, parent, hidden_load_id, textarea_id): '''Inserts the widget required to browse for and load a local Python file. This is intended to be used to load a file in the editor. ''' js_script = """path = file; load_file('%s')""" % textarea_id insert_file_browser(page, parent, hidden_load_id, '/jquery_file_tree_all', _('Select a file to open'), js_script, "load_file") btn = SubElement(parent, 'button', onclick="c=getElementById('%s');c.style.visibility='hidden';c.style.zIndex=-1;"%hidden_load_id) btn.text = _("Cancel") return
def unittest_widget_callback(page, elem, uid): """Handles embedding suitable code into the page in order to display and run unittests""" vlam = elem.attrib["title"] log_id = extract_log_id(vlam) if log_id: t = 'unittest' config[page.username]['logging_uids'][uid] = (log_id, t) # When a security mode is set to "display ...", we only parse the # page, but no Python execution from is allowed from that page. # If that is the case, we won't include javascript either, to make # thus making the source easier to read. if 'display' not in config[page.username]['page_security_level'](page.url): if not page.includes("unittest_included") : page.add_include("unittest_included") page.add_js_code(unittest_jscode) elem.attrib['title'] = "python" unittestcode, show_vlam = plugin['services'].style(page, elem, None, vlam) elem.attrib['title'] = vlam if log_id: config['log'][log_id] = [tostring(markup)] # which we store unittests[uid] = unittestcode wrap_in_div(elem, uid, vlam, "doctest", show_vlam) if config[page.username]['popups']: # insert popup helper img = Element("img", src="/images/help.png", style="height:32px;", title = "cluetip Hello %s! "%page.username + "This is a unittest.; click for more.", rel = "/docs/popups/unittest.html") elem.append(img) plugin['services'].insert_cluetip(page, img, uid) #insert_markup(elem, uid, vlam, markup, "unittest") # call the insert_editor_subwidget service to insert an editor: plugin['services'].insert_editor_subwidget(page, elem, uid) #some spacing: SubElement(elem, "br") # the actual button used for code execution: btn = SubElement(elem, "button") btn.text = "Run Unittest" btn.attrib["onclick"] = "exec_unittest('%s')" % uid if "analyzer_score" in vlam: plugin['services'].add_scoring(page, btn, uid) if "analyzer_report" in vlam: plugin['services'].insert_analyzer_button(page, elem, uid) SubElement(elem, "br") # finally, an output subwidget: plugin['services'].insert_io_subwidget(page, elem, uid)
def code_sample_process(page, elem, uid): """Style and saves a copy of the sample code. This code currently does not work because it depends on the obsoleted style_pycode service in the colourize plugin.""" raise NotImplementedError() vlam = elem.attrib["title"] name = extract_name(vlam) names[uid] = name # When a security mode is set to "display ...", we only parse the # page, but no Python execution from is allowed from that page. # If that is the case, we won't include javascript either, to make # thus making the source easier to read. if 'display' not in config[page.username]['page_security_level'](page.url): if not page.includes("code_test_included") : page.add_include("code_test_included") page.add_js_code(code_test_jscode) page.add_js_code(complete_test_jscode) page.add_css_code(css) insert_comprehensive_test_button(page) # next, we style the code, also extracting it in a useful form sample_code, markup, error = plugin['services'].style_pycode(page, elem) if error is not None: markup = copy.deepcopy(elem) # which we store code_samples[name] = sample_code # reset the original element to use it as a container. For those # familiar with dealing with ElementTree Elements, in other context, # note that the style_pycode() method extracted all of the existing # text, removing any original markup (and other elements), so that we # do not need to save either the "text" attribute or the "tail" one # before resetting the element. elem.clear() elem.tag = "div" elem.attrib["id"] = "div_" + uid elem.attrib['class'] = "crunchy" # We insert the styled sample code inside this container element: elem.append(markup) # Create a title h4 = Element('h4') h4.text = "Sample code; name= %s" % name elem.insert(0, h4) #some spacing: SubElement(elem, "br") # the actual button used for code execution: btn = SubElement(elem, "button") btn.text = "Run code check" btn.attrib["onclick"] = "exec_code_check('%s')" % uid SubElement(elem, "br") # finally, an output subwidget: plugin['services'].insert_io_subwidget(page, elem, uid) return
def insert_editor_subwidget(page, elem, uid, code="\n"): # tested """inserts an Elementtree that is an editor, used to provide a basic insert_editor_subwidget service """ inp = SubElement(elem, "textarea") inp.attrib["rows"] = "10" inp.attrib["cols"] = "80" editor_id = "code_" + uid inp.attrib["id"] = editor_id if code == "": code = "\n" inp.text = code plugin['services'].enable_editarea(page, elem, editor_id)
def insert_load_remote(dummy_page, parent, dummy_uid): # tested '''inserts a form to load a remote page''' # in general, page and uid are used by similar plugins, but they are # redundant here. div = SubElement(parent, "div") p = SubElement(div, "p") p.text = _("Type url of remote tutorial.") form = SubElement(div, 'form', name='url', size='80', method='get', action='/remote') SubElement(form, 'input', name='url', size='80', value=parent.text) input2 = SubElement(form, 'input', type='submit', value=_('Load remote tutorial')) input2.attrib['class'] = 'crunchy' parent.text = ' '
def create_security_menu_item(page): '''creates the security report menu item''' if 'display' in page.security_info['level']: security_result_image = '/images/display.png' elif page.security_info['number removed'] == 0: security_result_image = '/images/ok.png' else: security_result_image = '/images/warning.png' security_item = Element("li") a = SubElement(security_item, "a", id="security_info_link", href="#", onclick= "show_security_info();", title="security_link") a.text = "Security: " SubElement(a, "img", src=security_result_image) additional_menu_items['security_report'] = security_item return
def confirm_at_start(page, info_container): ''' Asks for confirmation from the user for any pre-existing settings regarding security level for known sites. This is meant to be called only at the start of a given Crunchy session (hence the name of the function). ''' page.add_css_code(security_css % ('block', 'block')) h2 = SubElement(info_container, 'h2') h2.text = _('Confirm the security levels') h2.attrib['class'] = "crunchy" directions = SubElement(info_container, "h4") directions.text = _("Before browsing any further ...\n\n") directions.text += _( "Do you wish to retain the existing settings for these sites?\n\n") directions.text += _( "You can change any of them before clicking on the approve button.\n\n" ) # in case list gets too long, we include buttons at top and bottom of list nb_sites = len(config[page.username]['site_security']) add_button(info_container, nb_sites) for site_num, site in enumerate(config[page.username]['site_security']): format_site_security_options(info_container, site, site_num, page) add_button(info_container, nb_sites) return
def insert_editor(page, elem, uid, lines, lineno): '''insert the an editor as usual''' # Note: in developping this plugin, we observed that the code was styled # automatically - that is the "div/getsource" handler was called before the # "pre" handler was. This could just be a coincidence on which we can not # rely. pre = SubElement(elem, "pre") if python_version < 3: vlam = "python" else: vlam = "python3" if "linenumber" in elem.attrib['title']: vlam += " linenumber=%s"%lineno pre.attrib['title'] = vlam pre.text ="".join(lines) plugin['services'].insert_editor(page, pre, uid) # prevent any further processing pre.attrib["title"] = "no_vlam" return
def insert_file_tree(page, elem, uid, action, callback, title, label): '''inserts a file tree object in a page.''' if 'display' not in config[page.username]['page_security_level'](page.url): if not page.includes("jquery_file_tree"): page.add_include("jquery_file_tree") page.insert_js_file("/javascript/jquery.filetree.js") page.insert_css_file("/css/jquery.filetree.css") else: return tree_id = "tree_" + uid form_id = "form_" + uid root = local_browser_root # use value specified in config.py by default if not os.path.exists(root): root = os.path.splitdrive(__file__)[0] + "/" # use base directory js_code = """$(document).ready( function() { $('#%s').fileTree({ root: '%s', script: '%s', expandSpeed: -1, collapseSpeed: -1, multiFolder: false }, function(file) { document.getElementById('%s').value=file; }); }); """ % (tree_id, root, action, form_id) page.add_js_code(js_code) elem.text = title elem.attrib['class'] = "filetree_wrapper" form = SubElement(elem, 'form', name='url', size='80', method='get', action=callback) SubElement(form, 'input', name='url', size='80', id=form_id) input_ = SubElement(form, 'input', type='submit', value=label) input_.attrib['class'] = 'crunchy' file_div = SubElement(elem, 'div') file_div.attrib['id'] = tree_id file_div.attrib['class'] = "filetree_window" return
def add_button(info_container, nb_sites): '''adds button for site approval or removal''' approve_btn = SubElement(info_container, "button", onclick="app_approve(%d)" % nb_sites) approve_btn.text = _("Approve") SubElement(info_container, "span").text = " " deny_btn = SubElement(info_container, "button", onclick="app_remove_all()") deny_btn.text = _("Remove all") return
def create_security_menu_item(page): '''creates the security report menu item''' if 'display' in page.security_info['level']: security_result_image = '/images/display.png' elif page.security_info['number removed'] == 0: security_result_image = '/images/ok.png' else: security_result_image = '/images/warning.png' security_item = Element("li") a = SubElement(security_item, "a", id="security_info_link", href="#", onclick="show_security_info();", title="security_link") a.text = "Security: " SubElement(a, "img", src=security_result_image) additional_menu_items['security_report'] = security_item return
def insert_interactive_objects(page): '''inserts the interactive objects required in a slideshow''' if not page.includes("slideshow_included"): return for div in page.tree.getiterator("div"): if 'class' in div.attrib: if div.attrib['class'] == "presentation": # add slide with interpreter new_div = Element("div") new_div.attrib['class'] = "slide" # new_div is not processed by set_overflow above which is why # we must set this property explictly. new_div.attrib['style'] = "height: 70%; overflow: auto;" new_div.attrib['id'] = "crunchy_interpreter" pre = SubElement(new_div, "pre", title="interpreter") # the following text is at least 50 characters # with a non-space character at the end. This is to allow # the creation of a list with "short" titles to select # a given slide. # see slides.js line 100 pre.text = "# Crunchy Interpreter #" uid = page.pageid + "_" + uidgen(page.username) plugin['services'].insert_interpreter(page, pre, uid) div.append(new_div) # add slide with editor new_div2 = Element("div") new_div2.attrib['class'] = "slide" # new_div2 is not processed by set_overflow above ... new_div2.attrib['style'] = "height: 70%; overflow: auto;" new_div2.attrib['id'] = "crunchy_editor" pre2 = SubElement(new_div2, "pre", title="editor") # same as above. pre2.text = "# Crunchy editor #" uid = page.pageid + "_" + uidgen(page.username) plugin['services'].insert_editor(page, pre2, uid) div.append(new_div2) return
def add_save_file(page, parent, hidden_save_id, textarea_id): '''Inserts the widget required to browse for and save a local Python file. This is intended to be used to save a file from the editor. ''' input_id = "input_" + hidden_save_id js_saved_script = """save_file(document.getElementById('%s').value, '%s');""" % (input_id, textarea_id) SubElement(parent, "br") SubElement(parent, 'input', name='url', size='60', id=input_id) SubElement(parent, "br") btn = SubElement(parent, 'button', onclick=js_saved_script) btn.text = _("Save file") js_script = """document.getElementById('%s').value=file;""" % input_id insert_file_browser(page, parent, hidden_save_id, '/jquery_file_tree_all', _('Select a file to save'), js_script, "save_file") btn = SubElement(parent, 'button', onclick="c=getElementById('%s');c.style.visibility='hidden';c.style.zIndex=-1;"%hidden_save_id) btn.text = _("Cancel") return
def format_table(parent, title, headings, content): '''formats a report in a standard table form''' h2 = SubElement(parent, 'h2') h2.text = title h2.attrib['class'] = "crunchy" table = SubElement(parent, 'table') table.attrib['class'] = 'summary' tr = SubElement(table, 'tr') for item in headings: th = SubElement(tr, 'th') th.text = item for item in content: tr = SubElement(table, 'tr') for cell in item: td = SubElement(tr, 'td') td.text = str(cell) return
def unittest_widget_callback(page, elem, uid): """Handles embedding suitable code into the page in order to display and run unittests""" vlam = elem.attrib["title"] log_id = extract_log_id(vlam) if log_id: t = 'unittest' config[page.username]['logging_uids'][uid] = (log_id, t) # When a security mode is set to "display ...", we only parse the # page, but no Python execution from is allowed from that page. # If that is the case, we won't include javascript either, to make # thus making the source easier to read. if 'display' not in config[page.username]['page_security_level'](page.url): if not page.includes("unittest_included"): page.add_include("unittest_included") page.add_js_code(unittest_jscode) elem.attrib['title'] = "python" unittestcode, show_vlam = plugin['services'].style(page, elem, None, vlam) elem.attrib['title'] = vlam if log_id: config['log'][log_id] = [tostring(markup)] # which we store unittests[uid] = unittestcode wrap_in_div(elem, uid, vlam, "doctest", show_vlam) if config[page.username]['popups']: # insert popup helper img = Element("img", src="/images/help.png", style="height:32px;", title="cluetip Hello %s! " % page.username + "This is a unittest.; click for more.", rel="/docs/popups/unittest.html") elem.append(img) plugin['services'].insert_cluetip(page, img, uid) #insert_markup(elem, uid, vlam, markup, "unittest") # call the insert_editor_subwidget service to insert an editor: plugin['services'].insert_editor_subwidget(page, elem, uid) #some spacing: SubElement(elem, "br") # the actual button used for code execution: btn = SubElement(elem, "button") btn.text = "Run Unittest" btn.attrib["onclick"] = "exec_unittest('%s')" % uid if "analyzer_score" in vlam: plugin['services'].add_scoring(page, btn, uid) if "analyzer_report" in vlam: plugin['services'].insert_analyzer_button(page, elem, uid) SubElement(elem, "br") # finally, an output subwidget: plugin['services'].insert_io_subwidget(page, elem, uid)
def confirm_at_start(page, info_container): ''' Asks for confirmation from the user for any pre-existing settings regarding security level for known sites. This is meant to be called only at the start of a given Crunchy session (hence the name of the function). ''' page.add_css_code(security_css%('block','block')) h2 = SubElement(info_container, 'h2') h2.text = _('Confirm the security levels') h2.attrib['class'] = "crunchy" directions = SubElement(info_container, "h4") directions.text = _("Before browsing any further ...\n\n") directions.text += _("Do you wish to retain the existing settings for these sites?\n\n") directions.text += _("You can change any of them before clicking on the approve button.\n\n") # in case list gets too long, we include buttons at top and bottom of list nb_sites = len(config[page.username]['site_security']) add_button(info_container, nb_sites) for site_num, site in enumerate(config[page.username]['site_security']): format_site_security_options(info_container, site, site_num, page) add_button(info_container, nb_sites) return
def code_sample_process(page, elem, uid): """Style and saves a copy of the sample code. This code currently does not work because it depends on the obsoleted style_pycode service in the colourize plugin.""" raise NotImplementedError() vlam = elem.attrib["title"] name = extract_name(vlam) names[uid] = name # When a security mode is set to "display ...", we only parse the # page, but no Python execution from is allowed from that page. # If that is the case, we won't include javascript either, to make # thus making the source easier to read. if 'display' not in config[page.username]['page_security_level'](page.url): if not page.includes("code_test_included"): page.add_include("code_test_included") page.add_js_code(code_test_jscode) page.add_js_code(complete_test_jscode) page.add_css_code(css) insert_comprehensive_test_button(page) # next, we style the code, also extracting it in a useful form sample_code, markup, error = plugin['services'].style_pycode(page, elem) if error is not None: markup = copy.deepcopy(elem) # which we store code_samples[name] = sample_code # reset the original element to use it as a container. For those # familiar with dealing with ElementTree Elements, in other context, # note that the style_pycode() method extracted all of the existing # text, removing any original markup (and other elements), so that we # do not need to save either the "text" attribute or the "tail" one # before resetting the element. elem.clear() elem.tag = "div" elem.attrib["id"] = "div_" + uid elem.attrib['class'] = "crunchy" # We insert the styled sample code inside this container element: elem.append(markup) # Create a title h4 = Element('h4') h4.text = "Sample code; name= %s" % name elem.insert(0, h4) #some spacing: SubElement(elem, "br") # the actual button used for code execution: btn = SubElement(elem, "button") btn.text = "Run code check" btn.attrib["onclick"] = "exec_code_check('%s')" % uid SubElement(elem, "br") # finally, an output subwidget: plugin['services'].insert_io_subwidget(page, elem, uid) return
def add_hidden_load_and_save(page, elem, textarea_id): # tested ''' adds hidden load and save javascript objects on a page ''' hidden_load_id = 'hidden_load' + textarea_id hidden_load = SubElement(elem, 'div', id=hidden_load_id) hidden_load.attrib['class'] = 'load_file' add_load_file(page, hidden_load, hidden_load_id, textarea_id) hidden_save_id = 'hidden_save' + textarea_id hidden_save = SubElement(elem, 'div', id=hidden_save_id) hidden_save.attrib['class'] = 'save_file' add_save_file(page, hidden_save, hidden_save_id, textarea_id) return
def insert_preferences(page, elem, uid): '''insert the requested preference choosers on a page''' if not page.includes("set_config"): page.add_include("set_config") page.add_js_code(set_config_jscode) page.add_js_code(gritter_jscode) page.add_include("jquery.gritter.js") page.insert_js_file("/javascript/jquery.gritter.js") page.insert_css_file("/css/gritter.css") # The original div in the raw html page may contain some text # as a visual reminder that we need to remove here. elem.text = '' elem.attrib['class'] = 'config_gui' parent = SubElement(elem, 'table') username = page.username to_show = elem.attrib['title'].split(' ') if len(to_show) == 1: # choices = "preferences"; all values are shown to_show = ['boolean', 'multiple_choice', 'user_defined'] show(parent, username, uid, to_show) return
def render(self, elem): """render the widget to a particular file object""" row = SubElement(elem, 'tr') option = SubElement(row, 'td') label = SubElement(option, 'label') label.attrib['for'] = self.key label.text = "%s: " % self.key # we use a unique id, rather than simply the key, in case two # identical preference widgets are on the same page... _id = str(self.uid) + "__KEY__" + str(self.key) input = SubElement(option, 'input', type = 'text', id = _id, name = self.key, value = self.get(), onchange = "growl_show('%s');set_config('%s', '%s');" % (self.key, _id, self.key) ) input.attrib['class'] = 'config_gui' desc = SubElement(row, 'td') desc.text = str(getattr(get_prefs(self.username).__class__, self.key).__doc__)
def pdb_widget_callback(page, elem, uid): """Handles embedding suitable code into the page in order to display and run pdb""" # When a security mode is set to "display ...", we only parse the # page, but no Python execution from is allowed from that page. # If that is the case, we won't include javascript either, to make # thus making the source easier to read. if 'display' not in config[page.username]['page_security_level'](page.url): if not page.includes("pdb_included"): page.add_include("pdb_included") #element tree always escape < to < and break my js code , so... page.insert_js_file("/pdb_js%s.js" % plugin['session_random_id']) if not page.includes("pdb_css_code"): page.add_include("pdb_css_code") page.add_css_code(pdb_css) # next, we style the code, also extracting it in a useful form ... vlam = elem.attrib["title"] python_code = util.extract_code(elem) if util.is_interpreter_session(python_code): elem.attrib['title'] = "pycon" python_code = util.extract_code_from_interpreter(python_code) else: elem.attrib['title'] = "python" code, show_vlam = plugin['services'].style(page, elem, None, vlam) elem.attrib['title'] = vlam util.wrap_in_div(elem, uid, vlam, "pdb", show_vlam) plugin['services'].insert_editor_subwidget(page, elem, uid, python_code) t = SubElement(elem, "h4", style="background-color:white;color:darkblue;") t.text = _("Local Namespace") local_ns_div = SubElement(elem, "div") local_ns_div.attrib["id"] = "local_ns_%s" % uid #some spacing: SubElement(elem, "br") btn = SubElement(elem, "button") btn.text = _("Start PDB") btn.attrib["onclick"] = "init_pdb('%s');" % (uid) btn.attrib["id"] = "btn_start_pdb_%s" % uid btn = SubElement(elem, "button") btn.text = _("Next Step") btn.attrib["id"] = "btn_next_step_%s" % uid btn.attrib["disabled"] = "disabled" btn = SubElement(elem, "button") btn.text = _("Step Into") btn.attrib["id"] = "btn_step_into_%s" % uid btn.attrib["disabled"] = "disabled" btn = SubElement(elem, "button") btn.text = _("Return") btn.attrib["id"] = "btn_return_%s" % uid btn.attrib["disabled"] = "disabled" btn = SubElement(elem, "button") btn.text = _("Next Multiple Steps") btn.attrib["id"] = "btn_next_many_steps_%s" % uid btn.attrib["disabled"] = "disabled" input1 = SubElement(elem, 'input', id='input_many_' + uid, size='4', value='1') t = SubElement(elem, "h4", style="background-color:white;color:darkblue;") t.text = _("Output") # finally, an output subwidget: plugin['services'].insert_io_subwidget(page, elem, uid) #register before_ouput hook plugin['services'].register_io_hook('before_output', pdb_filter, uid) #create pdb file cache for uid pdb_py_files[uid] = {}
def format_report(page, div): '''puts the security information (extracted material) into a table for display''' security_level = SubElement(div, 'h2') security_level.attrib['class'] = 'crunchy' security_level.text = "Security level: " + page.security_info['level'] security_summary = SubElement(div, 'h4') s_image = SubElement(security_summary, 'img') # make sure src link is not transformed: s_image.attrib['title'] = 'security_link' if 'display' in page.security_info['level']: s_image.attrib['src'] = '/images/display_big.png' s_image.tail = " : display mode selected; Python code execution forbidden." elif page.security_info['number removed'] == 0: s_image.attrib['src'] = '/images/ok_big.png' s_image.tail = " : clean page; nothing was removed by Crunchy." else: s_image.tail = " : Some html tags and/or attributes were removed by Crunchy." s_image.attrib['src'] = '/images/warning_big.png' if page.security_info['tags removed']: title = _('Removed: tag not allowed') headings = [_('Tag removed'), _('Number of times')] content = page.security_info['tags removed'] format_table(div, title, headings, content) if page.security_info['attributes removed']: title = _('Removed: attribute, or attribute value not allowed') headings = [_('Tag'), _('Attribute'), _('Value (if relevant)')] content = page.security_info['attributes removed'] format_table(div, title, headings, content) if page.security_info['styles removed']: title = _('Removed: style tag or attribute not allowed') headings = [_('Tag'), _('Attribute (if relevant)'), _('Value')] content = page.security_info['styles removed'] format_table(div, title, headings, content) #netloc = urlsplit(page.url).netloc # localhost will return empty string # urlsplit().netloc == urlsplit()[1] is not Python 2.4 compatible netloc = urlsplit(page.url)[1] if netloc: site = netloc else: site = "localhost (127.0.0.1)" h2 = SubElement(div, 'h2') h2.text = _('You may select a site specific security level:') h2.attrib['class'] = "crunchy" if netloc in config[page.username]['site_security']: p = SubElement(div, 'p') p.text = _("If you want to preserve the existing selection, ") p.text += _("simply dismiss this window by clicking on the X above.") format_site_security_options(div, site, 0, page) approve_btn = SubElement(div, "button") approve_btn.attrib["onclick"] = "javascript:allow_site();" approve_btn.text = _("Select site security level") for item in explanations: p = SubElement(div, 'p') p.text = item return
def format_site_security_options(parent, site, site_num, page): '''adds the various security options for a given site''' options = ['trusted', 'normal', 'strict', 'display trusted', 'display normal', 'display strict'] if 'localhost' not in site: options.append('remove') fieldset = SubElement(parent, "fieldset") site_label = SubElement(fieldset, "legend") site_label.text = site form = SubElement(fieldset, "form") form.attrib['id'] = "site_" + str(site_num+1) form.attrib['name'] = site for option in options: label = SubElement(form, 'label') if option == 'remove': label.text = _('remove from list') else: label.text = option label.attrib['for'] = site + option inp = SubElement(label, 'input', value=option, type='radio', name='rad', id=site+option) SubElement(form, 'br') if site in config[page.username]['site_security']: if option == config[page.username]['site_security'][site]: inp.attrib['checked'] = 'checked' elif 'localhost' in site: if option == config[page.username]['local_security']: inp.attrib['checked'] = 'checked' return
def format_site_security_options(parent, site, site_num, page): '''adds the various security options for a given site''' options = [ 'trusted', 'normal', 'strict', 'display trusted', 'display normal', 'display strict' ] if 'localhost' not in site: options.append('remove') fieldset = SubElement(parent, "fieldset") site_label = SubElement(fieldset, "legend") site_label.text = site form = SubElement(fieldset, "form") form.attrib['id'] = "site_" + str(site_num + 1) form.attrib['name'] = site for option in options: label = SubElement(form, 'label') if option == 'remove': label.text = _('remove from list') else: label.text = option label.attrib['for'] = site + option inp = SubElement(label, 'input', value=option, type='radio', name='rad', id=site + option) SubElement(form, 'br') if site in config[page.username]['site_security']: if option == config[page.username]['site_security'][site]: inp.attrib['checked'] = 'checked' elif 'localhost' in site: if option == config[page.username]['local_security']: inp.attrib['checked'] = 'checked' return
def create_home(): # tested '''creates the home element for the menu''' home = Element("li") a = SubElement(home, "a", href="/index.html") a.text = _("Crunchy Home") return home
def create_quit(): # tested '''creates the quit element for the menu''' Quit = Element("li") a = SubElement(Quit, "a", href=server['exit']) a.text = _("Quit Crunchy") return Quit
def rst_edit_setup(page, elem, uid): elem.tag = "div" # editor textarea = SubElement(elem, "textarea", name="rst_enter") textarea.attrib["id"] = uid + "_rst_edit" textarea.attrib["class"] = "rst_enter" textarea.text = elem.text elem.text = '' plugin['services'].enable_editarea(page, elem, textarea.attrib["id"], syntax="robotstxt") if not page.includes("editarea_included"): page.add_include("editarea_included") page.add_js_code(editArea_load_and_save) page.insert_js_file("/edit_area/edit_area_crunchy.js") # save html button = SubElement(elem, "button") button.text = _("Save html") # preview area div = SubElement(elem, "div") div.attrib["id"] = "html_preview" page.add_js_code(js_code) # hidden save file hidden_div = SubElement(elem, "div") h_uid = "hidden_div_" + uid hidden_div.attrib["id"] = h_uid button.attrib["onclick"] = show_save_file_js % h_uid add_save_file(page, hidden_div, h_uid, div.attrib["id"]) page.add_js_code(save_html_file_js % (h_uid, h_uid)) if page.is_local: src.interface.path_info['source_base_dir'] = page.url else: src.interface.path_info['source_base_dir'] = os.path.normpath( os.path.join(plugin['crunchy_base_dir'](), "server_root", page.url[1:])) base_dir = os.path.dirname(src.interface.path_info['source_base_dir']) if base_dir not in sys.path: sys.path.insert(0, base_dir)
def insert_alternate_python(page, elem, uid): """inserts the required widget to launch a Python script using an alternate Python version. """ vlam = insert_bare_editor(page, elem, uid) form1 = SubElement(elem, 'form', name='form1_') span = SubElement(form1, 'span') span.text = _('Alternate Python path: ') span.attrib['class'] = 'alt_python' input1 = SubElement( form1, 'input', id='input1_' + uid, size='50', value=config[page.username]['alternate_python_version']) input1.attrib['class'] = 'alt_python' SubElement(elem, "br") btn = SubElement(elem, "button") btn.attrib[ "onclick"] = "exec_code_externally_python_interpreter('%s')" % uid btn.text = _("Execute as external program") if "analyzer_score" in vlam: plugin['services'].add_scoring(page, btn, uid) if "analyzer_report" in vlam: plugin['services'].insert_analyzer_button(page, elem, uid) path_label = SubElement(elem, "span", id='path_' + uid) path_label.text = config[ page.username]['temp_dir'] + os.path.sep + "temp.py" path_label.attrib['class'] = 'path_info'
def insert_io_subwidget(page, elem, uid, interp_kind=None, sample_code='', show=False): # partially tested """insert an output widget into elem, usable for editors and interpreters, and includes a canvas. """ # embed the io widget inside a div so that it could be floated left # or right ... or whatever. # insert another div below, that can have it style set to "clear:both;" # so that it can work together with the floated io widget # (and python code sample) to have a two-column display if desired. new_div = SubElement(elem, "div") new_div.attrib['class'] = "io_div " + interface.crunchy_pygments clear_div = SubElement(elem, "div") clear_div.attrib['class'] = "end_io_widget" # When a security mode is set to "display ...", we only parse the # page, but no Python execution from is allowed from that page. # If that is the case, we won't include javascript either, to make # thus making the source easier to read. if 'display' not in config[page.username]['page_security_level'](page.url): if config['ctypes_available']: kill_link = Element("a") elem.insert(-2, kill_link) kill_link.attrib["id"] = "kill_%s" % uid kill_link.attrib["onclick"] = "kill_thread('%s')" % uid kill_image = SubElement(kill_link, 'img') kill_image.attrib["src"] = "/images/stop.png" kill_image.attrib["alt"] = _("Interrupt thread") kill_image.attrib["class"] = "kill_thread_image" _id = "kill_image_%s" % uid kill_image.attrib["id"] = _id if config[page.username]['popups']: # insert popup helper kill_image.attrib["title"] = "cluetip KeyboardInterrupt" kill_image.attrib["rel"] = "/docs/popups/keyboard_interrupt.html" plugin['services'].insert_cluetip(page, kill_image, _id) # hide them initially kill_image.attrib['style'] = 'display: none;' kill_link.attrib['style'] = 'display: none;' if not page.includes("io_included"): page.add_include("io_included") page.add_js_code(io_js) if interp_kind is not None: if not page.includes("push_input_included"): page.add_include("push_input_included") page.add_js_code(push_input) # needed for switching to edit area; not currently working if not page.includes("editarea_included"): page.add_include("editarea_included") page.add_js_code(editArea_load_and_save) page.insert_js_file("/edit_area/edit_area_crunchy.js") elif config['ctypes_available']: kill_image.attrib['style'] = 'display:none;' # revealed by Execute button else: return output = SubElement(new_div, "span") output.attrib["class"] = "output" output.attrib["id"] = "out_" + uid output.text = "\n" span_input = SubElement(new_div, "span") inp = SubElement(span_input, "input") inp.attrib["id"] = "in_" + uid inp.attrib["onkeydown"] = 'return push_keys(event, "%s")' % uid if interp_kind is not None: editor_link = SubElement(span_input, "a") editor_link.attrib["onclick"] = "return convertToEditor(this,'%s')" \ % _("Execute") editor_link.attrib["id"] = "ed_link_" + uid image = SubElement(editor_link, 'img') image.attrib["src"] = "/images/editor.png" image.attrib["alt"] = _("copy existing code") image.attrib["class"] = "interpreter_image" code_sample = SubElement(new_div, "textarea") code_sample.attrib["id"] = "code_sample_" + uid code_sample.attrib["style"] = 'visibility:hidden;overflow:hidden;z-index:-1;position:fixed;top:0;' code_sample.text = sample_code + '\n' if interp_kind == 'borg': inp.attrib["onkeypress"] = 'return tooltip_display(event, "%s")' % uid inp.attrib["type"] = "text" if show: inp.attrib["class"] = "input" else: inp.attrib["class"] = "input hidden"
def insert_editor(page, elem, uid): """handles the editor widget""" vlam = insert_bare_editor(page, elem, uid) #log_id = util.extract_log_id(vlam) SubElement(elem, "br") if not ("no_internal" in vlam and "external" in vlam): btn1 = SubElement(elem, "button") btn1.attrib["onclick"] = "exec_code('%s')" % uid SubElement(elem, "br") btn2 = SubElement(elem, "button", id="run_from_file_" + uid) btn2.attrib["onclick"] = "exec_code_externally('%s')" % uid btn2.text = _("Save and Run from file") path_label = SubElement(elem, "span") path_label.attrib['id'] = 'path_' + uid path_label.attrib['class'] = 'path_info' if "external" in vlam: path_label.text = config[ page.username]['temp_dir'] + os.path.sep + "temp.py" if "analyzer_score" in vlam: plugin['services'].add_scoring(page, btn2, uid) if not "no_internal" in vlam: btn1.text = _("Execute as separate thread") else: path_label.text = "" # effectively hides it. btn1.text = _("Execute") # Note that btn2 will be revealed by execution code when a file is saved; # see editarea.py for this. btn2.attrib['style'] = "display:none;" if "analyzer_score" in vlam: plugin['services'].add_scoring(page, btn1, uid) if "analyzer_report" in vlam: SubElement(elem, "br") plugin['services'].insert_analyzer_button(page, elem, uid) SubElement(elem, "br") plugin['services'].insert_io_subwidget(page, elem, uid)
def rst_edit_setup(page, elem, uid): elem.tag = "div" # editor textarea = SubElement(elem, "textarea", name="rst_enter") textarea.attrib["id"] = uid + "_rst_edit" textarea.attrib["class"] = "rst_enter" textarea.text = elem.text elem.text = "" plugin["services"].enable_editarea(page, elem, textarea.attrib["id"], syntax="robotstxt") if not page.includes("editarea_included"): page.add_include("editarea_included") page.add_js_code(editArea_load_and_save) page.insert_js_file("/edit_area/edit_area_crunchy.js") # save html button = SubElement(elem, "button") button.text = _("Save html") # preview area div = SubElement(elem, "div") div.attrib["id"] = "html_preview" page.add_js_code(js_code) # hidden save file hidden_div = SubElement(elem, "div") h_uid = "hidden_div_" + uid hidden_div.attrib["id"] = h_uid button.attrib["onclick"] = show_save_file_js % h_uid add_save_file(page, hidden_div, h_uid, div.attrib["id"]) page.add_js_code(save_html_file_js % (h_uid, h_uid)) if page.is_local: src.interface.path_info["source_base_dir"] = page.url else: src.interface.path_info["source_base_dir"] = os.path.normpath( os.path.join(plugin["crunchy_base_dir"](), "server_root", page.url[1:]) ) base_dir = os.path.dirname(src.interface.path_info["source_base_dir"]) if base_dir not in sys.path: sys.path.insert(0, base_dir)
def doctest_widget_callback(page, elem, uid): """Handles embedding suitable code into the page in order to display and run doctests""" vlam = elem.attrib["title"] log_id = extract_log_id(vlam) vlam_info = parse_vlam(vlam) limit_time = vlam_info.get("time", None) exam_name = vlam_info.get("exam_name", None) # We check to see if an exam name has been defined (in exam_mode.py). # This is only defined when a test has started. if exam_name: if page.username not in exams: elem.clear() return elif exam_name not in exams[page.username]: elem.clear() return else: exams[page.username][exam_name]['problems'].append(uid) if log_id: t = 'doctest' config[page.username]['logging_uids'][uid] = (log_id, t) # When a security mode is set to "display ...", we only parse the # page, but no Python execution from is allowed from that page. # If that is the case, we won't include javascript either, to make # thus making the source easier to read. if 'display' not in config[page.username]['page_security_level'](page.url): if not page.includes("doctest_included") : page.add_include("doctest_included") page.add_js_code(doctest_jscode) # next, we style the code, also extracting it in a useful form ... elem.attrib['title'] = "pycon" doctestcode, show_vlam = plugin['services'].style(page, elem, None, vlam) # remove trailing white spaces, which may mess the expected output... doctestcode_lines = doctestcode.split('\n') for i in range(len(doctestcode_lines)): doctestcode_lines[i] = doctestcode_lines[i].rstrip() doctestcode = '\n'.join(doctestcode_lines) elem.attrib['title'] = vlam if log_id: config[page.username]['log'][log_id] = [tostring(elem)] # which we store doctests[uid] = doctestcode wrap_in_div(elem, uid, vlam, "doctest", show_vlam) if config[page.username]['popups']: # insert popup helper img = Element("img", src="/images/help.png", style="height:32px;", title = "cluetip Hello %s! "%page.username + "This is a doctest.; click for more", rel = "/docs/popups/doctest.html") elem.append(img) plugin['services'].insert_cluetip(page, img, uid) # call the insert_editor_subwidget service to insert an editor: plugin['services'].insert_editor_subwidget(page, elem, uid) #some spacing: SubElement(elem, "br") # the actual button used for code execution: btn = SubElement(elem, "button") btn.attrib["id"] = "run_doctest_btn_" + uid btn.text = _("Run Doctest") btn.attrib["onclick"] = "exec_doctest('%s')" % uid if "analyzer_score" in vlam: plugin['services'].add_scoring(page, btn, uid) if "analyzer_report" in vlam: plugin['services'].insert_analyzer_button(page, elem, uid) SubElement(elem, "br") if limit_time: page.add_js_code("window.addEventListener('load', function(e){count_down('%s', get_doctest_time('%s'));}, false);" %(uid, uid)) # finally, an output subwidget: plugin['services'].insert_io_subwidget(page, elem, uid)
def get_pygments_tokens(page, elem, uid): """inserts a table containing all existent token types and corresponding css class, with an example""" # The original div in the raw html page may contain some text # as a visual reminder that we need to remove here. elem.text = '' elem.attrib['class'] = CRUNCHY_PYGMENTS table = SubElement(elem, 'table') row = SubElement(table, 'tr') for title in ['Token type', 'css class']: column = SubElement(row, 'th') column.text = title keys = list(STANDARD_TYPES.keys()) keys.sort() for token in keys: if len(repr(token)) == 5: # token = Token continue row = SubElement(table, 'tr') column1 = SubElement(row, 'td') column1.text = repr(token)[6:] # remove "Token." column2 = SubElement(row, 'td') token_class = STANDARD_TYPES[token] column2.text = token_class.split('_')[0] column3 = SubElement(row, 'td') span = SubElement(column3, 'span') span.attrib['class'] = token_class span.text = " * test * " column4 = SubElement(row, 'td') _code = SubElement(column4, 'code') _code.attrib['class'] = token_class _code.text = " * test * " column5 = SubElement(row, 'td') var = SubElement(column5, 'var') var.attrib['class'] = token_class var.text = " * test * " return
def pdb_widget_callback(page, elem, uid): """Handles embedding suitable code into the page in order to display and run pdb""" # When a security mode is set to "display ...", we only parse the # page, but no Python execution from is allowed from that page. # If that is the case, we won't include javascript either, to make # thus making the source easier to read. if 'display' not in config[page.username]['page_security_level'](page.url): if not page.includes("pdb_included"): page.add_include("pdb_included") #element tree always escape < to < and break my js code , so... page.insert_js_file("/pdb_js%s.js"%plugin['session_random_id']) if not page.includes("pdb_css_code"): page.add_include("pdb_css_code") page.add_css_code(pdb_css) # next, we style the code, also extracting it in a useful form ... vlam = elem.attrib["title"] python_code = util.extract_code(elem) if util.is_interpreter_session(python_code): elem.attrib['title'] = "pycon" python_code = util.extract_code_from_interpreter(python_code) else: elem.attrib['title'] = "python" code, show_vlam = plugin['services'].style(page, elem, None, vlam) elem.attrib['title'] = vlam util.wrap_in_div(elem, uid, vlam, "pdb", show_vlam) plugin['services'].insert_editor_subwidget(page, elem, uid, python_code) t = SubElement(elem, "h4", style="background-color:white;color:darkblue;") t.text = _("Local Namespace") local_ns_div = SubElement(elem, "div") local_ns_div.attrib["id"] = "local_ns_%s"%uid #some spacing: SubElement(elem, "br") btn = SubElement(elem, "button") btn.text = _("Start PDB") btn.attrib["onclick"] = "init_pdb('%s');" %(uid) btn.attrib["id"] = "btn_start_pdb_%s" % uid btn = SubElement(elem, "button") btn.text = _("Next Step") btn.attrib["id"] = "btn_next_step_%s" % uid btn.attrib["disabled"] = "disabled" btn = SubElement(elem, "button") btn.text = _("Step Into") btn.attrib["id"] = "btn_step_into_%s" % uid btn.attrib["disabled"] = "disabled" btn = SubElement(elem, "button") btn.text = _("Return") btn.attrib["id"] = "btn_return_%s" % uid btn.attrib["disabled"] = "disabled" btn = SubElement(elem, "button") btn.text = _("Next Multiple Steps") btn.attrib["id"] = "btn_next_many_steps_%s" % uid btn.attrib["disabled"] = "disabled" input1 = SubElement(elem, 'input', id='input_many_'+uid, size='4', value='1') t = SubElement(elem, "h4", style="background-color:white;color:darkblue;") t.text = _("Output") # finally, an output subwidget: plugin['services'].insert_io_subwidget(page, elem, uid) #register before_ouput hook plugin['services'].register_io_hook('before_output', pdb_filter, uid) #create pdb file cache for uid pdb_py_files[uid] = {}
def hidden_code_widget_callback(page, elem, uid): """Handles embedding suitable code into the page in order to display and run code samples""" vlam = elem.attrib["title"] config["extracted_lines"][uid] = [] # When a security mode is set to "display ...", we only parse the # page, but no Python execution from is allowed from that page. # If that is the case, we won't include javascript either, to make # thus making the source easier to read. if 'display' not in config[page.username]['page_security_level'](page.url): if not page.includes("hidden_code_included"): page.add_include("hidden_code_included") page.add_js_code(hidden_code_jscode) elem.attrib['title'] = "py" complete_code, show_vlam = plugin['services'].style(page, elem, None, vlam) # _lines = complete_code.split('\n') displayed_lines = [] hidden_lines = [] hide = False for _line in _lines: if hide: if _line.strip() == HIDDEN_CODE_END: hide = False config["extracted_lines"][uid].append('\n'.join(hidden_lines)) else: hidden_lines.append(_line) else: if _line.strip() == HIDDEN_CODE_BEGIN: hide = True hidden_lines = [] displayed_lines.append(HIDDEN_CODE_MARKER) else: displayed_lines.append(_line) complete_code = '\n'.join(displayed_lines) elem.attrib['title'] = vlam elem.attrib["class"] += " hidden" elem.attrib["id"] = "hidden_pre_" + uid wrap_in_div(elem, uid, vlam, "hidden_code", show_vlam) btn = SubElement(elem, "button") btn.text = _("Show/hide complete code") btn.attrib["onclick"] = "$('#%s').toggle()" % ("hidden_pre_" + uid) plugin['services'].insert_editor_subwidget(page, elem, uid, complete_code) SubElement(elem, "br") btn = SubElement(elem, "button") btn.attrib["id"] = "run_code_btn_" + uid btn.text = _("Run Code") btn.attrib["onclick"] = "exec_hidden_code('%s')" % uid SubElement(elem, "br") plugin['services'].insert_io_subwidget(page, elem, uid)