def preview_blog(): if not check_login(): return redirect(URL('login')) blog_text = "Empty" if request.post_vars['preview_text'] is not None: blog_text = markdown(request.post_vars['preview_text']) return blog_text
def _markdown_to_html(markdown_src='', open_links_in_new_window=False): html = XML(markdown(markdown_src, extras={'link-patterns':None}, link_patterns=[(link_regex, link_replace)]).encode('utf-8'), sanitize=False).flatten() if open_links_in_new_window: html = re.sub(r' href=', r' target="_blank" href=', html) return html
def advanced_repr(value, row): 'representa los primeros caracteres de un texto editado por advanced_editor' if not value: return '' mdtext = html2text.html2text(value) if len(mdtext) >= 300: mdtext = mdtext[:280] + ' ...' mdtext = mdtext.replace('\n', ' ') return XML(markdown(mdtext))
def taxonomy_version(): view_dict = default_view_dict.copy() # load taxonomy-version history and basic stats ott = json.loads(fetch_local_ott_stats() or '[]') if len(ott) == 0: # report this error on the page view_dict['taxonomy_version'] = 'NO VERSIONS FOUND' view_dict['taxonomy_stats'] = ott return view_dict # Get OTT version from URL, or bounce to the latest version by default if len(request.args) == 0: # safer to sort by date-strings [yyyy-mm-dd] than version strings sorted_ott = sorted(ott, key=lambda v: v['date'], reverse=False) taxonomy_version = sorted_ott[-1].get('version') redirect( URL('opentree', 'about', 'taxonomy_version', vars={}, args=[taxonomy_version])) taxo_version = request.args[0] view_dict['taxonomy_version'] = taxo_version view_dict['taxonomy_stats'] = ott # fetch and render Markdown release notes as HTML import requests from gluon.contrib.markdown.markdown2 import markdown fetch_url = 'https://raw.githubusercontent.com/OpenTreeOfLife/reference-taxonomy/master/doc/{v}.md'.format( v=taxo_version) try: version_notes_response = requests.get(url=fetch_url).text # N.B. We assume here that any hyperlinks have the usual Markdown braces! version_notes_html = markdown(version_notes_response).encode('utf-8') # scrub HTML output with bleach version_notes_html = ot_cleaner.clean(version_notes_html) except: version_notes_html = None view_dict['taxonomy_version_notes'] = version_notes_html # List all synthesis releases that used this OTT version synth = json.loads(fetch_local_synthesis_stats() or '{}') related_releases = [] for date in synth: synth_ott_version = synth[date]['OTT_version'] if synth_ott_version: # If a draft was provided (eg, "ott2.9draft8"), truncate this # to specify the main version (in this case, "ott2.9") synth_ott_version = synth_ott_version.split('draft')[0] if synth_ott_version == taxo_version: related_releases.append(synth[date]['version']) view_dict['related_synth_releases'] = related_releases return view_dict
def synthesis_release(): view_dict = default_view_dict.copy() # Load each JSON document into a list or dict, so we can compile daily entries. # NB: For simplicity and uniformity, filter these to use only simple dates # with no time component! # EXAMPLE u'2015-01-16T23Z' ==> u'2015-01-16' raw = json.loads(fetch_local_synthesis_stats() or '{}') # Pre-sort its raw date strings, so we can discard all the but latest info # for each date (e.g. we might toss the morning stats but keep the evening). sorted_dates = sorted(raw.keys(), reverse=False) synth = {} for d in sorted_dates: raw_data = raw[d] simple_date = _force_to_simple_date_string(d) synth[simple_date] = raw_data # this should overwrite data from earlier in the day if len(synth.keys()) == 0: # report this error on the page view_dict['release_version'] = 'NO RELEASES FOUND' view_dict['synthesis_stats'] = synth return view_dict # Get date or version from URL, or bounce to the latest release by default if len(request.args) == 0: release_date = sorted(synth.keys(), reverse=False)[-1] release_version = synth[release_date].get('version') redirect( URL('opentree', 'about', 'synthesis_release', vars={}, args=[release_version])) synth_release_version = request.args[0] view_dict['release_version'] = synth_release_version view_dict['synthesis_stats'] = synth # fetch and render Markdown release notes as HTML import requests from gluon.contrib.markdown.markdown2 import markdown fetch_url = 'https://raw.githubusercontent.com/OpenTreeOfLife/germinator/master/doc/ot-synthesis-{v}.md'.format( v=synth_release_version) try: version_notes_response = requests.get(url=fetch_url).text # N.B. We assume here that any hyperlinks have the usual Markdown braces! version_notes_html = markdown(version_notes_response).encode('utf-8') # scrub HTML output with bleach version_notes_html = ot_cleaner.clean(version_notes_html) except: version_notes_html = None view_dict['synthesis_release_notes'] = version_notes_html return view_dict
def afficher_recette(): recette = db(db.recette.id == request.args[0]).select() categories = db((db.categorie.id == db.recette_has_categorie.categorie) & (db.recette.id == db.recette_has_categorie.recette) & (db.recette.id == request.args[0])).select(db.categorie.name,db.categorie.id) ingredients = db((db.recette.id==db.recette_has_ingredient.recette) & (db.ingredient.id==db.recette_has_ingredient.ingredient) & (db.recette.id == request.args[0])).select(db.ingredient.name) recette[0].note = 4 recette[0].etapes = XML(markdown(recette[0].etapes)) return dict( recette = recette, categories = categories, ingredients = ingredients)
def taxonomy_version(): view_dict = default_view_dict.copy() # load taxonomy-version history and basic stats ott = json.loads(fetch_local_ott_stats() or '[]') if len(ott) == 0: # report this error on the page view_dict['taxonomy_version'] = 'NO VERSIONS FOUND' view_dict['taxonomy_stats'] = ott return view_dict # Get OTT version from URL, or bounce to the latest version by default if len(request.args) == 0: # safer to sort by date-strings [yyyy-mm-dd] than version strings sorted_ott = sorted(ott, key=lambda v: v['date'], reverse=False) taxonomy_version = sorted_ott[-1].get('version') redirect(URL('opentree', 'about', 'taxonomy_version', vars={}, args=[taxonomy_version])) taxo_version = request.args[0] view_dict['taxonomy_version'] = taxo_version view_dict['taxonomy_stats'] = ott # fetch and render Markdown release notes as HTML import requests from gluon.contrib.markdown.markdown2 import markdown fetch_url = 'https://raw.githubusercontent.com/OpenTreeOfLife/reference-taxonomy/master/doc/{v}.md'.format(v=taxo_version) try: version_notes_response = requests.get(url=fetch_url).text # N.B. We assume here that any hyperlinks have the usual Markdown braces! version_notes_html = markdown(version_notes_response).encode('utf-8') # scrub HTML output with bleach version_notes_html = ot_cleaner.clean(version_notes_html) except: version_notes_html = None view_dict['taxonomy_version_notes'] = version_notes_html # List all synthesis releases that used this OTT version synth = json.loads(fetch_local_synthesis_stats() or '{}') related_releases = [] for date in synth: synth_ott_version = synth[date]['OTT_version'] if synth_ott_version: # If a draft was provided (eg, "ott2.9draft8"), truncate this # to specify the main version (in this case, "ott2.9") synth_ott_version = synth_ott_version.split('draft')[0] if synth_ott_version == taxo_version: related_releases.append(synth[date]['version']) view_dict['related_synth_releases'] = related_releases return view_dict
def synthesis_release(): view_dict = default_view_dict.copy() # Load each JSON document into a list or dict, so we can compile daily entries. # NB: For simplicity and uniformity, filter these to use only simple dates # with no time component! # EXAMPLE u'2015-01-16T23Z' ==> u'2015-01-16' raw = json.loads(fetch_local_synthesis_stats() or '{}') # Pre-sort its raw date strings, so we can discard all the but latest info # for each date (e.g. we might toss the morning stats but keep the evening). sorted_dates = sorted(raw.keys(), reverse=False) synth = {} for d in sorted_dates: raw_data = raw[d] simple_date = _force_to_simple_date_string(d) synth[ simple_date ] = raw_data # this should overwrite data from earlier in the day if len(synth.keys()) == 0: # report this error on the page view_dict['release_version'] = 'NO RELEASES FOUND' view_dict['synthesis_stats'] = synth return view_dict # Get date or version from URL, or bounce to the latest release by default if len(request.args) == 0: release_date = sorted(synth.keys(), reverse=False)[-1] release_version = synth[release_date].get('version') redirect(URL('opentree', 'about', 'synthesis_release', vars={}, args=[release_version])) synth_release_version = request.args[0] view_dict['release_version'] = synth_release_version view_dict['synthesis_stats'] = synth # fetch and render Markdown release notes as HTML import requests from gluon.contrib.markdown.markdown2 import markdown fetch_url = 'https://raw.githubusercontent.com/OpenTreeOfLife/germinator/master/doc/ot-synthesis-{v}.md'.format(v=synth_release_version) try: version_notes_response = requests.get(url=fetch_url).text # N.B. We assume here that any hyperlinks have the usual Markdown braces! version_notes_html = markdown(version_notes_response).encode('utf-8') # scrub HTML output with bleach version_notes_html = ot_cleaner.clean(version_notes_html) except: version_notes_html = None view_dict['synthesis_release_notes'] = version_notes_html return view_dict
def list(): """ Lists all tasks with their description embedded and buttons to show the details, open the source file, create a CodeBlocks project or to upload a source file as solution. /task/list -> lists all tasks """ task_links_list = [] script_parts_list = '' for task in db(db.Tasks.id > 0).select(): # build panel header for each task including the button group displayed # on the right side current_description_id = 'description-{}'.format(task.id) current_title_id = 'tasktitle-{}'.format(task.id) current_title_text = H3(T('Task: {}').format(task.Name), _class='panel-title pull-left') view_current_task_button = A(T('View task'), _href=URL(c='task', f='view', args=(task.id,)), _class='btn btn-primary', _id='view_button-{}'.format(task.id)) upload_entry_for_task_button = A(T('Submit entry'), _href=URL(c='entry', f='add', args=(task.id,)), _class='btn btn-primary', _id='submit_button-{}'.format(task.id)) open_empty_file_button = A(T('Open empty file'), _href=URL(c='default', f='codeeditor', args=(task.id,)), _class='btn btn-primary', _id='open_button-{}'.format(task.id)) open_empty_project_button = A(T('Open empty CodeBlocks project'), _href=URL(c='task', f='download_project', args=(task.id,)), _class='btn btn-primary', _id='open_project_button-{}'.format(task.id)) button_group = DIV(view_current_task_button, open_empty_project_button, open_empty_file_button, upload_entry_for_task_button, _class='btn-group pull-right') task_link = DIV(DIV(current_title_text), DIV(button_group), _id=current_title_id, _class='panel-heading clearfix') task_description_path = os.path.join(task.DataPath, 'description.md') # build panel body containing task description with open(task_description_path, 'r') as task_description: task_description = DIV(XML(markdown2.markdown(task_description.read())), _id=current_description_id, _class='panel-body') task_links_list.append(DIV(task_link, task_description, _class='panel panel-default')) # deactivate task descriptions by default and toggle them by clicking script_parts_list += '$("#{descID}").hide();'.format(descID=current_description_id) script_parts_list += '$("#{titleID}").click(function(){{ $("#{descID}").slideToggle(); }});'.format(titleID=current_title_id, descID=current_description_id) task_table = DIV(task_links_list, _id='task_table') script = SCRIPT(""" function onclickTask(id) {{ alert(id); //$("#upload_Task").empty(); //ajax('', ['Teacher'], ':eval'); }}; {moreScript} """.format(moreScript=script_parts_list)) return dict(task_table=task_table, script=script)
def view(): """ Shows all tasks if no argument is given or details of a specific task. /task/view/[task id] -> view detailed information about a specific task """ if request.args: # check if argument is valid integer number try: task_to_be_shown = int(request.args[0]) except ValueError: raise HTTP(404, T('Invalid argument given.')) # check whether argument is a valid task id row = db(db.Tasks.id == task_to_be_shown) if not row: raise HTTP(404, T('Invalid task id given.')) task_data_path = row.select().first()['DataPath'] task_description_path = os.path.join(task_data_path, 'description.md') with open(task_description_path, 'r') as task_description: description = XML(markdown2.markdown(task_description.read())) back_button = A(T('Back'), _href=URL(f='list'), _class='btn btn-primary', _id='back_button') submit_entry_button = A(T('Submit entry'), _href=URL(c='entry',f='add', args=(task_to_be_shown)), _class='btn btn-primary', _id='submit_entry_button') open_empty_file_button = A(T('Open empty file'), _href=URL(c='default', f='codeeditor', args=(task_to_be_shown,)), _class='btn btn-primary', _id='open_new_button') open_empty_project_button = A(T('Open empty CodeBlocks project'), _href=URL(c='task', f='download_project', args=(task_to_be_shown,)), _class='btn btn-primary', _id='open_project_button-{}'.format(task_to_be_shown)) statistics = [] statistics.append(DIV(A(T('Submitted entries: '), SPAN('{}'.format(count_entries(task_to_be_shown)), _class='badge'), _id='submitted_entries_badge', _href=URL(c='entry',f='list', args=(task_to_be_shown))), _class='btn btn-primary')) statistics.append(DIV(T('Executed builds: '), SPAN('{}'.format(count_executed_builds(task_to_be_shown)), _class='badge'), _class='btn btn-primary')) statistics.append(DIV(T('Successful builds: '), SPAN('{}'.format(count_successful_builds(task_to_be_shown)), _class='badge'), _class='btn btn-primary')) statistics = DIV(*statistics) return dict(description=description, back_button=back_button, statistics=statistics, submit_entry_button=submit_entry_button, open_empty_file_button=open_empty_file_button, open_empty_project_button=open_empty_project_button, task_name=row.select().first()['Name']) else: raise HTTP(404, T('No task number given.'))
def node(comment): if not comment.deleted: #return T('COMMENT') return LI( DIV(##T('posted by %(first_name)s %(last_name)s',comment.created_by), # not sure why this doesn't work... db.auth record is not a mapping!? DIV( XML(markdown(comment.body or ''), sanitize=True),_class='body'), DIV(T('%s ',comment.created_by.first_name),T('%s',comment.created_by.last_name), # SPAN(' [local expertise]',_class='badge') if comment.claimed_expertise else '', SPAN(' ',comment.feedback_type,' ',_class='badge') if comment.feedback_type else '', SPAN(' ',comment.intended_scope,' ',_class='badge') if comment.intended_scope else '', T(' - %s',prettydate(comment.created_on,T)), SPAN( A(T('hide replies'),_class='toggle',_href='#'), SPAN(' | ') if auth.user_id else '', A(T('reply'),_class='reply',_href='#') if auth.user_id else '', SPAN(' | ') if comment.created_by == auth.user_id else '', A(T('delete'),_class='delete',_href='#') if comment.created_by == auth.user_id else '', _class='controls'), _class='byline'), _id='r%s' % comment.id), DIV(_class='reply'), # child messages (toggle hides/shows these) SUL(*[node(comment) for comment in thread.get(comment.id,[])]) ) elif comment.id in thread: return LI( DIV(SPAN(T('[deleted comment]'),_class='body'),' ', SPAN( A(T('hide replies'),_class='toggle',_href='#'), _class='controls'), _class='deleted'), DIV(_class='reply'), SUL(*[node(comment) for comment in thread.get(comment.id,[])])) else: return None
def about_page(): import os from gluon.contrib.markdown import markdown2 md_dir = '/opt/ddj/book/markdown' page = {} with open(os.path.join(md_dir, 'about.md')) as fd: page['about'] = markdown2.markdown(fd.read()) with open(os.path.join(md_dir, 'apology.md')) as fd: page['apology'] = markdown2.markdown(fd.read()) with open(os.path.join(md_dir, 'appresources.md')) as fd: page['resources'] = markdown2.markdown(fd.read()) with open(os.path.join(md_dir, 'copyright.md')) as fd: page['copyright'] = markdown2.markdown(fd.read()) with open(os.path.join(md_dir, 'references.md')) as fd: page['references'] = markdown2.markdown(fd.read()) with open(os.path.join(md_dir, 'contact.md')) as fd: page['contact'] = markdown2.markdown(fd.read()) return page
def node(comment): ##print("building node for comment id={0}...".format(comment.get('number', comment['id']))) # preload its comments (a separate API call) child_comments = [ ] if comment.get('comments') and comment.get('comments') > 0: get_children_url = comment['comments_url'] resp = requests.get( get_children_url, headers=GH_GET_HEADERS, timeout=10) # N.B. Timeout is in seconds, and watches for *any* new data within that time (vs. whole response) try: resp.raise_for_status() try: child_comments = resp.json() except: child_comments = resp.json except: # WE need logging in the web app! try: import sys sys.stderr.write('Error: got a {c} from {u}\n'.format(c=resp.status_code, u=get_children_url)) except: pass # well that sucks, we failed to even write to stderr metadata = parse_comment_metadata(comment['body']) ##print(metadata) # Examine the comment metadata (if any) to get the best display name # and URL for its author. Guests should appear here as the name and # email address they entered when creating a comment, rather than the # GitHub app (bot). # # Default values are what we can fetch from the issues API author_display_name = comment['user']['login'] author_link = comment['user']['html_url'] # Now let's try for something more friendly... if metadata: meta_author_info = metadata.get('Author', None) if meta_author_info: # Try to parse this fron a Markdown hyperlink. Typical values include: # u'opentreeapi' # u'11' # u'[Jim Allman](https://github.com/jimallman)' # u'[John Smith](mailto:[email protected])' regex = re.compile(r'\[(.*)\]\((.*)\)') markdown_fields = regex.findall(meta_author_info) if len(markdown_fields) > 0: # look for parts of a markdown link author_display_name, author_link = markdown_fields[0] else: # it's not a markdown link, just a bare name or numeric userid if meta_author_info.isdigit(): # ignore ugly userid (login is better) pass else: author_display_name = meta_author_info # Is this node for an issue (thread starter) or a comment (reply)? issue_node = 'number' in comment # Is the current user logged in? If so, what is their GitHub ID (login)? current_user_id = auth.user and auth.user.github_login or None # Cook up some reasonably strong regular expressions to detect bare # URLs and wrap them in hyperlinks. Adapted from # http://stackoverflow.com/questions/1071191/detect-urls-in-a-string-and-wrap-with-a-href-tag link_regex = re.compile( r''' (?x)( # verbose identify URLs within text (http|https) # make sure we find a resource type :// # ...needs to be followed by colon-slash-slash (\w+[:.]?){2,} # at least two domain groups, e.g. (gnosis.)(cx) (/?| # could be just the domain name (maybe w/ slash) [^ \n\r"]+ # or stuff then space, newline, tab, quote [\w/]) # resource name ends in alphanumeric or slash (?=([\s\.,>)'"\]]|$)) # assert: followed by white or clause ending OR end of line ) # end of match group ''') # link_replace = r'<a href="\1" />\1</a>' # let's try this do-nothing version link_replace = r'\1' # NOTE the funky constructor required to use this below # Define a consistent cleaner to sanitize user input. We need a few # elements that are common in our markdown but missing from the Bleach # whitelist. # N.B. HTML comments are stripped by default. Non-allowed tags will appear # "naked" in output, so we can identify any bad actors. common_feedback_tags = [u'p', u'br', u'h1', u'h2', u'h3', u'h4', u'h5', u'h6', ] ot_markdown_tags = list(set( bleach.sanitizer.ALLOWED_TAGS + common_feedback_tags)) ot_cleaner = Cleaner(tags=ot_markdown_tags) try: # TODO: if not comment.deleted: # N.B. some missing information (e.g. supporting URL) will appear here as a string like "None" supporting_reference_url = metadata.get('Supporting reference', None) has_supporting_reference_url = supporting_reference_url and (supporting_reference_url != u'None') # Prepare a sanitized rendering of this user-submitted markup rendered_comment_markdown = markdown( get_visible_comment_body(comment['body'] or ''), extras={'link-patterns':None}, link_patterns=[(link_regex, link_replace)]).encode('utf-8') safe_comment_markup = XML( ot_cleaner.clean(rendered_comment_markdown), sanitize=False) # gluon's sanitize will break on Unicode! markup = LI( DIV(##T('posted by %(first_name)s %(last_name)s',comment.created_by), # not sure why this doesn't work... db.auth record is not a mapping!? ('title' in comment) and DIV( comment['title'], A(T('on GitHub'), _href=comment['html_url'], _target='_blank'), _class='topic-title') or '', DIV( safe_comment_markup, _class=(issue_node and 'body issue-body' or 'body comment-body')), DIV( A(T('Supporting reference (opens in a new window)'), _href=supporting_reference_url, _target='_blank'), _class='body issue-supporting-reference' ) if has_supporting_reference_url else '', DIV( A(T(author_display_name), _href=author_link, _target='_blank'), # SPAN(' [local expertise]',_class='badge') if comment.claimed_expertise else '', SPAN(' ',metadata.get('Feedback type'),' ',_class='badge') if metadata.get('Feedback type') else '', T(' - %s',prettydate(utc_to_local(datetime.strptime(comment['created_at'], GH_DATETIME_FORMAT)),T)), SPAN( issue_node and A(T(child_comments and 'Hide comments' or 'Show/add comments'),_class='toggle',_href='#') or '', issue_node and comment['user']['login'] == current_user_id and SPAN(' | ') or '', A(T('Delete'),_class='delete',_href='#') if comment['user']['login'] == current_user_id else '', _class='controls'), _class='byline'), _id='r%s' % comment.get('number', comment['id']), _class='msg-wrapper'), # child messages (toggle hides/shows these) issue_node and SUL(*[node(comment) for comment in child_comments], _style=("" if child_comments else "display: none;")) or '', issue_node and DIV(_class='reply', _style=("" if child_comments else "display: none;")) or '', _class=(issue_node and 'issue' or 'comment')) return markup except: import sys print "Unexpected error:", sys.exc_info()[0] raise
def renderMarkdown(text): if text: text = markdown(text) return text
def MD(text): """ """ return markdown(text).encode('utf8')
def node(comment): ##print("building node for comment id={0}...".format(comment.get('number', comment['id']))) # preload its comments (a separate API call) child_comments = [ ] if comment.get('comments') and comment.get('comments') > 0: get_children_url = comment['comments_url'] resp = requests.get( get_children_url, headers=GH_GET_HEADERS) try: resp.raise_for_status() try: child_comments = resp.json() except: child_comments = resp.json print("found {0} child comments".format(len(child_comments))) except: # WE need logging in the web app! try: import sys sys.stderr.write('Error: got a {c} from {u}\n'.format(c=resp.status_code, u=get_children_url)) except: pass # well that sucks, we failed to even write to stderr metadata = parse_comment_metadata(comment['body']) ##print(metadata) # Examine the comment metadata (if any) to get the best display name # and URL for its author. Guests should appear here as the name and # email address they entered when creating a comment, rather than the # 'opentreeapi' bot user. # # Default values are what we can fetch from the issues API author_display_name = comment['user']['login'] author_link = comment['user']['html_url'] # Now let's try for something more friendly... if metadata: meta_author_info = metadata.get('Author', None) if meta_author_info: # Try to parse this fron a Markdown hyperlink. Typical values include: # u'opentreeapi' # u'11' # u'[Jim Allman](https://github.com/jimallman)' # u'[John Smith](mailto:[email protected])' regex = re.compile(r'\[(.*)\]\((.*)\)') markdown_fields = regex.findall(meta_author_info) if len(markdown_fields) > 0: # look for parts of a markdown link author_display_name, author_link = markdown_fields[0] else: # it's not a markdown link, just a bare name or numeric userid if meta_author_info.isdigit(): # ignore ugly userid (login is better) pass else: author_display_name = meta_author_info # Is this node for an issue (thread starter) or a comment (reply)? issue_node = 'number' in comment # Is the current user logged in? If so, what is their GitHub ID (login)? current_user_id = auth.user and auth.user.github_login or None # Cook up some reasonably strong regular expressions to detect bare # URLs and wrap them in hyperlinks. Adapted from # http://stackoverflow.com/questions/1071191/detect-urls-in-a-string-and-wrap-with-a-href-tag link_regex = re.compile( r''' (?x)( # verbose identify URLs within text (http|https) # make sure we find a resource type :// # ...needs to be followed by colon-slash-slash (\w+[:.]?){2,} # at least two domain groups, e.g. (gnosis.)(cx) (/?| # could be just the domain name (maybe w/ slash) [^ \n\r"]+ # or stuff then space, newline, tab, quote [\w/]) # resource name ends in alphanumeric or slash (?=([\s\.,>)'"\]]|$)) # assert: followed by white or clause ending OR end of line ) # end of match group ''') # link_replace = r'<a href="\1" />\1</a>' # let's try this do-nothing version link_replace = r'\1' # NOTE the funky constructor required to use this below try: # TODO: if not comment.deleted: markup = LI( DIV(##T('posted by %(first_name)s %(last_name)s',comment.created_by), # not sure why this doesn't work... db.auth record is not a mapping!? ('title' in comment) and DIV( comment['title'], A(T('on GitHub'), _href=comment['html_url'], _target='_blank'), _class='topic-title') or '', DIV( XML(markdown(get_visible_comment_body(comment['body'] or ''), extras={'link-patterns':None}, link_patterns=[(link_regex, link_replace)]).encode('utf-8'), sanitize=False),_class=(issue_node and 'body issue-body' or 'body comment-body')), DIV( A(T(author_display_name), _href=author_link, _target='_blank'), # SPAN(' [local expertise]',_class='badge') if comment.claimed_expertise else '', SPAN(' ',metadata.get('Feedback type'),' ',_class='badge') if metadata.get('Feedback type') else '', SPAN(' ',metadata.get('Intended scope'),' ',_class='badge') if metadata.get('Intended scope') else '', T(' - %s',prettydate(utc_to_local(datetime.strptime(comment['created_at'], GH_DATETIME_FORMAT)),T)), SPAN( issue_node and A(T(child_comments and 'Hide comments' or 'Show/add comments'),_class='toggle',_href='#') or '', issue_node and comment['user']['login'] == current_user_id and SPAN(' | ') or '', A(T('Delete'),_class='delete',_href='#') if comment['user']['login'] == current_user_id else '', _class='controls'), _class='byline'), _id='r%s' % comment.get('number', comment['id']), _class='msg-wrapper'), # child messages (toggle hides/shows these) issue_node and SUL(*[node(comment) for comment in child_comments], _style=("" if child_comments else "display: none;")) or '', issue_node and DIV(_class='reply', _style=("" if child_comments else "display: none;")) or '', _class=(issue_node and 'issue' or 'comment')) return markup except: import sys print "Unexpected error:", sys.exc_info()[0] raise
def codeeditor(): """ Shows a editor to view source files including their compiler errors and unit test results and to change source files directly in the browser. If not entry id is given the default solution.c file for the given task is shown. Otherwise the entry file is opened. /default/codeeditor/[task id]/[entry id] -> open an uploaded entry for a task in the code editor """ # check if given arguments are valid if not request.args: raise HTTP(404, T('No task and entry id given!')) if len(request.args) > 2: raise HTTP(404, T('Too much arguments given!')) # check if argument is valid task number try: task_for_which_to_open_entry = int(request.args[0]) except ValueError: raise HTTP(404, T('Invalid task id given.')) # check if entry id was given report_for_entry = '' if len(request.args) == 2: # get file path from entry try: entry_to_be_opened = int(request.args[1]) except ValueError: raise HTTP(404, T('Invalid entry id given.')) row = db(db.Entries.id == entry_to_be_opened).select() if not row: raise HTTP(404, T('Invalid entry id given.')) code_file_path = row.first()['OnDiskPath'] # get report for build of this entry row = db(db.Builds.Task == task_for_which_to_open_entry and db.Builds.Entry == entry_to_be_opened).select() if row: if row.first()['Finished']: report_for_entry = row.first()['Report'] else: # get file path from default file of task entry_to_be_opened = 0 row = db(db.Tasks.id == task_for_which_to_open_entry).select() if not row: raise HTTP(404, T('Invalid task id given.')) task_data_path = row.first()['DataPath'] # TODO Get code file name from tasks config.json file. code_file_path = os.path.join(task_data_path, 'src', 'solution.c') # open file and get content with open(code_file_path, 'r') as code_file: code = code_file.read() # prepare java script code for displaying the Ace editor (http://ace.c9.io/) js_on_submit_click = u""" function on_submit() {{ // send edited program to server as new entry var editor = ace.edit("editor"); $.ajax({{ type: "POST", url: "{upload_url}", dataType: "application/json", data: {{"filecontent": editor.getValue(), "requestFromCodeEditor": 1}}, complete: function(data) {{ obj = JSON.parse(data.responseText); var entry_id = obj.new_id; build(entry_id) }} }}); }}; var intervalID = 0; function build(entry_id) {{ var buildNumber = 0; // build newest entry for task $.get("{build_url}/" + entry_id, "", function(data) {{ // call server to build newest entry buildNumber = data.build_id; }}); // wait for build status and redirect to editor for new entry intervalID = setInterval(function() {{ reload(entry_id, buildNumber) }}, 2000); }}; function reload(entry_id, buildNumber) {{ $.get("{reload_url}/" + buildNumber, function(data) {{ if (data.test_results != ""){{ // clear timer and redirect clearInterval(intervalID); window.location.replace("{editor_url}/" + entry_id); }}; }}); }}; """.format(upload_url=URL(r=request, c='entry', f='add.json', args=(task_for_which_to_open_entry, )), build_url=URL(r=request, c='entry', f='build.json', args=(task_for_which_to_open_entry, )), reload_url=URL(r=request, c='entry', f='build_status.json'), editor_url=URL(r=request, c='default', f='codeeditor', args=(task_for_which_to_open_entry, ))) editor_code = u""" {on_submit} // call function on click on submit button $("#submit_button").bind('click', function () {{ on_submit() }} ); // setup Ace editor var editor = ace.edit("editor"); editor.setTheme("ace/theme/monokai"); editor.getSession().setMode("ace/mode/c_cpp"); editor.session.setOption("useWorker", false); var Range = ace.require('ace/range').Range; // add markers for warnings and errors """.format(on_submit=js_on_submit_click)#'alert("File saved!");' editor = DIV(code, _id='editor') # prepare javascript code for warnings and errors marker_js_code = '' if report_for_entry: report_data = json.loads(report_for_entry, encoding='utf-8') marker_js_code += build_annotations_for_errors(report_data) # add javascript blobs to page js1 = SCRIPT(_src=URL('static', 'js/src-noconflict/ace.js'), _type='text/javascript', _charset='utf-8') # TODO Fix problem with unicode characters in error descriptions! js2 = SCRIPT(u''.join([editor_code, marker_js_code]).encode('ascii', 'ignore'), _type='text/javascript', _charset='utf-8') submit_button = SPAN(INPUT(_type='button', _value=T('Save changes...'), _class='btn btn-primary', _id='submit_button')) # add test results if report_for_entry: test_results = build_test_results(report_data) else: test_results = '' if entry_to_be_opened: build_entry_link = A(T('Build entry'), _class='btn btn-primary', _href=URL(c='entry', f='build', args=(task_for_which_to_open_entry, entry_to_be_opened))) test_results = DIV(DIV(T('No unit tests results found!')), build_entry_link) # add task description task_from_db = db(db.Tasks.id == task_for_which_to_open_entry).select().first() task_description_path = os.path.join(task_from_db.DataPath, 'description.md') with open(task_description_path, 'r') as task_description_file: task_description = XML(markdown2.markdown(task_description_file.read())) return locals()
Field('admin_pass', required=True)) db.define_table('ray_category', Field('name', required=True), Field('corder', 'integer', required=True), Field('is_public', default=1, required=True)) db.define_table('ray_blog', Field('title', required=True), Field('text', 'text', required=True), Field('category_id', db.ray_category, required=True), Field('created_date', 'datetime', required=True, default=now, writable=False), Field('updated_date', 'datetime', required=True, default=now, writable=False), Field('count', 'integer',writable=False,readable=False,default=0), Field('is_markdown', default=False, required=True), Field.Virtual('text_view', lambda row: row.ray_blog.text if row.ray_blog.is_markdown!='1' else markdown(row.ray_blog.text)), #Field.Virtual('preview', lambda row: preview_html(row.ray_blog.text_view)) ) db.ray_blog.category_id.requires=IS_IN_DB(db, 'ray_category.id', '%(name)s') db.define_table('ray_comment', Field('title', required=True), Field('text', required=True), Field('name', required=True), Field('email', required=True, requires = IS_EMAIL(error_message=T('invalid email!'))), Field('created_date', 'datetime', readable=False, writable=False, required=True, default=now), Field('blog_id', db.ray_blog, required=True,writable=False,readable=False), Field('category_id', db.ray_category, required=True,writable=False,readable=False), Field('comment_id', 'integer', writable=False,readable=False))
def node(comment): ##print("building node for comment id={0}...".format(comment.get('number', comment['id']))) # preload its comments (a separate API call) child_comments = [ ] if comment.get('comments') and comment.get('comments') > 0: get_children_url = comment['comments_url'] resp = requests.get( get_children_url, headers=GH_GET_HEADERS) resp.raise_for_status() try: child_comments = resp.json() except: child_comments = resp.json print("found {0} child comments".format(len(child_comments))) metadata = parse_comment_metadata(comment['body']) ##print(metadata) # Examine the comment metadata (if any) to get the best display name # and URL for its author. Guests should appear here as the name and # email address they entered when creating a comment, rather than the # 'opentreeapi' bot user. # # Default values are what we can fetch from the issues API author_display_name = comment['user']['login'] author_link = comment['user']['html_url'] # Now let's try for something more friendly... if metadata: meta_author_info = metadata.get('Author', None) if meta_author_info: # Try to parse this fron a Markdown hyperlink. Typical values include: # u'opentreeapi' # u'11' # u'[Jim Allman](https://github.com/jimallman)' # u'[John Smith](mailto:[email protected])' regex = re.compile(r'\[(.*)\]\((.*)\)') markdown_fields = regex.findall(meta_author_info) if len(markdown_fields) > 0: # look for parts of a markdown link author_display_name, author_link = markdown_fields[0] else: # it's not a markdown link, just a bare name or numeric userid if meta_author_info.isdigit(): # ignore ugly userid (login is better) pass else: author_display_name = meta_author_info # Is this node for an issue (thread starter) or a comment (reply)? issue_node = 'number' in comment # Is the current user logged in? If so, what is their GitHub ID (login)? current_user_id = auth.user and auth.user.github_login or None # Cook up some reasonably strong regular expressions to detect bare # URLs and wrap them in hyperlinks. Adapted from # http://stackoverflow.com/questions/1071191/detect-urls-in-a-string-and-wrap-with-a-href-tag link_regex = re.compile( r''' (?x)( # verbose identify URLs within text (http|https) # make sure we find a resource type :// # ...needs to be followed by colon-slash-slash (\w+[:.]?){2,} # at least two domain groups, e.g. (gnosis.)(cx) (/?| # could be just the domain name (maybe w/ slash) [^ \n\r"]+ # or stuff then space, newline, tab, quote [\w/]) # resource name ends in alphanumeric or slash (?=([\s\.,>)'"\]]|$)) # assert: followed by white or clause ending OR end of line ) # end of match group ''') # link_replace = r'<a href="\1" />\1</a>' # let's try this do-nothing version link_replace = r'\1' # NOTE the funky constructor required to use this below try: # TODO: if not comment.deleted: markup = LI( DIV(##T('posted by %(first_name)s %(last_name)s',comment.created_by), # not sure why this doesn't work... db.auth record is not a mapping!? ('title' in comment) and DIV( comment['title'], A(T('on GitHub'), _href=comment['html_url'], _target='_blank'), _class='topic-title') or '', DIV( XML(markdown(get_visible_comment_body(comment['body'] or ''), extras={'link-patterns':None}, link_patterns=[(link_regex, link_replace)]).encode('utf-8'), sanitize=False),_class=(issue_node and 'body issue-body' or 'body comment-body')), DIV( A(T(author_display_name), _href=author_link, _target='_blank'), # SPAN(' [local expertise]',_class='badge') if comment.claimed_expertise else '', SPAN(' ',metadata.get('Feedback type'),' ',_class='badge') if metadata.get('Feedback type') else '', SPAN(' ',metadata.get('Intended scope'),' ',_class='badge') if metadata.get('Intended scope') else '', T(' - %s',prettydate(utc_to_local(datetime.strptime(comment['created_at'], GH_DATETIME_FORMAT)),T)), SPAN( issue_node and A(T(child_comments and 'Hide comments' or 'Show/add comments'),_class='toggle',_href='#') or '', issue_node and comment['user']['login'] == current_user_id and SPAN(' | ') or '', A(T('Delete'),_class='delete',_href='#') if comment['user']['login'] == current_user_id else '', _class='controls'), _class='byline'), _id='r%s' % comment.get('number', comment['id']), _class='msg-wrapper'), # child messages (toggle hides/shows these) issue_node and SUL(*[node(comment) for comment in child_comments], _style=("" if child_comments else "display: none;")) or '', issue_node and DIV(_class='reply', _style=("" if child_comments else "display: none;")) or '', _class=(issue_node and 'issue' or 'comment')) return markup except: import sys print "Unexpected error:", sys.exc_info()[0] raise
def readme(): from os.path import join as pathjoin with open(pathjoin(request.folder, 'private', 'README.md')) as f: data = f.read() return dict(data=markdown2.markdown(data))