def test_class_sublogger_no_context(self): profiler = profiling.Profiler('Class.method') profiler.start() profiler.stop() self.assertEqual(log.handlers[0].get_log_events()[0].name, '%s.%s' % (profiling.__name__, 'Class.method'))
def test_multiple_logging_context(self): with profiling.Profiler('profiler1'): pass with profiling.Profiler('profiler2'): pass self.assertEqual(len(log.handlers[0].get_log_events()), 2)
def test_no_sublogger_no_context(self): profiler = profiling.Profiler('testing sublogger') profiler.start() profiler.stop() self.assertEqual(log.handlers[0].get_log_events()[0].name, profiling.__name__)
def renderDashboard(req, db, user): if user.isAnonymous(): default_show = "open" else: default_show = user.getPreference(db, "dashboard.defaultGroups") show = req.getParameter("show", default_show) if user.isAnonymous(): def possible(group): return group in ("open", "closed") else: def possible(group): return True showlist = filter(possible, show.split(",")) showset = set(showlist) if user.getPreference(db, "commit.diff.compactMode"): default_compact = "yes" else: default_compact = "no" repository_arg = req.getParameter("repository", None) repository = gitutils.Repository.fromParameter( db, repository_arg) if repository_arg else None compact = req.getParameter("compact", default_compact) == "yes" cursor = db.cursor() profiler = profiling.Profiler() document = htmlutils.Document(req) document.setTitle("Dashboard") html = document.html() head = html.head() body = html.body() def generateRight(target): def addLink(key, title=None): if not title: title = key if key not in showset: target.text("[") target.a(href="dashboard?show=%s" % ",".join(showlist + [key])).text("show %s" % title) target.text("]") if user.isAnonymous(): addLink("open", "open") addLink("closed") else: target.text("[") target.a(href="config?highlight=dashboard.defaultGroups").text( "configure defaults") target.text("]") addLink("owned") addLink("draft") addLink("active") addLink("watched") addLink("open", "other open") addLink("closed") page.utils.generateHeader(body, db, user, current_page="dashboard", generate_right=generateRight, profiler=profiler) document.addExternalStylesheet("resource/dashboard.css") document.addExternalScript("resource/dashboard.js") document.addInternalScript(user.getJS()) target = body.div("main") def flush(target): return document.render(stop=target, pretty=not compact) def includeReview(review_id): if repository: cursor = db.cursor() cursor.execute( "SELECT branches.repository FROM branches JOIN reviews ON (reviews.branch=branches.id) WHERE reviews.id=%s", (review_id, )) return cursor.fetchone()[0] == repository.id else: return True def sortedReviews(data): reviews = [] for review_id in sorted(data.keys()): reviews.append((review_id, data[review_id])) return reviews def isAccepted(review_ids): cursor.execute( """SELECT reviews.id, COUNT(reviewfiles.id)=0 AND COUNT(commentchains.id)=0 FROM reviews LEFT OUTER JOIN reviewfiles ON (reviewfiles.review=reviews.id AND reviewfiles.state='pending') LEFT OUTER JOIN commentchains ON (commentchains.review=reviews.id AND commentchains.type='issue' AND commentchains.state='open') WHERE reviews.id=ANY (%s) GROUP BY reviews.id""", (review_ids, )) return dict(cursor) def renderReviews(target, reviews, lines_and_comments=True, links=True): cursor.execute("SELECT id, name FROM branches WHERE id=ANY (%s)", (list(branch_id for _, (_, branch_id, _, _) in reviews), )) branch_names = dict(cursor) cursor.execute( "SELECT branches.id, repositories.name FROM branches LEFT JOIN repositories ON (repositories.id = branches.repository) WHERE branches.id=ANY (%s)", (list(branch_id for _, (_, branch_id, _, _) in reviews), )) repo_names = dict(cursor) for review_id, (summary, branch_id, lines, comments) in reviews: row = target.tr("review") row.td("name").text(branch_names[branch_id]) row.td("repo_name").text(repo_names[branch_id]) row.td("title").a(href="r/%d" % review_id).text(summary) if lines_and_comments: if lines: if links: row.td("lines").a( href="showcommit?review=%d&filter=pending" % review_id).text("%d lines" % (sum(lines))) else: row.td("lines").text("%d lines" % (sum(lines))) else: row.td("lines").text() if comments: if links: row.td("comments").a( href="showcomments?review=%s&filter=toread" % review_id).text( "%d comment%s" % (comments, "s" if comments > 1 else "")) else: row.td("comments").text( "%d comment%s" % (comments, "s" if comments > 1 else "")) else: row.td("comments").text() def hidden(what): new_show = ",".join(filter(lambda item: item != what, showlist)) if new_show: return "dashboard?show=%s" % new_show else: return "dashboard" profiler.check("generate: prologue") def renderOwned(): owned_accepted = [] owned_open = [] cursor.execute( """SELECT id, summary, branch FROM reviews JOIN reviewusers ON (review=id AND reviewusers.owner) WHERE state='open' AND uid=%s ORDER BY id DESC""", (user.id, )) owned = cursor.fetchall() profiler.check("query: owned") is_accepted = isAccepted(list(review_id for review_id, _, _ in owned)) for review_id, summary, branch_id in owned: if includeReview(review_id): if is_accepted[review_id]: owned_accepted.append( (review_id, (summary, branch_id, None, None))) else: owned_open.append( (review_id, (summary, branch_id, None, None))) profiler.check("processing: owned") if owned_accepted or owned_open: table = target.table("paleyellow reviews", id="owned", align="center", cellspacing=0) table.col(width="15%") table.col(width="15%") table.col(width="40%") table.col(width="15%") table.col(width="15%") header = table.tr().td("h1", colspan=4).h1() header.text("Owned By You") header.span("right").a(href=hidden("owned")).text("[hide]") if owned_accepted: table.tr(id="accepted").td("h2", colspan=4).h2().text("Accepted") renderReviews(table, owned_accepted) if owned_open: table.tr(id="open").td("h2", colspan=4).h2().text("Pending") renderReviews(table, owned_open) profiler.check("generate: owned") return True def renderDraft(): draft_changes = {} draft_comments = {} draft_both = {} cursor.execute( """SELECT reviews.id, reviews.summary, reviews.branch, SUM(reviewfiles.deleted), SUM(reviewfiles.inserted) FROM reviews JOIN reviewfiles ON (reviewfiles.review=reviews.id) JOIN reviewfilechanges ON (reviewfilechanges.file=reviewfiles.id) WHERE reviews.state='open' AND reviewfiles.state=reviewfilechanges.from_state AND reviewfilechanges.state='draft' AND reviewfilechanges.uid=%s GROUP BY reviews.id, reviews.summary, reviews.branch""", (user.id, )) profiler.check("query: draft lines") for review_id, summary, branch_id, deleted_count, inserted_count in cursor: if includeReview(review_id): draft_changes[review_id] = (summary, branch_id, (deleted_count, inserted_count), None) profiler.check("processing: draft lines") cursor.execute( """SELECT reviews.id, reviews.summary, reviews.branch, COUNT(comments.id) FROM reviews JOIN commentchains ON (commentchains.review=reviews.id) JOIN comments ON (comments.chain=commentchains.id) WHERE comments.state='draft' AND comments.uid=%s GROUP BY reviews.id, reviews.summary, reviews.branch""", [user.id]) profiler.check("query: draft comments") for review_id, summary, branch_id, comments_count in cursor: if includeReview(review_id): if draft_changes.has_key(review_id): draft_both[review_id] = (summary, branch_id, draft_changes[review_id][2], comments_count) del draft_changes[review_id] else: draft_comments[review_id] = (summary, branch_id, None, comments_count) profiler.check("processing: draft comments") if draft_both or draft_changes or draft_comments: table = target.table("paleyellow reviews", id="draft", align="center", cellspacing=0) table.col(width="15%") table.col(width="15%") table.col(width="40%") table.col(width="15%") table.col(width="15%") header = table.tr().td("h1", colspan=4).h1() header.text("Reviews With Unsubmitted Work") header.span("right").a(href=hidden("draft")).text("[hide]") if draft_both: table.tr(id="draft-changes-comments").td( "h2", colspan=4).h2().text("Draft Changes And Comments") renderReviews(table, sortedReviews(draft_both), links=False) if draft_changes: table.tr(id="draft-changes").td( "h2", colspan=4).h2().text("Draft Changes") renderReviews(table, sortedReviews(draft_changes), links=False) if draft_comments: table.tr(id="draft-comments").td( "h2", colspan=4).h2().text("Draft Comments") renderReviews(table, sortedReviews(draft_comments), links=False) profiler.check("generate: draft") return True active = {} def fetchActive(): if not active: with_changes = {} with_comments = {} with_both = {} cursor.execute( """SELECT reviews.id, reviews.summary, reviews.branch, SUM(reviewfiles.deleted), SUM(reviewfiles.inserted) FROM reviews JOIN reviewusers ON (reviewusers.review=reviews.id AND reviewusers.uid=%s) JOIN reviewfiles ON (reviewfiles.review=reviews.id) JOIN reviewuserfiles ON (reviewuserfiles.file=reviewfiles.id AND reviewuserfiles.uid=%s) WHERE reviews.state='open' AND reviewfiles.state='pending' GROUP BY reviews.id, reviews.summary, reviews.branch""", (user.id, user.id)) profiler.check("query: active lines") for review_id, summary, branch_id, deleted_count, inserted_count in cursor: if includeReview(review_id): with_changes[review_id] = (summary, branch_id, (deleted_count, inserted_count), None) profiler.check("processing: active lines") cursor.execute( """SELECT reviews.id, reviews.summary, reviews.branch, unread.count FROM (SELECT commentchains.review AS review, COUNT(commentstoread.comment) AS count FROM commentchains JOIN comments ON (comments.chain=commentchains.id) JOIN commentstoread ON (commentstoread.comment=comments.id AND commentstoread.uid=%s) GROUP BY commentchains.review) AS unread JOIN reviews ON (reviews.id=unread.review) WHERE reviews.state='open'""", (user.id, )) profiler.check("query: active comments") for review_id, summary, branch_id, comments_count in cursor: if includeReview(review_id): if with_changes.has_key(review_id): with_both[review_id] = (summary, branch_id, with_changes[review_id][2], comments_count) del with_changes[review_id] else: with_comments[review_id] = (summary, branch_id, None, comments_count) profiler.check("processing: active comments") active["changes"] = with_changes active["comments"] = with_comments active["both"] = with_both def renderActive(): fetchActive() if active["both"] or active["changes"] or active["comments"]: table = target.table("paleyellow reviews", id="active", align="center", cellspacing=0) table.col(width="15%") table.col(width="15%") table.col(width="40%") table.col(width="15%") table.col(width="15%") header = table.tr().td("h1", colspan=4).h1() header.text("Active Reviews") header.span("right").a(href=hidden("active")).text("[hide]") if active["both"]: review_ids = ",".join(map(str, active["both"].keys())) h2 = table.tr(id="active-changes-comments").td( "h2", colspan=4).h2().text("Has Changes And Comments") h2.a(href="javascript:void(0);", onclick="markChainsAsRead([%s]);" % review_ids).text("[mark all as read]") renderReviews(table, sortedReviews(active["both"])) if active["changes"]: table.tr(id="active-changes").td( "h2", colspan=4).h2().text("Has Changes") renderReviews(table, sortedReviews(active["changes"])) if active["comments"]: review_ids = ",".join(map(str, active["comments"].keys())) h2 = table.tr(id="active-comments").td( "h2", colspan=4).h2().text("Has Comments") h2.a(href="javascript:void(0);", onclick="markChainsAsRead([%s]);" % review_ids).text("[mark all as read]") renderReviews(table, sortedReviews(active["comments"])) profiler.check("generate: active") return True other = {} def fetchWatchedAndClosed(): if not other: if "watched" not in showset: state_filter = " WHERE reviews.state='closed'" elif "closed" not in showset: state_filter = " WHERE reviews.state='open'" else: state_filter = "" profiler.check("query: watched/closed") watched = {} owned_closed = {} other_closed = {} if "watched" in showset: fetchActive() cursor.execute( """SELECT reviews.id, reviews.summary, reviews.branch, reviews.state, reviewusers.owner, reviewusers.uid IS NULL FROM reviews LEFT OUTER JOIN reviewusers ON (reviewusers.review=reviews.id AND reviewusers.uid=%s)""" + state_filter, (user.id, )) for review_id, summary, branch_id, review_state, is_owner, not_associated in cursor: if includeReview(review_id): if review_state == 'open': if is_owner or not_associated: continue fetchActive() if active["both"].has_key( review_id) or active["changes"].has_key( review_id) or active["comments"].has_key( review_id): continue watched[review_id] = summary, branch_id, None, None elif is_owner: owned_closed[ review_id] = summary, branch_id, None, None else: other_closed[ review_id] = summary, branch_id, None, None profiler.check("processing: watched/closed") other["watched"] = watched other["owned-closed"] = owned_closed other["other-closed"] = other_closed def renderWatched(): fetchWatchedAndClosed() watched = other["watched"] accepted = [] pending = [] is_accepted = isAccepted(watched.keys()) for review_id, (summary, branch_id, lines, comments) in sortedReviews(watched): if is_accepted[review_id]: accepted.append( (review_id, (summary, branch_id, lines, comments))) else: pending.append( (review_id, (summary, branch_id, lines, comments))) if accepted or pending: table = target.table("paleyellow reviews", id="watched", align="center", cellspacing=0) table.col(width="15%") table.col(width="15%") table.col(width="70%") header = table.tr().td("h1", colspan=4).h1() header.text("Watched Reviews") header.span("right").a(href=hidden("watched")).text("[hide]") if accepted: table.tr(id="active-changes-comments").td( "h2", colspan=4).h2().text("Accepted") renderReviews(table, accepted, False) if pending: table.tr(id="active-changes-comments").td( "h2", colspan=4).h2().text("Pending") renderReviews(table, pending, False) profiler.check("generate: watched") return True def renderClosed(): fetchWatchedAndClosed() owned_closed = other["owned-closed"] other_closed = other["other-closed"] if owned_closed or other_closed: table = target.table("paleyellow reviews", id="closed", align="center", cellspacing=0) table.col(width="15%") table.col(width="15%") table.col(width="70%") header = table.tr().td("h1", colspan=4).h1() header.text("Closed Reviews") header.span("right").a(href=hidden("closed")).text("[hide]") if not user.isAnonymous(): if owned_closed: table.tr().td("h2", colspan=4).h2().text("Owned") renderReviews(table, sortedReviews(owned_closed), False) if other_closed: table.tr().td("h2", colspan=4).h2().text("Other") renderReviews(table, sortedReviews(other_closed), False) else: renderReviews(table, sortedReviews(other_closed), False) profiler.check("generate: closed") return True def renderOpen(): other_open = {} cursor.execute( """SELECT reviews.id, reviews.summary, reviews.branch FROM reviews LEFT OUTER JOIN reviewusers ON (reviewusers.review=reviews.id AND reviewusers.uid=%s) WHERE reviews.state='open' AND reviewusers.uid IS NULL""", [user.id]) profiler.check("query: open") for review_id, summary, branch_id in cursor: if includeReview(review_id): other_open[review_id] = summary, branch_id, None, None profiler.check("processing: open") if other_open: accepted = [] pending = [] for review_id, (summary, branch_id, lines, comments) in sortedReviews(other_open): if dbutils.Review.isAccepted(db, review_id): accepted.append( (review_id, (summary, branch_id, lines, comments))) else: pending.append( (review_id, (summary, branch_id, lines, comments))) table = target.table("paleyellow reviews", id="open", align="center", cellspacing=0) table.col(width="15%") table.col(width="15%") table.col(width="70%") header = table.tr().td("h1", colspan=4).h1() header.text( "Open Reviews" if user.isAnonymous() else "Other Open Reviews") header.span("right").a(href=hidden("open")).text("[hide]") if accepted: table.tr().td("h2", colspan=4).h2().text("Accepted") renderReviews(table, accepted, False) if pending: table.tr().td("h2", colspan=4).h2().text("Pending") renderReviews(table, pending, False) profiler.check("generate: open") return True render = { "owned": renderOwned, "draft": renderDraft, "active": renderActive, "watched": renderWatched, "closed": renderClosed, "open": renderOpen } empty = True for item in showlist: if item in render: target.comment(repr(item)) if render[item](): empty = False yield flush(target) if empty: document.addExternalStylesheet("resource/message.css") body.div("message paleyellow").h1("center").text("No reviews!") profiler.output(db=db, user=user, target=document) yield flush(None)
def renderShowComments(req, db, user): context_lines = req.getParameter("context", user.getPreference( db, "comment.diff.contextLines"), filter=int) default_compact = "yes" if user.getPreference( db, "commit.diff.compactMode") else "no" compact = req.getParameter("compact", default_compact) == "yes" default_tabify = "yes" if user.getPreference( db, "commit.diff.visualTabs") else "no" tabify = req.getParameter("tabify", default_tabify) == "yes" original = req.getParameter("original", "no") == "yes" review_id = req.getParameter("review", filter=int) batch_id = req.getParameter("batch", None, filter=int) filter = req.getParameter("filter", "all") blame = req.getParameter("blame", None) profiler = profiling.Profiler() review = dbutils.Review.fromId(db, review_id) review.repository.enableBlobCache() cursor = db.cursor() profiler.check("create review") if blame is not None: blame_user = dbutils.User.fromName(db, blame) cursor.execute( """SELECT commentchains.id FROM commentchains JOIN commentchainlines ON (commentchainlines.chain=commentchains.id) JOIN fileversions ON (fileversions.new_sha1=commentchainlines.sha1) JOIN changesets ON (changesets.id=fileversions.changeset) JOIN commits ON (commits.id=changesets.child) JOIN gitusers ON (gitusers.id=commits.author_gituser) JOIN usergitemails USING (email) JOIN reviewchangesets ON (reviewchangesets.changeset=changesets.id AND reviewchangesets.review=commentchains.review) WHERE commentchains.review=%s AND usergitemails.uid=%s AND commentchains.state!='empty' AND (commentchains.state!='draft' OR commentchains.uid=%s) ORDER BY commentchains.file, commentchainlines.commit, commentchainlines.first_line""", (review.id, blame_user.id, user.id)) include_chain_ids = set([chain_id for (chain_id, ) in cursor]) profiler.check("initial blame filtering") else: include_chain_ids = None if filter == "toread": query = "SELECT commentchains.id FROM commentchains JOIN comments ON (comments.chain=commentchains.id) JOIN commentstoread ON (commentstoread.comment=comments.id) LEFT OUTER JOIN commentchainlines ON (commentchainlines.chain=commentchains.id) WHERE review=%s AND commentstoread.uid=%s ORDER BY file, commit, first_line" cursor.execute(query, (review.id, user.id)) else: query = "SELECT id FROM commentchains LEFT OUTER JOIN commentchainlines ON (chain=id) WHERE review=%s AND commentchains.state!='empty'" arguments = [review.id] if filter == "issues": query += " AND type='issue' AND (commentchains.state!='draft' OR commentchains.uid=%s)" arguments.append(user.id) elif filter == "draft-issues": query += " AND type='issue' AND commentchains.state='draft' AND commentchains.uid=%s" arguments.append(user.id) elif filter == "open-issues": query += " AND type='issue' AND commentchains.state='open'" elif filter == "addressed-issues": query += " AND type='issue' AND commentchains.state='addressed'" elif filter == "closed-issues": query += " AND type='issue' AND commentchains.state='closed'" elif filter == "notes": query += " AND type='note' AND (commentchains.state!='draft' OR commentchains.uid=%s)" arguments.append(user.id) elif filter == "draft-notes": query += " AND type='note' AND commentchains.state='draft' AND commentchains.uid=%s" arguments.append(user.id) elif filter == "open-notes": query += " AND type='note' AND commentchains.state='open'" else: query += " AND (commentchains.state!='draft' OR commentchains.uid=%s)" arguments.append(user.id) if batch_id is not None: query += " AND batch=%s" arguments.append(batch_id) # This ordering is inaccurate if comments apply to the same file but # different commits, but then, in that case there isn't really a # well-defined natural order either. Two comments that apply to the # same file and commit will at least be order by line number, and that's # better than nothing. query += " ORDER BY file, commit, first_line" cursor.execute(query, arguments) profiler.check("main query") if include_chain_ids is None: chain_ids = [chain_id for (chain_id, ) in cursor] else: chain_ids = [ chain_id for (chain_id, ) in cursor if chain_id in include_chain_ids ] profiler.check("query result") document = htmlutils.Document(req) html = document.html() head = html.head() body = html.body() document.addInternalScript(user.getJS(db)) document.addInternalScript(review.getJS()) page.utils.generateHeader( body, db, user, lambda target: review_utils.renderDraftItems(db, user, review, target), extra_links=[("r/%d" % review.id, "Back to Review", True)]) profiler.check("page header") target = body.div("main") if chain_ids and not user.isAnonymous() and user.name == req.user: document.addInternalScript( "$(function () { markChainsAsRead([%s]); });" % ", ".join(map(str, chain_ids))) #yield document.render(stop=target, pretty=not compact) if chain_ids: processed = set() chains = [] file_ids = set() changesets_files = {} changesets = {} if blame is not None: annotators = {} review.branch.loadCommits(db) commits = log.commitset.CommitSet(review.branch.commits) for chain_id in chain_ids: if chain_id in processed: continue else: processed.add(chain_id) chain = review_comment.CommentChain.fromId(db, chain_id, user, review=review) chains.append(chain) if chain.file_id is not None: file_ids.add(chain.file_id) changesets_files.setdefault( (chain.first_commit, chain.last_commit), set()).add(chain.file_id) profiler.check("load chains") changeset_cache = {} for (from_commit, to_commit), filtered_file_ids in changesets_files.items(): changesets[(from_commit, to_commit)] = changeset_utils.createChangeset( db, user, review.repository, from_commit=from_commit, to_commit=to_commit, filtered_file_ids=filtered_file_ids)[0] profiler.check("create changesets") if blame is not None: annotators[(from_commit, to_commit)] = operation.blame.LineAnnotator( db, from_commit, to_commit, file_ids=file_ids, commits=commits, changeset_cache=changeset_cache) profiler.check("create annotators") for chain in chains: if blame is not None and chain.file_id is not None: changeset = changesets[(chain.first_commit, chain.last_commit)] annotator = annotators[(chain.first_commit, chain.last_commit)] offset, count = chain.lines_by_sha1[changeset.getFile( chain.file_id).new_sha1] if not annotator.annotate(chain.file_id, offset, offset + count - 1, check_user=blame_user): continue profiler.check("detailed blame filtering") if chain.file_id is not None: from_commit, to_commit = review_html.getCodeCommentChainChangeset( db, chain, original) changeset = changesets.get((from_commit, to_commit)) else: changeset = None review_html.renderCommentChain(db, target, user, review, chain, context_lines=context_lines, compact=compact, tabify=tabify, original=original, changeset=changeset, linkify=linkify.Context( db=db, request=req, review=review)) profiler.check("rendering") yield document.render( stop=target, pretty=not compact ) + "<script>console.log((new Date).toString());</script>" profiler.check("transfer") page.utils.renderShortcuts(target, "showcomments") else: target.h1(align="center").text("No comments.") profiler.output(db, user, document) yield document.render(pretty=not compact)
def renderHome(req, db, user): if user.isAnonymous(): raise page.utils.NeedLogin(req) profiler = profiling.Profiler() cursor = db.cursor() readonly = req.getParameter( "readonly", "yes" if user.name != req.user else "no") == "yes" repository = req.getParameter("repository", None, gitutils.Repository.FromParameter(db)) verified_email_id = req.getParameter("email_verified", None, int) if not repository: repository = user.getDefaultRepository(db) title_fullname = user.fullname if title_fullname[-1] == 's': title_fullname += "'" else: title_fullname += "'s" cursor.execute( "SELECT email FROM usergitemails WHERE uid=%s ORDER BY email ASC", (user.id, )) gitemails = ", ".join([email for (email, ) in cursor]) document = htmlutils.Document(req) html = document.html() head = html.head() body = html.body() if user.name == req.user: actual_user = None else: actual_user = req.getUser(db) def renderHeaderItems(target): if readonly and actual_user and actual_user.hasRole( db, "administrator"): target.a("button", href="/home?user=%s&readonly=no" % user.name).text("Edit") page.utils.generateHeader(body, db, user, generate_right=renderHeaderItems, current_page="home") document.addExternalStylesheet("resource/home.css") document.addExternalScript("resource/home.js") document.addExternalScript("resource/autocomplete.js") if repository: document.addInternalScript(repository.getJS()) else: document.addInternalScript("var repository = null;") if actual_user and actual_user.hasRole(db, "administrator"): document.addInternalScript("var administrator = true;") else: document.addInternalScript("var administrator = false;") document.addInternalScript(user.getJS()) document.addInternalScript("user.gitEmails = %s;" % jsify(gitemails)) document.addInternalScript( "var verifyEmailAddresses = %s;" % jsify(configuration.base.VERIFY_EMAIL_ADDRESSES)) document.setTitle("%s Home" % title_fullname) target = body.div("main") basic = target.table('paleyellow basic', align='center') basic.tr().td('h1', colspan=3).h1().text("%s Home" % title_fullname) def row(heading, value, help=None, extra_class=None): if extra_class: row_class = "line " + extra_class else: row_class = "line" main_row = basic.tr(row_class) main_row.td('heading').text("%s:" % heading) value_cell = main_row.td('value', colspan=2) if callable(value): value(value_cell) else: value_cell.text(value) basic.tr('help').td('help', colspan=3).text(help) def renderFullname(target): if readonly: target.text(user.fullname) else: target.input("value", id="user_fullname", value=user.fullname) target.span("status", id="status_fullname") buttons = target.span("buttons") buttons.button(onclick="saveFullname();").text("Save") buttons.button(onclick="resetFullname();").text("Reset") def renderEmail(target): if not actual_user or actual_user.hasRole(db, "administrator"): cursor.execute( """SELECT id, email, verified FROM useremails WHERE uid=%s ORDER BY id ASC""", (user.id, )) rows = cursor.fetchall() if rows: if len(rows) > 1: target.addClass("multiple") addresses = target.div("addresses") for email_id, email, verified in rows: checked = "checked" if email == user.email else None selected = " selected" if email == user.email else "" label = addresses.label("address inset flex" + selected, data_email_id=email_id) if len(rows) > 1: label.input(name="email", type="radio", value=email, checked=checked) label.span("value").text(email) actions = label.span("actions") if verified is False: actions.a("action unverified", href="#").text("[unverified]") elif verified is True: now = " now" if email_id == verified_email_id else "" actions.span("action verified" + now).text("[verified]") actions.a("action delete", href="#").text("[delete]") else: target.i().text("No email address") target.span("buttons").button("addemail").text("Add email address") elif user.email is None: target.i().text("No email address") elif user.email_verified is False: # Pending verification: don't show to other users. target.i().text("Email address not verified") else: target.span("inset").text(user.email) def renderGitEmails(target): if readonly: target.text(gitemails) else: target.input("value", id="user_gitemails", value=gitemails) target.span("status", id="status_gitemails") buttons = target.span("buttons") buttons.button(onclick="saveGitEmails();").text("Save") buttons.button(onclick="resetGitEmails();").text("Reset") def renderPassword(target): cursor.execute("SELECT password IS NOT NULL FROM users WHERE id=%s", (user.id, )) has_password = cursor.fetchone()[0] if not has_password: target.text("not set") else: target.text("****") if not readonly: if not has_password or (actual_user and actual_user.hasRole( db, "administrator")): target.span("buttons").button( onclick="setPassword();").text("Set password") else: target.span("buttons").button( onclick="changePassword();").text("Change password") row("User ID", str(user.id)) row("User Name", user.name) row("Display Name", renderFullname, "This is the name used when displaying commits or comments.") row("Primary Email", renderEmail, "This is the primary email address, to which emails are sent.", extra_class="email") row( "Git Emails", renderGitEmails, "These email addresses (comma-separated) are used to map Git commits to the user." ) if configuration.base.AUTHENTICATION_MODE == "critic": row("Password", renderPassword, extra_class="password") cursor.execute( """SELECT provider, account FROM externalusers WHERE uid=%s""", (user.id, )) external_accounts = [(auth.PROVIDERS[provider_name], account) for provider_name, account in cursor if provider_name in auth.PROVIDERS] if external_accounts: basic.tr().td('h2', colspan=3).h2().text("External Accounts") for provider, account in external_accounts: def renderExternalAccount(target): url = provider.getAccountURL(account) target.a("external", href=url).text(account) row(provider.getTitle(), renderExternalAccount) profiler.check("user information") filters = page.utils.PaleYellowTable(body, "Filters") filters.titleRight.a("button", href="/tutorial?item=filters").text("Tutorial") cursor.execute( """SELECT repositories.id, repositories.name, repositories.path, filters.id, filters.type, filters.path, NULL, filters.delegate FROM repositories JOIN filters ON (filters.repository=repositories.id) WHERE filters.uid=%s""", (user.id, )) rows = cursor.fetchall() if configuration.extensions.ENABLED: cursor.execute( """SELECT repositories.id, repositories.name, repositories.path, filters.id, 'extensionhook', filters.path, filters.name, filters.data FROM repositories JOIN extensionhookfilters AS filters ON (filters.repository=repositories.id) WHERE filters.uid=%s""", (user.id, )) rows.extend(cursor.fetchall()) FILTER_TYPES = ["reviewer", "watcher", "ignored", "extensionhook"] def rowSortKey(row): (repository_id, repository_name, repository_path, filter_id, filter_type, filter_path, filter_name, filter_data) = row # Rows are grouped by repository first and type second, so sort by # repository name and filter type primarily. # # Secondarily sort by filter name (only for extension hook filters; is # None for regular filters) and filter path. This sorting is mostly to # achieve a stable order; it has no greater meaning. return (repository_name, FILTER_TYPES.index(filter_type), filter_name, filter_path) rows.sort(key=rowSortKey) if rows: repository = None repository_filters = None tbody_reviewer = None tbody_watcher = None tbody_ignored = None tbody_extensionhook = None count_matched_files = {} for (repository_id, repository_name, repository_path, filter_id, filter_type, filter_path, filter_name, filter_data) in rows: if not repository or repository.id != repository_id: repository = gitutils.Repository.fromId(db, repository_id) repository_url = repository.getURL(db, user) filters.addSection(repository_name, repository_url) repository_filters = filters.addCentered().table( "filters callout") tbody_reviewer = tbody_watcher = tbody_ignored = tbody_extensionhook = None if filter_type == "reviewer": if not tbody_reviewer: tbody_reviewer = repository_filters.tbody() tbody_reviewer.tr().th(colspan=5).text("Reviewer") tbody = tbody_reviewer elif filter_type == "watcher": if not tbody_watcher: tbody_watcher = repository_filters.tbody() tbody_watcher.tr().th(colspan=5).text("Watcher") tbody = tbody_watcher elif filter_type == "ignored": if not tbody_ignored: tbody_ignored = repository_filters.tbody() tbody_ignored.tr().th(colspan=5).text("Ignored") tbody = tbody_ignored else: if not tbody_extensionhook: tbody_extensionhook = repository_filters.tbody() tbody_extensionhook.tr().th( colspan=5).text("Extension hooks") tbody = tbody_extensionhook row = tbody.tr() row.td("path").text(filter_path) if filter_type != "extensionhook": delegates = row.td("delegates", colspan=2) if filter_data: delegates.i().text("Delegates: ") delegates.span("names").text(", ".join( filter_data.split(","))) else: role = extensions.role.filterhook.getFilterHookRole( db, filter_id) if role: title = row.td("title") title.text(role.title) data = row.td("data") data.text(filter_data) else: row.td(colspan=2).i().text("Invalid filter") if filter_path == "/": row.td("files").text("all files") else: href = "javascript:void(showMatchedFiles(%s, %s));" % (jsify( repository.name), jsify(filter_path)) row.td("files").a(href=href, id=("f%d" % filter_id)).text("? files") count_matched_files.setdefault(repository_id, []).append(filter_id) links = row.td("links") arguments = (jsify(repository.name), filter_id, jsify(filter_type), jsify(filter_path), jsify(filter_data)) links.a(href="javascript:void(editFilter(%s, %d, %s, %s, %s));" % arguments).text("[edit]") if filter_type != "extensionhook": links.a( href= "javascript:if (deleteFilterById(%d)) location.reload(); void(0);" % filter_id).text("[delete]") links.a(href="javascript:location.href='/config?filter=%d';" % filter_id).text("[preferences]") else: links.a( href= "javascript:if (deleteExtensionHookFilterById(%d)) location.reload(); void(0);" % filter_id).text("[delete]") document.addInternalScript("var count_matched_files = %s;" % json_encode(count_matched_files.values())) else: filters.addCentered().p().b().text("No filters") # Additionally check if there are in fact no repositories. cursor.execute("SELECT 1 FROM repositories") if not cursor.fetchone(): document.addInternalScript("var no_repositories = true;") if not readonly: filters.addSeparator() filters.addCentered().button( onclick="editFilter();").text("Add filter") profiler.check("filters") hidden = body.div("hidden", style="display: none") if configuration.extensions.ENABLED: filterhooks = extensions.role.filterhook.listFilterHooks(db, user) else: filterhooks = [] with hidden.div("filterdialog") as dialog: paragraph = dialog.p() paragraph.b().text("Repository:") paragraph.br() page.utils.generateRepositorySelect(db, user, paragraph, name="repository") paragraph = dialog.p() paragraph.b().text("Filter type:") paragraph.br() filter_type = paragraph.select(name="type") filter_type.option(value="reviewer").text("Reviewer") filter_type.option(value="watcher").text("Watcher") filter_type.option(value="ignored").text("Ignored") for extension, manifest, roles in filterhooks: optgroup = filter_type.optgroup(label=extension.getTitle(db)) for role in roles: option = optgroup.option( value="extensionhook", data_extension_id=extension.getExtensionID(db), data_filterhook_name=role.name) option.text(role.title) paragraph = dialog.p() paragraph.b().text("Path:") paragraph.br() paragraph.input(name="path", type="text") paragraph.span("matchedfiles") regular_div = dialog.div("regular") paragraph = regular_div.p() paragraph.b().text("Delegates:") paragraph.br() paragraph.input(name="delegates", type="text") paragraph = regular_div.p() label = paragraph.label() label.input(name="apply", type="checkbox", checked="checked") label.b().text("Apply to existing reviews") for extension, manifest, roles in filterhooks: for role in roles: if not role.data_description: continue filterhook_id = "%d_%s" % (extension.getExtensionID(db), role.name) extensionhook_div = dialog.div("extensionhook " + filterhook_id, style="display: none") extensionhook_div.innerHTML(role.data_description) paragraph = extensionhook_div.p() paragraph.b().text("Data:") paragraph.br() paragraph.input(type="text") profiler.output(db, user, document) return document
def load(data): input_stream = InputStream(data) lexer = UDMFLexer(input_stream) token_stream = CommonTokenStream(lexer) parser = UDMFParser(token_stream) tree = parser.udmf() udmf_map = UDMFMap() extractor = UDMFDataExtractor(udmf_map) ParseTreeWalker().walk(extractor, tree) return udmf_map if __name__ == '__main__': import sys if 1 == len(sys.argv): print('Usage: %s textmap.txt ...' % __file__) sys.exit(0) import profiling profiler = profiling.Profiler(False) for filename in sys.argv[1:]: with open(filename) as f: print(load(f.read()).astext()) profiler.close()