From: W. Trevor King Date: Fri, 7 Aug 2009 18:19:30 +0000 (-0400) Subject: Merged Gianluca's html output branch. X-Git-Tag: 1.0.0~62^2~34 X-Git-Url: http://git.tremily.us/gitweb.cgi?a=commitdiff_plain;h=91d4c0bf808f849bed642d6c448957d5f0f3cc3d;p=be.git Merged Gianluca's html output branch. Changes to merge with my branch: * Added some reference to "be html" or "becommands/html.py" in his new bugs' summaries. Bug titles should make clear to which aspect of our growing repository they refer. * Fixed unittests in becommands/html.py. * execute() kwarg "test"->!"manipulate_encodings * bugdir.simple_bug_dir() -> bugdir.SimpleBugDir() * bd.cleanup() at end of unittests --- 91d4c0bf808f849bed642d6c448957d5f0f3cc3d diff --cc .be/bugs/2b81b428-fc43-4970-9469-b442385b9c0d/values index 0000000,0a47ab5..c2861d0 mode 000000,100644..100644 --- a/.be/bugs/2b81b428-fc43-4970-9469-b442385b9c0d/values +++ b/.be/bugs/2b81b428-fc43-4970-9469-b442385b9c0d/values @@@ -1,0 -1,17 +1,17 @@@ + creator: gianluca + + + reporter: gianluca + + + severity: minor + + -status: closed ++status: fixed + + -summary: Use the get_parser ++summary: Use the get_parser in becommands/html.py + + + time: Wed, 08 Jul 2009 21:27:37 +0000 + diff --cc .be/bugs/8385a1fb-63df-4ca6-81cd-28ede83bb0c2/values index 0000000,918f6be..5d80e70 mode 000000,100644..100644 --- a/.be/bugs/8385a1fb-63df-4ca6-81cd-28ede83bb0c2/values +++ b/.be/bugs/8385a1fb-63df-4ca6-81cd-28ede83bb0c2/values @@@ -1,0 -1,17 +1,17 @@@ + creator: gianluca + + + reporter: gianluca + + + severity: minor + + + status: wontfix + + -summary: Add the html files for the status detail ++summary: Add the html files for the status detail to "be html" output + + + time: Fri, 03 Jul 2009 22:56:09 +0000 + diff --cc .be/bugs/9b1a0e71-4f7d-40b1-ab32-18496bf19a3f/values index 0000000,600f2c3..4b6bb4f mode 000000,100644..100644 --- a/.be/bugs/9b1a0e71-4f7d-40b1-ab32-18496bf19a3f/values +++ b/.be/bugs/9b1a0e71-4f7d-40b1-ab32-18496bf19a3f/values @@@ -1,0 -1,17 +1,17 @@@ + creator: gianluca + + + reporter: gianluca + + + severity: minor + + + status: wontfix + + -summary: Add the html files for the severity detail ++summary: Add the html files for the severity detail to "be html" output + + + time: Fri, 03 Jul 2009 22:56:19 +0000 + diff --cc .be/bugs/c271a802-d324-48a6-b01d-63e4a72aa43e/values index 0000000,8b58566..b859364 mode 000000,100644..100644 --- a/.be/bugs/c271a802-d324-48a6-b01d-63e4a72aa43e/values +++ b/.be/bugs/c271a802-d324-48a6-b01d-63e4a72aa43e/values @@@ -1,0 -1,17 +1,17 @@@ + creator: gianluca + + + reporter: gianluca + + + severity: wishlist + + + status: open + + -summary: Add a verbose option? ++summary: Add a verbose option to "be html"? + + + time: Fri, 03 Jul 2009 21:17:41 +0000 + diff --cc .be/bugs/d8dba78d-f82a-4674-9003-a0ec569b4a96/comments/5b2e1ec8-3bb7-40cd-9f4f-74e5c59838f6/body index 0000000,0000000..1090ace new file mode 100644 --- /dev/null +++ b/.be/bugs/d8dba78d-f82a-4674-9003-a0ec569b4a96/comments/5b2e1ec8-3bb7-40cd-9f4f-74e5c59838f6/body @@@ -1,0 -1,0 +1,2 @@@ ++Available with ++ be -d DIR html diff --cc .be/bugs/d8dba78d-f82a-4674-9003-a0ec569b4a96/comments/5b2e1ec8-3bb7-40cd-9f4f-74e5c59838f6/values index 0000000,0000000..9ac4884 new file mode 100644 --- /dev/null +++ b/.be/bugs/d8dba78d-f82a-4674-9003-a0ec569b4a96/comments/5b2e1ec8-3bb7-40cd-9f4f-74e5c59838f6/values @@@ -1,0 -1,0 +1,8 @@@ ++Author: W. Trevor King ++ ++ ++Content-type: text/plain ++ ++ ++Date: Fri, 07 Aug 2009 17:58:58 +0000 ++ diff --cc .be/bugs/d8dba78d-f82a-4674-9003-a0ec569b4a96/values index 0000000,a5777b9..ce4bc92 mode 000000,100644..100644 --- a/.be/bugs/d8dba78d-f82a-4674-9003-a0ec569b4a96/values +++ b/.be/bugs/d8dba78d-f82a-4674-9003-a0ec569b4a96/values @@@ -1,0 -1,17 +1,17 @@@ + creator: gianluca + + + reporter: gianluca + + + severity: wishlist + + -status: closed ++status: fixed + + -summary: Add the possibility to specify the repository Directory ? ++summary: Add the possibility to specify the repository directory to "be html"? + + + time: Fri, 03 Jul 2009 21:18:13 +0000 + diff --cc .be/bugs/da2b09ff-af24-40f3-9b8d-6ffaa5f41164/values index 0000000,4d784ad..2832bb3 mode 000000,100644..100644 --- a/.be/bugs/da2b09ff-af24-40f3-9b8d-6ffaa5f41164/values +++ b/.be/bugs/da2b09ff-af24-40f3-9b8d-6ffaa5f41164/values @@@ -1,0 -1,17 +1,17 @@@ + creator: Gianluca Montecchi + + + reporter: Gianluca Montecchi + + + severity: wishlist + + + status: open + + -summary: Add an icon near the status string ++summary: Add an icon near the status string in "be html" output + + + time: Tue, 04 Aug 2009 21:15:52 +0000 + diff --cc .be/bugs/f77fc673-c852-4c81-bfa2-1d59de2661c8/values index 0000000,5a7261b..72c2839 mode 000000,100644..100644 --- a/.be/bugs/f77fc673-c852-4c81-bfa2-1d59de2661c8/values +++ b/.be/bugs/f77fc673-c852-4c81-bfa2-1d59de2661c8/values @@@ -1,0 -1,17 +1,17 @@@ + creator: Gianluca Montecchi + + + reporter: Gianluca Montecchi + + + severity: minor + + + status: fixed + + -summary: Comment should be threaded in the html output ++summary: Comment should be threaded in the "be html" output + + + time: Tue, 21 Jul 2009 21:39:52 +0000 + diff --cc becommands/html.py index 0000000,4bf43f4..3acf973 mode 000000,100644..100644 --- a/becommands/html.py +++ b/becommands/html.py @@@ -1,0 -1,581 +1,587 @@@ -# Copyright (C) 2005-2009 Aaron Bentley and Panometrics, Inc. -# Marien Zwart -# Thomas Gerigk -# W. Trevor King -# ++# Copyright (C) 2005-2009 + # + # 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. + # + # 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 + """Generate a static HTML dump of the current repository status""" -from libbe import cmdutil, bugdir, bug, settings_object ++from libbe import cmdutil, bugdir, bug + #from html_data import * + 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) + complete(options, args, parser) + cmdutil.default_complete(options, args, parser, + bugid_args={0: lambda bug : bug.active==False}) + + if len(args) == 0: + out_dir = options.outdir + print "Creating the html output in %s"%out_dir + else: + out_dir = args[0] + 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 + st = {} + se = {} + stime = {} + bugs_active = [] + bugs_inactive = [] + for s in status_list: + st[s] = 0 + for b in sorted(bd, reverse=True): + stime[b.uuid] = b.time + if b.status in ["open", "test", "unconfirmed", "assigned"]: + bugs_active.append(b) + else: + bugs_inactive.append(b) + st[b.status] += 1 + ordered_bug_list = sorted([(value,key) for (key,value) in stime.items()]) + ordered_bug_list_in = sorted([(value,key) for (key,value) in stime.items()]) + #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", 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") + parser.add_option("-o", "--output", metavar="export_dir", dest="outdir", + help="Set the output path, default is ./html_export", default="html_export") + return parser + + longhelp=""" + Generate a set of html pages representing the current state of the bug + directory. + """ + + def help(): + return get_parser().help_str() + longhelp + + def complete(options, args, parser): + for option, value in cmdutil.option_value_pairs(options, parser): + if "--complete" in args: + raise cmdutil.GetCompletions() # no positional arguments for list + + + def escape(string): - if string == settings_object.EMPTY: ++ 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 = "" + self.bd = bd + + self.css_file = """ + body { + font-family: "lucida grande", "sans serif"; + color: #333; + width: auto; + margin: auto; + } + + + div.main { + padding: 20px; + margin: auto; + padding-top: 0; + margin-top: 1em; + background-color: #fcfcfc; + } + + .comment { + padding: 20px; + margin: auto; + padding-top: 20px; + margin-top: 0; + } + + .commentF { + padding: 0px; + margin: auto; + padding-top: 0px; + paddin-bottom: 20px; + margin-top: 0; + } + + tb { + border = 1; + } + + .wishlist-row { + background-color: #B4FF9B; + width: auto; + } + + .minor-row { + background-color: #FCFF98; + width: auto; + } + + + .serious-row { + background-color: #FFB648; + width: auto; + } + + .critical-row { + background-color: #FF752A; + width: auto; + } + + .fatal-row { + background-color: #FF3300; + width: auto; + } + + .person { + font-family: courier; + } + + a, a:visited { + background: inherit; + text-decoration: none; + } + + a { + color: #003d41; + } + + a:visited { + color: #553d41; + } + + ul { + list-style-type: none; + padding: 0; + } + + p { + width: auto; + } + + .inline-status-image { + position: relative; + top: 0.2em; + } + + .dimmed { + color: #bbb; + } + + table { + border-style: 10px solid #313131; + border-spacing: 0; + width: auto; + } + + table.log { + } + + td { + border-width: 0; + border-style: none; + padding-right: 0.5em; + padding-left: 0.5em; + width: auto; + } + + .td_sel { + background-color: #afafaf; + border: 1px solid #afafaf; + font-weight:bold; + padding-right: 1em; + padding-left: 1em; + + } + + .td_nsel { + border: 0px; + padding-right: 1em; + padding-left: 1em; + } + + tr { + vertical-align: top; + width: auto; + } + + h1 { + padding: 0.5em; + background-color: #305275; + margin-top: 0; + margin-bottom: 0; + color: #fff; + margin-left: -20px; + margin-right: -20px; + } + + wid { + text-transform: uppercase; + font-size: smaller; + margin-top: 1em; + margin-left: -0.5em; + /*background: #fffbce;*/ + /*background: #628a0d;*/ + padding: 5px; + color: #305275; + } + + .attrname { + text-align: right; + font-size: smaller; + } + + .attrval { + color: #222; + } + + .issue-closed-fixed { + background-image: "green-check.png"; + } + + .issue-closed-wontfix { + background-image: "red-check.png"; + } + + .issue-closed-reorg { + background-image: "blue-check.png"; + } + + .inline-issue-link { + text-decoration: underline; + } + + img { + border: 0; + } + + + div.footer { + font-size: small; + padding-left: 20px; + padding-right: 20px; + padding-top: 5px; + padding-bottom: 5px; + margin: auto; + background: #305275; + color: #fffee7; + } + + .footer a { + color: #508d91; + } + + + .header { + font-family: "lucida grande", "sans serif"; + font-size: smaller; + background-color: #a9a9a9; + text-align: left; + + padding-right: 0.5em; + padding-left: 0.5em; + + } + + + .selected-cell { + background-color: #e9e9e2; + } + + .plain-cell { + background-color: #f9f9f9; + } + + + .logcomment { + padding-left: 4em; + font-size: smaller; + } + + .id { + font-family: courier; + } + + .table_bug { + background-color: #afafaf; + border: 2px solid #afafaf; + } + + .message { + } + + .progress-meter-done { + background-color: #03af00; + } + + .progress-meter-undone { + background-color: #ddd; + } + + .progress-meter { + } + + """ + + self.index_first = """ + + + + BugsEverywhere Issue Tracker + + + + + + +
+

BugsEverywhere Bug List

+

+ + + + + + + +
Active BugsInactive Bugs
+ + + """ % self.bd.encoding + + self.bug_line =""" + + + + + + + + """ + + self.detail_first = """ + + + + BugsEverywhere Issue Tracker + + + + + + +
+

BugsEverywhere Bug List

+
Back to Index
+

Bug: _bug_id_

+
%s%s%s%s%s
+ + """ % self.bd.encoding + + + + self.detail_line =""" + + + + """ + + self.index_last = """ + +
%s%s
+ +
+ + + + + + """ + + self.comment_section = """ + """ + + self.begin_comment_section =""" + + Comments: + + + """ + + + self.end_comment_section =""" + + + """ + + self.detail_last = """ + + + +
Back to Index
+ + + + """ + + + def create_index_file(self, out_dir_path, summary, bugs, ordered_bug, fileid, encoding): + try: + os.stat(out_dir_path) + except: + try: + os.mkdir(out_dir_path) + except: + raise cmdutil.UsageError, "Cannot create output directory." + try: + FO = codecs.open(out_dir_path+"/style.css", "w", encoding) + FO.write(self.css_file) + FO.close() + except: + raise cmdutil.UsageError, "Cannot create the style.css file." + + try: + os.mkdir(out_dir_path+"/bugs") + except: + pass + + try: + if fileid == "active": + FO = codecs.open(out_dir_path+"/index.html", "w", encoding) + FO.write(self.index_first%('td_sel','td_nsel')) + if fileid == "inactive": + 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." + + c = 0 + t = len(bugs) - 1 + for l in range(t, -1, -1): + 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, encoding) + when = time.ctime() + FO.write(self.index_last%when) + + + def create_detail_file(self, bug, out_dir_path, fileid, encoding): + f = "%s.html"%bug.uuid + p = out_dir_path+"/bugs/"+f + try: + FD = codecs.open(p, "w", encoding) + except: + raise cmdutil.UsageError, "Cannot create the detail html file." + + detail_first_ = re.sub('_bug_id_', bug.uuid[0:3], self.detail_first) + if fileid == "active": + FD.write(detail_first_%"../index.html") + if fileid == "inactive": + FD.write(detail_first_%"../index_inactive.html") + + + + bug_ = self.bd.bug_from_shortname(bug.uuid) + bug_.load_comments(load_full=True) + + FD.write(self.detail_line%("ID : ", bug.uuid)) + 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("
") + FD.write(self.begin_comment_section) + tr = [] + b = '' + level = 0 + 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("\n") # close non-parent
') + else: + FD.write('
') + FD.write("
\n".join(lines)+"
\n") + while len(stack) > 0: + stack.pop(-1) + FD.write("
\n") # close every remaining