diff options
Diffstat (limited to 'becommands/html.py')
-rw-r--r-- | becommands/html.py | 214 |
1 files changed, 113 insertions, 101 deletions
diff --git a/becommands/html.py b/becommands/html.py index 4835227..908c714 100644 --- a/becommands/html.py +++ b/becommands/html.py @@ -1,40 +1,47 @@ -# Copyright (C) 2005-2009 Aaron Bentley and Panometrics, Inc. -# Marien Zwart <marienz@gentoo.org> -# Thomas Gerigk <tgerigk@gmx.de> -# W. Trevor King <wking@drexel.edu> -# <abentley@panoramicfeedback.com> +# Copyright (C) 2009 Gianluca Montecchi <gian@grys.it> +# W. Trevor King <wking@drexel.edu> # -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. # -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -"""Re-open a bug""" +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +"""Generate a static HTML dump of the current repository status""" from libbe import cmdutil, bugdir, bug #from html_data import * -import os, re, time, string +import codecs, os, re, string, time +import xml.sax.saxutils, htmlentitydefs __desc__ = __doc__ -def execute(args, test=False): +def execute(args, manipulate_encodings=True): """ >>> import os - >>> bd = bugdir.simple_bug_dir() + >>> bd = bugdir.SimpleBugDir() >>> os.chdir(bd.root) - >>> print bd.bug_from_shortname("b").status - closed - >>> execute(["b"], test=True) - >>> bd._clear_bugs() - >>> print bd.bug_from_shortname("b").status - open + >>> execute([], manipulate_encodings=False) + Creating the html output in html_export + >>> os.path.exists("./html_export") + True + >>> os.path.exists("./html_export/index.html") + True + >>> os.path.exists("./html_export/index_inactive.html") + True + >>> os.path.exists("./html_export/bugs") + True + >>> os.path.exists("./html_export/bugs/a.html") + True + >>> os.path.exists("./html_export/bugs/b.html") + True + >>> bd.cleanup() """ parser = get_parser() options, args = parser.parse_args(args) @@ -50,7 +57,8 @@ def execute(args, test=False): if len(args) > 0: raise cmdutil.UsageError, "Too many arguments." - bd = bugdir.BugDir(from_disk=True, manipulate_encodings=not test) + bd = bugdir.BugDir(from_disk=True, + manipulate_encodings=manipulate_encodings) bd.load_all_bugs() status_list = bug.status_values severity_list = bug.severity_values @@ -61,9 +69,9 @@ def execute(args, test=False): bugs_inactive = [] for s in status_list: st[s] = 0 - for b in bd: + for b in sorted(bd, reverse=True): stime[b.uuid] = b.time - if b.status in ["open", "test", "unconfirmed", "assigned"]: + if b.active == True: bugs_active.append(b) else: bugs_inactive.append(b) @@ -73,8 +81,8 @@ def execute(args, test=False): #open_bug_list = sorted([(value,key) for (key,value) in bugs.items()]) html_gen = BEHTMLGen(bd) - html_gen.create_index_file(out_dir, st, bugs_active, ordered_bug_list, "active") - html_gen.create_index_file(out_dir, st, bugs_inactive, ordered_bug_list, "inactive") + html_gen.create_index_file(out_dir, st, bugs_active, ordered_bug_list, "active", bd.encoding) + html_gen.create_index_file(out_dir, st, bugs_inactive, ordered_bug_list, "inactive", bd.encoding) def get_parser(): parser = cmdutil.CmdOptionParser("be open OUTPUT_DIR") @@ -83,7 +91,8 @@ def get_parser(): return parser longhelp=""" -Generate a set of html pages. +Generate a set of html pages representing the current state of the bug +directory. """ def help(): @@ -94,7 +103,18 @@ def complete(options, args, parser): if "--complete" in args: raise cmdutil.GetCompletions() # no positional arguments for list - + +def escape(string): + if string == None: + return "" + chars = [] + for char in xml.sax.saxutils.escape(string): + codepoint = ord(char) + if codepoint in htmlentitydefs.codepoint2name: + char = "&%s;" % htmlentitydefs.codepoint2name[codepoint] + chars.append(char) + return "".join(chars) + class BEHTMLGen(): def __init__(self, bd): self.index_value = "" @@ -353,10 +373,12 @@ class BEHTMLGen(): """ self.index_first = """ + <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <title>BugsEverywhere Issue Tracker</title> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta http-equiv="Content-Type" content="text/html; charset=%s" /> <link rel="stylesheet" href="style.css" type="text/css" /> </head> <body> @@ -368,17 +390,17 @@ class BEHTMLGen(): <table> <tr> - <td class=%s><a href="index.html">Active Bugs</a></td> - <td class=%s><a href="index_inactive.html">Inactive Bugs</a></td> + <td class="%%s"><a href="index.html">Active Bugs</a></td> + <td class="%%s"><a href="index_inactive.html">Inactive Bugs</a></td> </tr> </table> - <table class=table_bug> + <table class="table_bug"> <tbody> - """ + """ % self.bd.encoding self.bug_line =""" - <tr class=%s-row cellspacing=1> + <tr class="%s-row"> <td ><a href="bugs/%s.html">%s</a></td> <td ><a href="bugs/%s.html">%s</a></td> <td><a href="bugs/%s.html">%s</a></td> @@ -388,10 +410,12 @@ class BEHTMLGen(): """ self.detail_first = """ + <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <title>BugsEverywhere Issue Tracker</title> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta http-equiv="Content-Type" content="text/html; charset=%s" /> <link rel="stylesheet" href="../style.css" type="text/css" /> </head> <body> @@ -399,11 +423,11 @@ class BEHTMLGen(): <div class="main"> <h1>BugsEverywhere Bug List</h1> - <h5><a href="%s">Back to Index</a></h5> + <h5><a href="%%s">Back to Index</a></h5> <h2>Bug: _bug_id_</h2> <table > <tbody> - """ + """ % self.bd.encoding @@ -430,7 +454,7 @@ class BEHTMLGen(): self.begin_comment_section =""" <tr> - <td align=right>Comments: + <td align="right">Comments: </td> <td> """ @@ -452,7 +476,7 @@ class BEHTMLGen(): """ - def create_index_file(self, out_dir_path, summary, bugs, ordered_bug, fileid): + def create_index_file(self, out_dir_path, summary, bugs, ordered_bug, fileid, encoding): try: os.stat(out_dir_path) except: @@ -461,7 +485,7 @@ class BEHTMLGen(): except: raise cmdutil.UsageError, "Cannot create output directory." try: - FO = open(out_dir_path+"/style.css", "w") + FO = codecs.open(out_dir_path+"/style.css", "w", encoding) FO.write(self.css_file) FO.close() except: @@ -474,10 +498,10 @@ class BEHTMLGen(): try: if fileid == "active": - FO = open(out_dir_path+"/index.html", "w") + FO = codecs.open(out_dir_path+"/index.html", "w", encoding) FO.write(self.index_first%('td_sel','td_nsel')) if fileid == "inactive": - FO = open(out_dir_path+"/index_inactive.html", "w") + FO = codecs.open(out_dir_path+"/index_inactive.html", "w", encoding) FO.write(self.index_first%('td_nsel','td_sel')) except: raise cmdutil.UsageError, "Cannot create the index.html file." @@ -485,25 +509,25 @@ class BEHTMLGen(): c = 0 t = len(bugs) - 1 for l in range(t, -1, -1): - line = self.bug_line%(bugs[l].severity, - bugs[l].uuid, bugs[l].uuid[0:3], - bugs[l].uuid, bugs[l].status, - bugs[l].uuid, bugs[l].severity, - bugs[l].uuid, bugs[l].summary, - bugs[l].uuid, bugs[l].time_string - ) + line = self.bug_line%(escape(bugs[l].severity), + escape(bugs[l].uuid), escape(bugs[l].uuid[0:3]), + escape(bugs[l].uuid), escape(bugs[l].status), + escape(bugs[l].uuid), escape(bugs[l].severity), + escape(bugs[l].uuid), escape(bugs[l].summary), + escape(bugs[l].uuid), escape(bugs[l].time_string) + ) FO.write(line) c += 1 - self.create_detail_file(bugs[l], out_dir_path, fileid) + self.create_detail_file(bugs[l], out_dir_path, fileid, encoding) when = time.ctime() FO.write(self.index_last%when) - def create_detail_file(self, bug, out_dir_path, fileid): + def create_detail_file(self, bug, out_dir_path, fileid, encoding): f = "%s.html"%bug.uuid p = out_dir_path+"/bugs/"+f try: - FD = open(p, "w") + FD = codecs.open(p, "w", encoding) except: raise cmdutil.UsageError, "Cannot create the detail html file." @@ -519,53 +543,41 @@ class BEHTMLGen(): bug_.load_comments(load_full=True) FD.write(self.detail_line%("ID : ", bug.uuid)) - FD.write(self.detail_line%("Short name : ", bug.uuid[0:3])) - FD.write(self.detail_line%("Severity : ", bug.severity)) - FD.write(self.detail_line%("Status : ", bug.status)) - FD.write(self.detail_line%("Assigned : ", bug.assigned)) - FD.write(self.detail_line%("Target : ", bug.target)) - FD.write(self.detail_line%("Reporter : ", bug.reporter)) - FD.write(self.detail_line%("Creator : ", bug.creator)) - FD.write(self.detail_line%("Created : ", bug.time_string)) - FD.write(self.detail_line%("Summary : ", bug.summary)) - FD.write("<tr><td colspan=2><hr></td></tr>") + FD.write(self.detail_line%("Short name : ", escape(bug.uuid[0:3]))) + FD.write(self.detail_line%("Severity : ", escape(bug.severity))) + FD.write(self.detail_line%("Status : ", escape(bug.status))) + FD.write(self.detail_line%("Assigned : ", escape(bug.assigned))) + FD.write(self.detail_line%("Target : ", escape(bug.target))) + FD.write(self.detail_line%("Reporter : ", escape(bug.reporter))) + FD.write(self.detail_line%("Creator : ", escape(bug.creator))) + FD.write(self.detail_line%("Created : ", escape(bug.time_string))) + FD.write(self.detail_line%("Summary : ", escape(bug.summary))) + FD.write("<tr><td colspan=\"2\"><hr /></td></tr>") FD.write(self.begin_comment_section) tr = [] b = '' level = 0 - for i in bug_.comments(): - if not isinstance(i.in_reply_to,str): - first = True - a = i.string_thread(flatten=False) - d = re.split('\n',a) - for x in range(0,len(d)): - hr = "" - if re.match(" *--------- Comment ---------",d[x]): - com = """ - %s<br> - %s<br> - %s<br> - %s<br> - %s<br> - """%(d[x+1],d[x+2],d[x+3],d[x+4],d[x+5]) - l = re.sub("--------- Comment ---------", "", d[x]) - ll = l.split(" ") - la = l - ba = "" - if len(la) > level: - FD.write("<div class='comment'>") - if len(la) < level: - FD.write("</div>") - if len(la) == 0: - if not first : - FD.write("</div>") - first = False - FD.write("<div class='commentF'>") - level = len(la) - x += 5 - FD.write("--------- Comment ---------<p />") - FD.write(com) - FD.write("</div>") + stack = [] + for depth,comment in bug_.comment_root.thread(flatten=False): + while len(stack) > depth: + stack.pop(-1) # pop non-parents off the stack + FD.write("</div>\n") # close non-parent <div class="comment... + assert len(stack) == depth + stack.append(comment) + lines = ["--------- Comment ---------", + "Name: %s" % comment.uuid, + "From: %s" % escape(comment.author), + "Date: %s" % escape(comment.date), + ""] + lines.extend(escape(comment.body).splitlines()) + if depth == 0: + FD.write('<div class="commentF">') + else: + FD.write('<div class="comment">') + FD.write("<br />\n".join(lines)+"<br />\n") + while len(stack) > 0: + stack.pop(-1) + FD.write("</div>\n") # close every remaining <div class="comment... FD.write(self.end_comment_section) if fileid == "active": FD.write(self.detail_last%"../index.html") @@ -573,4 +585,4 @@ class BEHTMLGen(): FD.write(self.detail_last%"../index_inactive.html") FD.close() -
\ No newline at end of file + |