# # cat.py - DITrack 'cat' command # # Copyright (c) 2006-2007 The DITrack Project, www.ditrack.org. # # $Id: cat.py 2191 2007-10-15 22:34:10Z vss $ # $HeadURL: https://127.0.0.1/ditrack/src/tags/0.7/DITrack/Command/cat.py $ # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # import sys # DITrack modules import DITrack.Command.generic class Handler(DITrack.Command.generic.Handler): canonical_name = "cat" description = """Dump contents/headers of an issue or its part. usage: %s ISSUEID or: %s ISSUEID.COMMENTID or: %s [--path] ISSUEID.{ATTACHMENT_NAME} """ % (canonical_name, canonical_name, canonical_name) def run(self, opts, globals): self.check_options(opts) if len(opts.fixed) != 2: self.print_help(globals) sys.exit(1) # XXX: this double check '("X" in ...) and ...' is silly, need to # wrap it into something headers_only = opts.var.has_key("headers_only") \ and opts.var["headers_only"] path_option = ("path" in opts.var) and opts.var["path"] xml_option = ("xml" in opts.var) and opts.var["xml"] db = DITrack.Util.common.open_db(globals, opts) # XXX: add a wrapper function to err out? try: parsed_id = DITrack.Common.Identifier(opts.fixed[1]) except ValueError: DITrack.Util.common.err( "Invalid identifier: '%s'" % opts.fixed[1], fatal=True) issue_id = parsed_id.issue.id issue = db.issue_by_id(issue_id) if parsed_id.has_comment_part(): comment_id = parsed_id.comment.id elif parsed_id.is_attachment_id(): fname = parsed_id.attachment.fname try: af = issue.get_attachment(fname) except KeyError: DITrack.Util.common.err( "No such attachment: '%s'" % fname, fatal=True ) if path_option: sys.stdout.write("%s\n" % af.path) else: sys.stdout.write(open(af.path).read()) sys.exit(0) else: if headers_only: # dt cat --headers-only 1 # is a shortcut for # dt cat --headers-only 1.0 comment_id = "0" else: comment_id = None if path_option: DITrack.Util.common.err( "Can't print a path of non-attachment: '%s'" % opts.fixed[1], fatal=True ) if xml_option: attrs = [ ("issue", issue_id) ] if comment_id is not None: attrs.append(("comment", comment_id)) if headers_only: attrs.append(("headers-only", "true")) xo = DITrack.XML.Output("cat", attrs) match = False if (comment_id is None) or (comment_id == "0"): match = True if xml_option: xo.writer.opentag("header", { "issue-id": issue_id }, nl=True) for (k, v) in issue.info.items(): xo.writer.tag_enclose(k, {}, v, nl=True, indent=2) xo.writer.closetag("header", nl=True) xo.writer.text("\n") else: sys.stdout.write("Issue: %s\n" % issue_id) issue.write_info() if not headers_only: sys.stdout.write("\n") first = True for id, comment in issue.comments(): if (comment_id is None) or (id == comment_id): match = True if xml_option: xo.writer.opentag("comment", { "id": id }, nl=True) xo.writer.opentag("header", {}, nl=True, indent=2) for (k, v) in comment.headers(): xo.writer.tag_enclose(k, {}, v, nl=True, indent=4) xo.writer.closetag("header", nl=True, indent=2) if not headers_only: xo.writer.opentag("text", {}, nl=True, indent=2) xo.writer.text(comment.text) xo.writer.closetag("text", nl=True, indent=2) xo.writer.closetag("comment", nl=True) xo.writer.text("\n") else: if not first: sys.stdout.write("Comment: %s\n" % id) comment.write( headers_only=headers_only, display_headers=( (not first) or (comment_id and (comment_id != "0")) ) ) if not headers_only: sys.stdout.write("\n") if not xml_option: if comment_id is None: sys.stdout.write("%s\n" % globals.text_delimiter) first = False if not match: DITrack.Util.common.err( "No such entity: '%s.%s'" % (issue_id, comment_id), fatal=True) if xml_option: xo.finish()