diff --git a/dist/osc.complete b/dist/osc.complete index c4ae3ddd..bf4f6065 100755 --- a/dist/osc.complete +++ b/dist/osc.complete @@ -60,7 +60,7 @@ oscopts=(--version --help --debugger --post-mortem --traceback --http-full-debug osccmds=(abortbuild add addremove aggregatepac api ar bco bl blt branch branchco bsdevelproject bse bugowner build buildconfig buildhist buildhistory buildinfo buildlog buildlogtail cat changedevelreq changedevelrequest checkconstraints checkin checkout - chroot ci co commit config copypac cr createincident createrequest creq del + chroot ci co comment commit config copypac cr createincident createrequest creq del delete deletereq deleterequest dependson detachbranch develproject di diff distributions dists dr dropreq droprequest getbinaries getpac help importsrcpkg info init jobhist jobhistory lbl ldiff less linkdiff linkpac linktobranch list @@ -78,6 +78,8 @@ oscreq=(list log show accept decline revoke reopen setincident supersede approve checkout clone) oscrev=(show list add accept decline reopen supersede) oscmy=(work pkg prj rq sr) +osccmt=(list create delete) +osccmtkind=(package project request) oscprj="" oscpkg="" @@ -1095,6 +1097,16 @@ my) builtin compgen -W "${opts[*]}" -- "${cmdline[3]}" fi ;; +comment) + opts=(--comment --parent) + if ((count == 1)) ; then + builtin compgen -W "${osccmds[*]}" -- "${cmdline[count]}" + elif ((count == 2)) ; then + builtin compgen -W "${opts[*]} ${osccmt[*]}" -- "${cmdline[2]}" + elif ((count == 3)) ; then + builtin compgen -W "${opts[*]} ${osccmtkind[*]}" -- "${cmdline[3]}" + fi + ;; copypac|linkpac) opts=(--help --expand --to-apiurl --revision --keep-develproject --keep-link --keep-maintainers --client-side-copy) diff --git a/osc/commandline.py b/osc/commandline.py index 4b01f7d3..ee4b58a0 100644 --- a/osc/commandline.py +++ b/osc/commandline.py @@ -8737,6 +8737,73 @@ Please submit there instead, or use --nodevelproject to force direct submission. if not opts.dry_run: os.unlink(os.path.join(p.absdir, filename)) + @cmdln.option('-c', '--comment', + help='comment text', metavar='COMMENT') + @cmdln.option('-p', '--parent', + help='reply to comment with parent id', metavar='PARENT') + def do_comment(self, subcmd, opts, *args): + """${cmd_name}: List / create / delete comments + + On create: + If -p is given a reply to the ID is created. Otherwise + a toplevel comment is created. + If -c is not given the default editor will be opened and + you can type your comment + + usage: + osc comment list package PROJECT PACKAGE + osc comment list project PROJECT + osc comment list request REQUEST_ID + + osc comment create [-p PARENT_ID] [-c COMMENT] package PROJECT PACKAGE + osc comment create [-p PARENT_ID] [-c COMMENT] project PROJECT + osc comment create [-p PARENT_ID] [-c COMMENT] request REQUEST_ID + + osc comment delete ID + + """ + + comment = None + args = slash_split(args) + apiurl = self.get_api_url() + + if len(args) < 2: + raise oscerr.WrongArgs('Incorrect number of arguments.\n\n' \ + + self.get_cmd_help('comment')) + + cmds = ['list', 'create', 'delete'] + if args[0] not in cmds: + raise oscerr.WrongArgs('Unknown comment action %s. Choose one of %s.' \ + % (args[0], ', '.join(cmds))) + + comment_targets = ['package', 'project', 'request'] + if args[0] != 'delete' and args[1] not in comment_targets: + raise oscerr.WrongArgs('Unknown comment target %s. Choose one of %s.' \ + % (args[1], ', '.join(comment_targets))) + + if args[1] == 'package' and len(args) != 4: + raise oscerr.WrongArgs('Please use PROJECT PACKAGE') + elif args[1] == 'project' and len(args) != 3: + raise oscerr.WrongArgs('Please use PROJECT') + elif args[1] == 'request' and len(args) != 3: + raise oscerr.WrongArgs('Please use REQUEST') + elif args[0] == 'delete' and len(args) != 2: + raise oscerr.WrongArgs('Please use COMMENT_ID') + if not opts.comment and args[0] == 'create': + comment = edit_text() + else: + comment = opts.comment + + if args[0] == 'list': + print_comments(apiurl, args[1], *args[2:]) + elif args[0] == 'create': + result = create_comment(apiurl, args[1], comment, + *args[2:], parent=opts.parent) + print(result) + elif args[0] == 'delete': + result = delete_comment(apiurl, args[1]) + print(result) + def _load_plugins(self): plugin_dirs = [ '/usr/lib/osc-plugins', diff --git a/osc/core.py b/osc/core.py index 3242bceb..f2aeacc5 100644 --- a/osc/core.py +++ b/osc/core.py @@ -7407,26 +7407,40 @@ def which(name): return None -def get_comments(apiurl, kind, name): - url = makeurl(apiurl, ['comments', kind, name]) +def get_comments(apiurl, kind, *args): + url = makeurl(apiurl, ('comments', kind) + args) f = http_GET(url) return ET.parse(f).getroot() -def print_comments(apiurl, kind, name): +def print_comments(apiurl, kind, *args): def print_rec(comments, indent=''): for comment in comments: print(indent, end='') - print('On', comment.get('when'), comment.get('who'), 'wrote:') + print('(', comment.get('id'), ')', 'On', comment.get('when'), comment.get('who'), 'wrote:') text = indent + comment.text.replace('\r\n',' \n') print(('\n' + indent).join(text.split('\n'))) print() print_rec([c for c in root if c.get('parent') == comment.get('id')], indent + ' ') - - root = get_comments(apiurl, kind, name) + root = get_comments(apiurl, kind, *args) comments = [c for c in root if c.get('parent') is None] if comments: print('\nComments:') print_rec(comments) +def create_comment(apiurl, kind, comment, *args, **kwargs): + query = {} + if kwargs.get('parent') is not None: + query = {'parent_id': kwargs['parent']} + u = makeurl(apiurl, ('comments', kind) + args, query=query) + f = http_POST(u, data=comment) + ret = ET.fromstring(f.read()).find('summary') + return ret.text + +def delete_comment(apiurl, cid): + u = makeurl(apiurl, ['comment', cid]) + f = http_DELETE(u) + ret = ET.fromstring(f.read()).find('summary') + return ret.text + # vim: sw=4 et