Transitioned import_xml to Command-format
[be.git] / libbe / command / comment.py
1 # Copyright (C) 2005-2009 Aaron Bentley and Panometrics, Inc.
2 #                         Gianluca Montecchi <gian@grys.it>
3 #                         W. Trevor King <wking@drexel.edu>
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License along
16 # with this program; if not, write to the Free Software Foundation, Inc.,
17 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
19 import os
20 import sys
21
22 import libbe
23 import libbe.command
24 import libbe.command.util
25 import libbe.comment
26 import libbe.ui.util.editor
27 import libbe.util.id
28
29
30 class Comment (libbe.command.Command):
31     """Add a comment to a bug
32
33     >>> import time
34     >>> import libbe.bugdir
35     >>> bd = libbe.bugdir.SimpleBugDir(memory=False)
36     >>> cmd = Comment()
37     >>> cmd._setup_io = lambda i_enc,o_enc : None
38     >>> cmd.stdout = sys.stdout
39
40     >>> cmd.run(bd.storage, bd, {'user-id':u'Fran\\xe7ois'},
41     ...         ['/a', 'This is a comment about a'])
42     >>> bd.flush_reload()
43     >>> bug = bd.bug_from_uuid('a')
44     >>> bug.load_comments(load_full=False)
45     >>> comment = bug.comment_root[0]
46     >>> comment.id.storage() == comment.uuid
47     True
48     >>> print comment.body
49     This is a comment about a
50     <BLANKLINE>
51     >>> comment.author
52     u'Fran\\xe7ois'
53     >>> comment.time <= int(time.time())
54     True
55     >>> comment.in_reply_to is None
56     True
57
58     >>> if 'EDITOR' in os.environ:
59     ...     del os.environ['EDITOR']
60     >>> cmd.run(bd.storage, bd, {'user-id':u'Frank'}, ['/b'])
61     Traceback (most recent call last):
62     UserError: No comment supplied, and EDITOR not specified.
63
64     >>> os.environ['EDITOR'] = "echo 'I like cheese' > "
65     >>> cmd.run(bd.storage, bd, {'user-id':u'Frank'}, ['/b'])
66     >>> bd.flush_reload()
67     >>> bug = bd.bug_from_uuid('b')
68     >>> bug.load_comments(load_full=False)
69     >>> comment = bug.comment_root[0]
70     >>> print comment.body
71     I like cheese
72     <BLANKLINE>
73     >>> bd.cleanup()
74     """
75     name = 'comment'
76
77     def __init__(self, *args, **kwargs):
78         libbe.command.Command.__init__(self, *args, **kwargs)
79         self.requires_bugdir = True
80         self.options.extend([
81                 libbe.command.Option(name='author', short_name='a',
82                     help='Set the comment author',
83                     arg=libbe.command.Argument(
84                         name='author', metavar='AUTHOR')),
85                 libbe.command.Option(name='alt-id',
86                     help='Set an alternate comment ID',
87                     arg=libbe.command.Argument(
88                         name='alt-id', metavar='ID')),
89                 libbe.command.Option(name='content-type', short_name='c',
90                     help='Set comment content-type (e.g. text/plain)',
91                     arg=libbe.command.Argument(name='content-type',
92                         metavar='MIME')),
93                 ])
94         self.args.extend([
95                 libbe.command.Argument(
96                     name='id', metavar='ID', default=None,
97                     completion_callback=libbe.command.util.complete_bug_comment_id),
98                 libbe.command.Argument(
99                     name='comment', metavar='COMMENT', default=None,
100                     optional=True,
101                     completion_callback=libbe.command.util.complete_assigned),
102                 ])
103
104     def _run(self, storage, bugdir, **params):
105         bug,parent = \
106             libbe.command.util.bug_comment_from_user_id(bugdir, params['id'])
107         if params['comment'] == None:
108             # try to launch an editor for comment-body entry
109             try:
110                 if parent == bug.comment_root:
111                     parent_body = bug.summary+'\n'
112                 else:
113                     parent_body = parent.body
114                 estr = 'Please enter your comment above\n\n> %s\n' \
115                     % ('\n> '.join(parent_body.splitlines()))
116                 body = libbe.ui.util.editor.editor_string(estr)
117             except libbe.ui.util.editor.CantFindEditor, e:
118                 raise libbe.command.UserError(
119                     'No comment supplied, and EDITOR not specified.')
120             if body is None:
121                 raise libbe.command.UserError('No comment entered.')
122         elif params['comment'] == '-': # read body from stdin
123             binary = not (params['content-type'] == None
124                           or params['content-type'].startswith("text/"))
125             if not binary:
126                 body = self.stdin.read()
127                 if not body.endswith('\n'):
128                     body += '\n'
129             else: # read-in without decoding
130                 body = sys.stdin.read()
131         else: # body given on command line
132             body = params['comment']
133             if not body.endswith('\n'):
134                 body+='\n'
135         if params['author'] == None:
136             params['author'] = params['user-id']
137
138         new = parent.new_reply(body=body)
139         for key in ['alt-id', 'author', 'content-type']:
140             if params[key] != None:
141                 setattr(new, key, params[key])
142
143     def _long_help(self):
144         return """
145 To add a comment to a bug, use the bug ID as the argument.  To reply
146 to another comment, specify the comment name (as shown in "be show"
147 output).  COMMENT, if specified, should be either the text of your
148 comment or "-", in which case the text will be read from stdin.  If
149 you do not specify a COMMENT, $EDITOR is used to launch an editor.  If
150 COMMENT is unspecified and EDITOR is not set, no comment will be
151 created.
152 """