diff --git a/NEWS b/NEWS index 0e27337e..19c1ff28 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,9 @@ 0.118: +- Obsolete "submitreq" command +- New generic "request" command: + - new "delete" request + - new "change_devel" request + - Multiple actions in one request is not yet supported by osc - support of added .changes in commit message template - make submit request listing fast by server side filtering - allow pulling of conflicting changes via "osc repairlink" diff --git a/TODO b/TODO index e1c28ccf..4ae30a69 100644 --- a/TODO +++ b/TODO @@ -58,85 +58,11 @@ MINOR: -[1] - -http://api.opensuse.org/result/Apache/SUSE_Linux_10.0/apache2/result -15:06 kurz zeit ueber 1-2 osc feature request zu reden die ich grade bekommen habe? -15:06 ja -15:06 ok -15:06 das 1. ist -15:06 osc listpackages [] -15:06 als Alias? -15:07 osc listpackages [] [] -15:07 es soll die gebauten sachen listen -15:07 ach so, rpms -15:07 quasi alle rpms/debs die da sind -15:07 und dann -15:07 mit Pfad/URL? -15:07 also praktisch den Link auf software.opesuse.org? -15:07 osc getpackage [] [] []+ -15:07 nein -15:07 im zweifel ueber API saugen -15:08 hm, waere noetig, falls ein Projekt noch nicht durchgebaut hat -15:08 jau -15:08 richi wuerde sich wirklich drueber freuen -15:08 ich weiss dass es ueber die api vom backend geht -15:09 ich weiss nur nicht ob api alles durchreicht -15:09 und leider hab ich schon ein paar sachen im api code gefunden -15:09 der falsch mit dem backend spricht :/ -15:09 ja, macht osc build auch so, eigentlich, allerdings weiss es dann die noetigen Datein aus dem buildinfo (version, release) -15:09 man kann auf dem backend alle rpms listen lassen - - - -[3] - -19:08 < Beineri> DuDE: can you add an option to "up" which moves instead overwriting a file if it has changed in the repository? -19:08 < darix> Beineri: moves? -19:08 < darix> oO -19:08 < darix> Beineri: use case? -19:09 < Beineri> darix: I want to see what changed when updating (we miss notification and history if you didn't notice). so I want to run "diff foo.myversion foo" -19:09 < darix> Beineri: we have a history? -19:09 < darix> Beineri: you should rtfm the api docs before claiming stuff!:p -19:10 < Beineri> darix: trying to turn around my words? -19:10 < darix> Beineri: no -19:10 < darix> just correcting wrong statements. -19:10 < DuDE> Beineri: doesn't sound too useful -19:10 < Beineri> darix: what's wrong with "we miss history"? -19:10 < DuDE> it's deviating too much from the normal usecase -19:10 < DuDE> which is, merging upstream changes in -19:10 < DuDE> Beineri: but I have a better idea, I think -19:11 < DuDE> Beineri: something that I miss in svn very much -19:11 < Beineri> DuDE: it still shall merge, but make a copy of my version before :-) -19:11 < darix> GET http://api.opensuse.org/source/// -19:11 < DuDE> Beineri: you mean, keep a fool.mine file in any case? -19:11 < darix> GET http://api.opensuse.org/source///?rev=1234 -19:11 < DuDE> Beineri: what I miss badly, is a command to see upstream changes -19:11 < DuDE> Beineri: such as the good old cvs status -19:12 < DuDE> Beineri: which showed the status of the files on the server -19:12 < Beineri> DuDE: status is not enough, I want to see what changed :-) -19:12 < DuDE> Beineri: I mostly want to know what I have to expect, before up'ping and merging -19:12 < DuDE> Beineri: yes, I also want to see that -19:12 < DuDE> Beineri: some kind of osc updiff -19:13 < DuDE> Beineri: would that help? -19:13 < darix> .oO( i smell nice race conditions^^ )o -19:13 < DuDE> Beineri: sorry, I just recognize that you asked for an option -19:13 < DuDE> Beineri: that's of course always an option -19:14 < DuDE> Beineri: surely -19:14 < Beineri> DuDE: that would help, yes. "my" stuff I could for now do with a wrapper :-) -19:15 < Beineri> darix: and that's how useful without osc/web-frontend support? - - - - - - 15:16 < DuDE> mt: Projekte anlegen geht nur, wenn es ein Subprojekt ist von einem Projekt wo Du Schreibrechte hast 15:16 < mt> DuDE: wofür? 15:16 < DuDE> mt: dass jeder einfach so top-level-Projekte anlegen kann, war einmal. Chaos-Reduzierung 15:17 < DuDE> mt: ueblich ist heutzutage ein Request auf opensuse-buildservice@ 15:18 < DuDE> mt: kannst Du das gleiche mal eben mit osc -H probieren? Mich wuerde mal interessieren, ob da eine sinnvollere Meldung im Body mitkommt -15:19 < DuDE> mt: mit -H muesste osc den Response-Body anzeigen. Meist ist der unerwuenscht, weil er typischerweise dank iChain hauptsaechlich Javascript-Schlonz enthaelt. 15:19 < mt> DuDE: reply: 'HTTP/1.1 403 Forbidden\r\n' 15:20 < DuDE> mt: das ist gut, dann sollte osc kein "try again" anbieten, sondern die Meldung rueberbringen diff --git a/osc/commandline.py b/osc/commandline.py index 23b81873..08e78703 100755 --- a/osc/commandline.py +++ b/osc/commandline.py @@ -486,58 +486,25 @@ class Osc(cmdln.Cmdln): help='only show requests created by yourself') @cmdln.alias("sr") @cmdln.alias("submitrequest") + @cmdln.hide(1) def do_submitreq(self, subcmd, opts, *args): """${cmd_name}: Handle requests to submit a package into another project [See http://en.opensuse.org/Build_Service/Collaboration for information on this topic.] - For "create", there are two ways to use it. Either with a working copy - or without. If called with no arguments, osc will guess what to submit - where. If you don't have a working copy, you can give the respective - arguments on the command line (see below for an example). - Then, the DESTPAC name is optional; the source packages' name will be - used if DESTPAC is omitted. - With --message, a message can be attached. - With --revision, a revision MD5 of a package can be specified which is - to be submitted. The default is to request submission of the currently - checked in revision. - - "list" lists open requests attached to a project or package. - - "log" will show the history of the given ID - - "show" will show the request itself, and generate a diff for review, if - used with the --diff option. - - "decline" will change the request state to "declined" and append a - message that you specify with the --message option. - - "delete" will permanently delete a request and append a - message that you specify with the --message option. - - "revoke" will set the request state to "revoked" and append a - message that you specify with the --message option. - - "accept" will change the request state to "accepted" and will trigger - the actual submit process. That would normally be a server-side copy of - the source package to the target package. - - - usage: - osc submitreq create [-m TEXT] - osc submitreq create [-m TEXT] DESTPRJ [DESTPKG] - osc submitreq create [-m TEXT] SOURCEPRJ SOURCEPKG DESTPRJ [DESTPKG] - osc submitreq list [-M] [PRJ [PKG]] - osc submitreq log ID - osc submitreq show [-d] [-b] ID - osc submitreq accept [-m TEXT] ID - osc submitreq decline [-m TEXT] ID - osc submitreq delete [-m TEXT] ID - osc submitreq revoke [-m TEXT] ID - ${cmd_option_list} + ************************************************************************* + WARNING: the "submitreq" command is about to become obsolete. Please use + the "request" command instead ! + ************************************************************************* """ + print """ + ************************************************************************* + WARNING: the "submitreq" command is about to become obsolete. Please use + the "request" command instead ! + ************************************************************************* + """ args = slash_split(args) cmds = ['create', 'list', 'log', 'show', 'decline', 'accept', 'delete', 'revoke'] @@ -639,23 +606,25 @@ of the package %s primarily takes place. Please submit there instead, or use --nodevelproject to force direct submission.""" \ % (devloc, dst_package) sys.exit(1) - reqs = get_submit_request_list(apiurl, dst_project, dst_package) + reqs = get_request_list(apiurl, dst_project, dst_package) user = conf.get_apiurl_usr(apiurl) myreqs = [ i for i in reqs if i.state.who == user ] repl = '' if len(myreqs) > 0: - print 'You already created the following submitrequests: %s.' % \ + print 'You already created the following requests: %s.' % \ ', '.join([str(i.reqid) for i in myreqs ]) repl = raw_input('Revoke the old requests? (y/N) ') + # since we have no support in the cli to specify different action types yet + # the default is a submit action result = create_submit_request(apiurl, - src_project, src_package, - dst_project, dst_package, - opts.message, orev=opts.revision) + src_project, src_package, + dst_project, dst_package, + opts.message, orev=opts.revision) if repl == 'y': for req in myreqs: - change_submit_request_state(apiurl, str(req.reqid), 'revoked', - 'superseded by %s' % result) + change_request_state(apiurl, str(req.reqid), 'revoked', + 'superseded by %s' % result) print 'created request id', result @@ -667,8 +636,8 @@ Please submit there instead, or use --nodevelproject to force direct submission. if opts.mine: who = conf.get_apiurl_usr(apiurl) - results = get_submit_request_list(apiurl, - project, package, who, state_list) + results = get_request_list(apiurl, + project, package, who, state_list) results.sort(reverse=True) @@ -676,13 +645,13 @@ Please submit there instead, or use --nodevelproject to force direct submission. print result.list_view() elif cmd == 'log': - for l in get_submit_request_log(conf.config['apiurl'], reqid): + for l in get_request_log(conf.config['apiurl'], reqid): print l # show elif cmd == 'show': - r = get_submit_request(conf.config['apiurl'], reqid) + r = get_request(conf.config['apiurl'], reqid) if opts.brief: print r.list_view() else: @@ -691,8 +660,8 @@ Please submit there instead, or use --nodevelproject to force direct submission. if opts.diff: try: print server_diff(conf.config['apiurl'], - r.dst_project, r.dst_package, None, - r.src_project, r.src_package, r.src_rev, opts.unified) + r.actions[0].dst_project, r.actions[0].dst_package, None, + r.actions[0].src_project, r.actions[0].src_package, r.actions[0].src_rev, opts.unified) except urllib2.HTTPError, e: e.osc_msg = 'Diff not possible' raise @@ -700,23 +669,300 @@ Please submit there instead, or use --nodevelproject to force direct submission. # decline elif cmd == 'decline': - r = change_submit_request_state(conf.config['apiurl'], + r = change_request_state(conf.config['apiurl'], reqid, 'declined', opts.message or '') print r # accept elif cmd == 'accept': - r = change_submit_request_state(conf.config['apiurl'], + r = change_request_state(conf.config['apiurl'], reqid, 'accepted', opts.message or '') print r # delete elif cmd == 'delete': - r = change_submit_request_state(conf.config['apiurl'], + r = change_request_state(conf.config['apiurl'], reqid, 'deleted', opts.message or '') print r # revoke elif cmd == 'revoke': - r = change_submit_request_state(conf.config['apiurl'], + r = change_request_state(conf.config['apiurl'], + reqid, 'revoked', opts.message or '') + print r + + + @cmdln.option('-d', '--diff', action='store_true', + help='generate a diff') + @cmdln.option('-u', '--unified', action='store_true', + help='output the diff in the unified diff format') + @cmdln.option('-m', '--message', metavar='TEXT', + help='specify message TEXT') + @cmdln.option('-r', '--revision', metavar='REV', + help='for "create", specify a certain source revision ID (the md5 sum)') + @cmdln.option('--nodevelproject', action='store_true', + help='do not follow a defined devel project ' \ + '(primary project where a package is developed)') + @cmdln.option('-s', '--state', default='new', + help='only list requests in one of the comma separated given states [default=new]') + @cmdln.option('-b', '--brief', action='store_true', default=False, + help='print output in list view as list subcommand') + @cmdln.option('-M', '--mine', action='store_true', + help='only show requests created by yourself') + @cmdln.alias("rq") + def do_request(self, subcmd, opts, *args): + """${cmd_name}: Handle requests to another project + + [See http://en.opensuse.org/Build_Service/Collaboration for information + on this topic.] + + For "submit", there are two ways to use it. Either with a working copy + or without. If called with no arguments, osc will guess what to submit + where. If you don't have a working copy, you can give the respective + arguments on the command line (see below for an example). + Then, the DESTPAC name is optional; the source packages' name will be + used if DESTPAC is omitted. + With --message, a message can be attached. + With --revision, a revision MD5 of a package can be specified which is + to be submitted. The default is to request submission of the currently + checked in revision. + + "list" lists open requests attached to a project or package. + + "log" will show the history of the given ID + + "show" will show the request itself, and generate a diff for review, if + used with the --diff option. + + "decline" will change the request state to "declined" and append a + message that you specify with the --message option. + + "delete" will permanently delete a request and append a + message that you specify with the --message option. + + "revoke" will set the request state to "revoked" and append a + message that you specify with the --message option. + + "accept" will change the request state to "accepted" and will trigger + the actual submit process. That would normally be a server-side copy of + the source package to the target package. + + + usage: + osc request submit [-m TEXT] + osc request submit [-m TEXT] DESTPRJ [DESTPKG] + osc request submit [-m TEXT] SOURCEPRJ SOURCEPKG DESTPRJ [DESTPKG] + osc request list [-M] [PRJ [PKG]] + osc request log ID + osc request show [-d] [-b] ID + osc request accept [-m TEXT] ID + osc request decline [-m TEXT] ID + osc request revoke [-m TEXT] ID + osc request delete [-m TEXT] DESTPRJ [DESTPKG] + osc request change_devel [-m TEXT] PROJECT PACKAGE DEVEL_PROJECT [DEVEL_PACKAGE] + ${cmd_option_list} + """ + + args = slash_split(args) + + cmds = ['submit', 'list', 'log', 'show', 'decline', 'accept', 'delete', 'revoke', 'change_devel'] + if not args or args[0] not in cmds: + raise oscerr.WrongArgs('Unknown request action. Choose one of %s.' \ + % ', '.join(cmds)) + + cmd = args[0] + del args[0] + + if cmd in ['submit']: + min_args, max_args = 0, 4 + elif cmd in ['delete']: + min_args, max_args = 1, 2 + elif cmd in ['change_devel']: + min_args, max_args = 3, 4 + elif cmd in ['list']: + min_args, max_args = 0, 2 + else: + min_args, max_args = 1, 1 + if len(args) < min_args: + raise oscerr.WrongArgs('Too few arguments.') + if len(args) > max_args: + raise oscerr.WrongArgs('Too many arguments.') + + apiurl = conf.config['apiurl'] + + # collect specific arguments + if cmd == 'submit': + if len(args) <= 2: + # try using the working copy at hand + p = findpacs(os.curdir)[0] + src_project = p.prjname + src_package = p.name + if len(args) == 0 and p.islink(): + dst_project = p.linkinfo.project + dst_package = p.linkinfo.package + apiurl = p.apiurl + elif len(args) > 0: + dst_project = args[0] + if len(args) == 2: + dst_package = args[1] + else: + dst_package = src_package + else: + sys.exit('Package \'%s\' is not a source link, so I cannot guess the submit target.\n' + 'Please provide it the target via commandline arguments.' % p.name) + + modified = [i for i in p.filenamelist if p.status(i) != ' ' and p.status(i) != '?'] + if len(modified) > 0: + print 'Your working copy has local modifications.' + repl = raw_input('Proceed without committing the local changes? (y|N) ') + if repl != 'y': + sys.exit(1) + elif len(args) >= 3: + # get the arguments from the commandline + src_project, src_package, dst_project = args[0:3] + if len(args) == 4: + dst_package = args[3] + else: + dst_package = src_package + else: + raise oscerr.WrongArgs('Incorrect number of arguments.\n\n' \ + + self.get_cmd_help('request')) + + elif cmd == 'list': + package = None + project = None + if len(args) > 0: + project = args[0] + elif not opts.mine: + project = store_read_project(os.curdir) + apiurl = store_read_apiurl(os.curdir) + try: + package = store_read_package(os.curdir) + except oscerr.NoWorkingCopy: + pass + + if len(args) > 1: + package = args[1] + elif cmd in ['log', 'show', 'decline', 'accept', 'delete', 'revoke']: + reqid = args[0] + + + # create submit request + if cmd == 'submit': + if not opts.nodevelproject: + devloc = None + try: + devloc = show_develproject(apiurl, dst_project, dst_package) + except urllib2.HTTPError: + print >>sys.stderr, """\ +Warning: failed to fetch meta data for '%s' package '%s' (new package?) """ \ + % (dst_project, dst_package) + pass + + if devloc \ + and dst_project != devloc \ + and src_project != devloc: + print """\ +Sorry, but a different project, %s, is defined as the place where development +of the package %s primarily takes place. +Please submit there instead, or use --nodevelproject to force direct submission.""" \ + % (devloc, dst_package) + sys.exit(1) + reqs = get_request_list(apiurl, dst_project, dst_package) + user = conf.get_apiurl_usr(apiurl) + myreqs = [ i for i in reqs if i.state.who == user ] + repl = '' + if len(myreqs) > 0: + print 'You already created the following submit request: %s.' % \ + ', '.join([str(i.reqid) for i in myreqs ]) + repl = raw_input('Revoke the old requests? (y/N) ') + + # since we have no support in the cli to specify different action types yet + # the default is a submit action + result = create_submit_request(apiurl, + src_project, src_package, + dst_project, dst_package, + opts.message, orev=opts.revision) + if repl == 'y': + for req in myreqs: + change_request_state(apiurl, str(req.reqid), 'revoked', + 'superseded by %s' % result) + + print 'created request id', result + + # create delete request + elif cmd == 'delete': + project = args[0] + package = None + if len(args) > 1: + package = args[1] + result = create_delete_request(apiurl, project, package, opts.message) + print result + + # request to change devel project + elif cmd == 'change_devel': + devel_project = args[2] + project = args[0] + package = args[1] + devel_package = package + if len(args) > 3: + devel_package = args[3] + result = create_change_devel_request(apiurl, + devel_project, devel_package, + project, package, + opts.message) + print result + + # list + elif cmd == 'list': + state_list = opts.state.split(',') + who = '' + if opts.mine: + who = conf.get_apiurl_usr(apiurl) + + results = get_request_list(apiurl, + project, package, who, state_list) + + results.sort(reverse=True) + + for result in results: + print result.list_view() + + elif cmd == 'log': + for l in get_request_log(conf.config['apiurl'], reqid): + print l + + + # show + elif cmd == 'show': + r = get_request(conf.config['apiurl'], reqid) + if opts.brief: + print r.list_view() + else: + print r + # fixme: will inevitably fail if the given target doesn't exist + if opts.diff: + try: + print server_diff(conf.config['apiurl'], + r.actions[0].dst_project, r.actions[0].dst_package, None, + r.actions[0].src_project, r.actions[0].src_package, r.actions[0].src_rev, opts.unified) + except urllib2.HTTPError, e: + e.osc_msg = 'Diff not possible' + raise + + + # decline + elif cmd == 'decline': + r = change_request_state(conf.config['apiurl'], + reqid, 'declined', opts.message or '') + print r + + # accept + elif cmd == 'accept': + r = change_request_state(conf.config['apiurl'], + reqid, 'accepted', opts.message or '') + print r + # revoke + elif cmd == 'revoke': + r = change_request_state(conf.config['apiurl'], reqid, 'revoked', opts.message or '') print r @@ -727,6 +973,7 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.alias("createpac") @cmdln.alias("edituser") @cmdln.alias("usermeta") + @cmdln.hide(1) def do_editmeta(self, subcmd, opts, *args): """${cmd_name}: diff --git a/osc/core.py b/osc/core.py index 9e4ffe7a..696b8dc9 100755 --- a/osc/core.py +++ b/osc/core.py @@ -1231,9 +1231,18 @@ class RequestState: self.when = when self.comment = comment +class Action: + """represents an action""" + def __init__(self, type, src_project, src_package, src_rev, dst_project, dst_package): + self.type = type + self.src_project = src_project + self.src_package = src_package + self.src_rev = src_rev + self.dst_project = dst_project + self.dst_package = dst_package -class SubmitReq: - """represent a submit request and holds its metadata +class Request: + """represent a request and holds its metadata it has methods to read in metadata from xml, different views, ...""" def __init__(self): @@ -1242,26 +1251,30 @@ class SubmitReq: self.who = None self.when = None self.last_author = None - self.src_project = None - self.src_package = None - self.src_rev = None - self.dst_project = None - self.dst_package = None self.descr = None + self.actions = [] self.statehistory = [] def read(self, root): self.reqid = int(root.get('id')) + actions = root.findall('action') + if len(actions) == 0: + actions = [ root.find('submit') ] # for old style requests - n = root.find('submit').find('source') - self.src_project = n.get('project') - self.src_package = n.get('package') - try: self.src_rev = n.get('rev') - except: pass - - n = root.find('submit').find('target') - self.dst_project = n.get('project') - self.dst_package = n.get('package') + for action in actions: + type = action.get('type', 'submit') + try: + n = action.find('source') + src_prj = n.get('project') + src_pkg = n.get('package') + src_rev = n.get('rev', None) + n = action.find('target') + dst_prj = n.get('project') + dst_pkg = n.get('package') + self.add_action(type, src_prj, src_pkg, src_rev, dst_prj, dst_pkg) + except: + msg = 'invalid request format:\n%s' % ET.tostring(root) + raise oscerr.APIError(msg) # read the state n = root.find('state') @@ -1292,11 +1305,15 @@ class SubmitReq: except: pass + def add_action(self, type, src_prj, src_pkg, src_rev, dst_prj, dst_pkg): + self.actions.append(Action(type, src_prj, src_pkg, src_rev, + dst_prj, dst_pkg) + ) def list_view(self): - dst = "%s/%s" % (self.dst_project, self.dst_package) - if self.src_package == self.dst_package: - dst = self.dst_project + dst = "%s/%s" % (self.actions[0].dst_project, self.actions[0].dst_package) + if self.actions[0].src_package == self.actions[0].dst_package: + dst = self.actions[0].dst_project desc = "" if self.descr: @@ -1305,15 +1322,16 @@ class SubmitReq: return '%6d %-7s %-12s %-50s -> %-20s %s' % \ (self.reqid, self.state.name, "(%s)" % self.state.who, - "%s/%s" % (self.src_project, self.src_package), + "%s/%s" % (self.actions[0].src_project, self.actions[0].src_package), dst, desc) def __cmp__(self, other): return cmp(self.reqid, other.reqid) def __str__(self): + # XXX: only prints out the first action element s = """\ -Request to submit (sri%d): +Request to %s (sri%s): %s/%s -> %s/%s @@ -1325,12 +1343,13 @@ Message: State: %-10s %s %s Comment: %s -""" % (self.reqid, - self.src_project, - self.src_package, - self.dst_project, - self.dst_package, - self.src_rev or 'not given', +""" % (self.actions[0].type, + self.reqid, + self.actions[0].src_project, + self.actions[0].src_package, + self.actions[0].dst_project, + self.actions[0].dst_package, + self.actions[0].src_rev or 'not given', self.descr, self.state.name, self.state.when, self.state.who, self.state.comment) @@ -2022,21 +2041,68 @@ def edit_message(footer='', template=''): pass +def create_delete_request(apiurl, project, package, message): + + import cgi + + if package: + package = """package="%s" """ % (package) + else: + package = "" + + xml = """\ + + + + + + %s + +""" % (project, package, + cgi.escape(message or '')) + + u = makeurl(apiurl, ['request'], query='cmd=create') + f = http_POST(u, data=xml) + + root = ET.parse(f).getroot() + return root.get('id') + + +def create_change_devel_request(apiurl, + devel_project, devel_package, + project, package, + message): + + import cgi + xml = """\ + + + + + + + %s + +""" % (devel_project, + devel_package, + project, + package, + cgi.escape(message or '')) + + u = makeurl(apiurl, ['request'], query='cmd=create') + f = http_POST(u, data=xml) + + root = ET.parse(f).getroot() + return root.get('id') + + def create_submit_request(apiurl, src_project, src_package, dst_project, dst_package, message, orev=None): import cgi - - r = SubmitReq() - r.src_project = src_project - r.src_package = src_package - r.src_rev = orev or show_upstream_rev(apiurl, src_project, src_package) - r.dst_project = dst_project - r.dst_package = dst_package - r.descr = cgi.escape(message or '') - + # XXX: keep the old template for now in order to work with old obs instances xml = """\ @@ -2046,12 +2112,12 @@ def create_submit_request(apiurl, %s -""" % (r.src_project, - r.src_package, - r.src_rev, - r.dst_project, - r.dst_package, - r.descr) +""" % (src_project, + src_package, + orev or show_upstream_rev(apiurl, src_project, src_package), + dst_project, + dst_package, + cgi.escape(message or '')) u = makeurl(apiurl, ['request'], query='cmd=create') f = http_POST(u, data=xml) @@ -2060,17 +2126,17 @@ def create_submit_request(apiurl, return root.get('id') -def get_submit_request(apiurl, reqid): +def get_request(apiurl, reqid): u = makeurl(apiurl, ['request', reqid]) f = http_GET(u) root = ET.parse(f).getroot() - r = SubmitReq() + r = Request() r.read(root) return r -def change_submit_request_state(apiurl, reqid, newstate, message=''): +def change_request_state(apiurl, reqid, newstate, message=''): u = makeurl(apiurl, ['request', reqid], query={'cmd': 'changestate', 'newstate': newstate}) @@ -2078,40 +2144,43 @@ def change_submit_request_state(apiurl, reqid, newstate, message=''): return f.read() -def get_submit_request_list(apiurl, project, package, req_who='', req_state=('new',) ): - match = '' - if project: - if len(match): match += '%20and%20' - match += 'submit/target/@project=\'%s\'' % quote_plus(project) - if package: - if len(match): match += '%20and%20' - match += 'submit/target/@package=\'%s\'' % quote_plus(package) - for state in req_state: - if len(match): match += '%20and%20' - match += 'state/@name=\'%s\'' % quote_plus(state) - if req_who: - if len(match): match += '%20and%20' - match += 'state/@who=\'%s\'' % quote_plus(req_who) - - u = makeurl(apiurl, ['search', 'request'], ['match=%s' % match]) - f = http_GET(u) - collection = ET.parse(f).getroot() - +def get_request_list(apiurl, project, package, req_who='', req_state=('new',) ): requests = [] - for root in collection.findall('request'): - r = SubmitReq() - r.read(root) - if (r.state.name in req_state) or not len(req_state): - requests.append(r) + # XXX: we cannot use the '|' in the xpath expression because it is not supported + # in the backend + for what in ['action', 'submit']: + match = '' + if project: + if len(match): match += '%20and%20' + match += '%s/target/@project=\'%s\'' % (what, quote_plus(project)) + if package: + if len(match): match += '%20and%20' + match += '%s/target/@package=\'%s\'' % (what, quote_plus(package)) + for state in req_state: + if len(match): match += '%20and%20' + match += 'state/@name=\'%s\'' % quote_plus(state) + if req_who: + if len(match): match += '%20and%20' + match += 'state/@who=\'%s\'' % quote_plus(req_who) + + u = makeurl(apiurl, ['search', 'request'], ['match=%s' % match]) + f = http_GET(u) + collection = ET.parse(f).getroot() + + for root in collection.findall('request'): + r = Request() + r.read(root) + if (r.state.name in req_state) or not len(req_state): + requests.append(r) return requests -def get_submit_request_log(apiurl, reqid): - r = get_submit_request(conf.config['apiurl'], reqid) +def get_request_log(apiurl, reqid): + r = get_request(conf.config['apiurl'], reqid) data = [] frmt = '-' * 76 + '\n%s | %s | %s\n\n%s' - # the description of the submitrequest is used for the initial log entry + # the description of the request is used for the initial log entry # otherwise its comment attribute would contain None if len(r.statehistory) >= 1: r.statehistory[-1].comment = r.descr