X-Git-Url: https://git.ozlabs.org/?a=blobdiff_plain;f=apps%2Fpatchwork%2Fbin%2Fpwclient;h=dba68fb036b1b28c9351548f6cf142b770238ccb;hb=ad4715cef72910b1310d4b93a2294ace878b0b4a;hp=5b2c2daf2090cd36381722762c02fa2a0d60ae92;hpb=c3b440bc54591f9f64ae8ffa73a6c161d6976eb1;p=patchwork diff --git a/apps/patchwork/bin/pwclient b/apps/patchwork/bin/pwclient index 5b2c2da..dba68fb 100755 --- a/apps/patchwork/bin/pwclient +++ b/apps/patchwork/bin/pwclient @@ -79,12 +79,13 @@ class Filter: """Return human-readable description of the filter.""" return str(self.d) -class BasicHTTPAuthTransport(xmlrpclib.Transport): +class BasicHTTPAuthTransport(xmlrpclib.SafeTransport): - def __init__(self, username = None, password = None): + def __init__(self, username = None, password = None, use_https = False): self.username = username self.password = password - xmlrpclib.Transport.__init__(self) + self.use_https = use_https + xmlrpclib.SafeTransport.__init__(self) def authenticated(self): return self.username != None and self.password != None @@ -97,6 +98,13 @@ class BasicHTTPAuthTransport(xmlrpclib.Transport): auth = 'Basic ' + base64.encodestring(credentials).strip() connection.putheader('Authorization', auth) + def make_connection(self, host): + if self.use_https: + fn = xmlrpclib.SafeTransport.make_connection + else: + fn = xmlrpclib.Transport.make_connection + return fn(self, host) + def usage(): sys.stderr.write("Usage: %s [options]\n\n" % \ (os.path.basename(sys.argv[0]))) @@ -119,17 +127,18 @@ def usage(): -w : Filter by submitter (name, e-mail substring search) -d : Filter by delegate (name, e-mail substring search) -n : Restrict number of results\n""") + sys.stderr.write("""\nActions that take an ID argument can also be \ +invoked with: + -h : Lookup by patch hash\n""") sys.exit(1) def project_id_by_name(rpc, linkname): """Given a project short name, look up the Project ID.""" if len(linkname) == 0: return 0 - # The search requires - instead of _ - search = linkname.replace("_", "-") - projects = rpc.project_list(search, 0) + projects = rpc.project_list(linkname, 0) for project in projects: - if project['linkname'].replace("_", "-") == search: + if project['linkname'] == linkname: return project['id'] return 0 @@ -170,7 +179,8 @@ def action_list(rpc, filter, submitter_str, delegate_str): for id in ids: person = rpc.person_get(id) print "Patches submitted by %s <%s>:" % \ - (person['name'], person['email']) + (unicode(person['name']).encode("utf-8"), \ + unicode(person['email']).encode("utf-8")) f = filter f.add("submitter_id", id) patches = rpc.patch_list(f.d) @@ -202,7 +212,7 @@ def action_projects(rpc): print("%-5s %-24s %s" % ("--", "----", "-----------")) for project in projects: print("%-5d %-24s %s" % (project['id'], \ - project['linkname'].replace("_", "-"), \ + project['linkname'], \ project['name'])) def action_states(rpc): @@ -233,7 +243,7 @@ def action_get(rpc, patch_id): sys.exit(1) try: - f.write(s) + f.write(unicode(s).encode("utf-8")) f.close() print "Saved patch to %s" % fname except: @@ -284,11 +294,24 @@ def action_update_patch(rpc, patch_id, state = None, commit = None): if not success: sys.stderr.write("Patch not updated\n") +def patch_id_from_hash(rpc, project, hash): + try: + patch = rpc.patch_get_by_project_hash(project, hash) + except xmlrpclib.Fault: + # the server may not have the newer patch_get_by_project_hash function, + # so fall back to hash-only. + patch = rpc.patch_get_by_hash(hash) + + if patch == {}: + return None + + return patch['id'] + auth_actions = ['update'] def main(): try: - opts, args = getopt.getopt(sys.argv[2:], 's:p:w:d:n:c:') + opts, args = getopt.getopt(sys.argv[2:], 's:p:w:d:n:c:h:') except getopt.GetoptError, err: print str(err) usage() @@ -305,6 +328,7 @@ def main(): project_str = "" commit_str = "" state_str = "" + hash_str = "" url = DEFAULT_URL config = ConfigParser.ConfigParser() @@ -328,6 +352,8 @@ def main(): delegate_str = value elif name == '-c': commit_str = value + elif name == '-h': + hash_str = value elif name == '-n': try: filt.add("max_count", int(value)) @@ -348,9 +374,12 @@ def main(): if config.has_option('auth', 'username') and \ config.has_option('auth', 'password'): + use_https = url.startswith('https') + transport = BasicHTTPAuthTransport( \ config.get('auth', 'username'), - config.get('auth', 'password')) + config.get('auth', 'password'), + use_https) else: sys.stderr.write(("The %s action requires authentication, " @@ -369,6 +398,14 @@ def main(): sys.stderr.write("Unable to connect to %s\n" % url) sys.exit(1) + patch_id = None + if hash_str: + patch_id = patch_id_from_hash(rpc, project_str, hash_str) + if patch_id is None: + sys.stderr.write("No patch has the hash provided\n") + sys.exit(1) + + if action == 'list' or action == 'search': if len(args) > 0: filt.add("name__icontains", args[0]) @@ -382,18 +419,18 @@ def main(): elif action == 'view': try: - patch_id = int(args[0]) + patch_id = patch_id or int(args[0]) except: sys.stderr.write("Invalid patch ID given\n") sys.exit(1) s = rpc.patch_get_mbox(patch_id) if len(s) > 0: - print s + print unicode(s).encode("utf-8") elif action == 'get' or action == 'save': try: - patch_id = int(args[0]) + patch_id = patch_id or int(args[0]) except: sys.stderr.write("Invalid patch ID given\n") sys.exit(1) @@ -402,7 +439,7 @@ def main(): elif action == 'apply': try: - patch_id = int(args[0]) + patch_id = patch_id or int(args[0]) except: sys.stderr.write("Invalid patch ID given\n") sys.exit(1) @@ -411,7 +448,7 @@ def main(): elif action == 'update': try: - patch_id = int(args[0]) + patch_id = patch_id or int(args[0]) except: sys.stderr.write("Invalid patch ID given\n") sys.exit(1)