From: Eric S. Raymond Date: Sun, 7 Dec 2003 04:34:01 +0000 (+0000) Subject: We're getting login. X-Git-Tag: 1-1~25 X-Git-Url: http://thyrsus.com/gitweb/?a=commitdiff_plain;h=ce17f38662be3c0097243884bf38e9757ce3f987;p=freecode-submit.git We're getting login. --- diff --git a/freshmeat-submit b/freshmeat-submit index 3027c3f..7bf7774 100755 --- a/freshmeat-submit +++ b/freshmeat-submit @@ -1,4 +1,6 @@ #!/usr/bin/env python +# +# meathook -- script transactions with the Freshmeat server import sys @@ -10,7 +12,7 @@ def error(m): if sys.version[:6] < '2.2.0': error("you must upgrade to Python 2.2.0 or better to use this script.") -import xmlrpclib, netrc +import xmlrpclib, netrc, email.Parser, optparse class FreshmeatSessionException: def __init__(self, msg): @@ -21,7 +23,8 @@ class FreshmeatSession: freshmeat_xmlrpc = "http://dev.freshmeat.net/xmlrpc/" def __init__(self, login=None, password=None, verbose=0): - "Initialize an XML-RPC session to Freshmeat by loggin in." + "Initialize an XML-RPC session to Freshmeat by logging in." + self.verbose = verbose # If user didn't supply credentials, fetch from ~/.netrc if not login: try: @@ -39,22 +42,161 @@ class FreshmeatSession: # Open xml-rpc connection to Freshmeat self.session = xmlrpclib.Server(FreshmeatSession.freshmeat_xmlrpc, verbose=verbose) - # Log in to the service - self.sid = self.session.login(login, password) + # Log in to Freshmeat + response = self.session.login( \ + {"username":login, "password":password}) + self.sid = response['SID'] + self.lifetime = response['Validity'] + if verbose: + print "Session ID = %s, lifetime = %s" % (self.sid, self.lifetime) + + def set_project(self, name): + "Set the current project." + if self.verbose: + print "About to look up project" + self.pid = self.session.lookup_project_id({'SID':self.sid,'name':name}) + if self.verbose: + print "Project ID is:", self.pid + self.branch_list = self.session.fetch_branch_list(self.sid, self.pid) + if self.verbose: + print "Project branch list is:", self.branch_list + + def add_release(self, release_info, branch=None): + "Add a new release to the current project." + if not branch and len(self.branch_list) == 1: + branch = self.branch_list.keys()[0] + if not branch: + raise FreshmeatSessionException("branch specification required") + self.session.add_release(self.sid, self.pid, branch, dir(release_info)) + + def withdraw_release(self, release): + pass def logout(self): + "End the session." return self.session.logout(self.sid) +freshmeat_field_map = ( + ("Project", "p", "project"), + ("Branch", "b", "project"), + ("Version", "v", "version"), + ("Changes", "c", "changes"), + ("Release-Focus", "r", "release_focus"), + ("Hide", "x", "hide_from_frontpage"), + ("Home-Page-URL", "H", "url_homepage"), + ("Gzipped-Tar-URL", "G", "url_tgz"), + ("Bzipped-Tar-URL", "B", "url_bz2"), + ("Zipped-Tar-URL", "Z", "url_zip"), + ("RPM-URL", "R", "url_rom"), + ("Debian-URL", "D", "url_deb"), + ("OSX-URL", "O", "url_osx"), + ("BSD-Port-URL", "P", "url_bsdport"), + ("Purchase-URL", "U", "url_purchase"), + ("CVS-URL", "C", "url_cvs"), + ("Mailing-List-URL", "L", "url_list"), + ("Mirror-Site-URL", "M", "url_mirror"), + ("Demo-URL", "E", "url_demo"), + ) + +class FreshmeatMetadata: + "Complete release information for a project/branch pair." + # Member names are identical to the XML-RPC structure members + # for an add_release request. + def __init__(self): + self.version = None # Version string of new release + self.changes = None # Changes list of new release + self.release_focus = None # Release focus ID of new release + self.hide_from_frontpage = None # 'Y' if release is to be hidden + self.url_homepage = None # Homepage + self.url_tgz = None # Tar/GZ + self.url_bz2 = None # Tar/BZ2 + self.url_zip = None # Zip + self.url_changelog = None # Changelog + self.url_rpm = None # RPM package + self.url_deb = None # Debian package + self.url_osx = None # OS X package + self.url_bsdport = None # BSD Ports URL + self.url_purchase = None # Purchase + self.url_cvs = None # CVS tree (cvsweb) + self.url_list = None # Mailing list archive + self.url_mirror = None # Mirror site + self.url_demo = None # Demo site + + def field_to_header(hdr): + hdr = "-".join(map(lambda x: x.capitalize(), hdr.split("_"))) + for (alias, shortopt, name) in field_map: + if hdr == name: + hdr = alias + break + return hdr + + def __repr__(self): + res = "" + return res + +class FreshmeatMetadataFactory: + "Factory class for producing Metadata records" + + def __init__(self): + self.message_parser = email.Parser.Parser() + self.argument_parser = optparse.OptionParser( \ + usage="usage: %prog [options]") + for (msg_field, shortopt, rpc_field) in freshmeat_field_map: + self.argument_parser.add_option("-" + shortopt, + "--" + msg_field.lower(), + dest=rpc_field, + help="Set the %s field"%msg_field) + self.argument_parser.add_option('-n', '--no-stdin', dest='read', + default=True, action='store_false', + help='Suppress reading fields from stdin.') + self.argument_parser.add_option('-V', '--verbose', dest='verbose', + default=True, action='store_false', + help='Enable verbose debugging.') + + def header_to_field(self, hdr): + hdr = hdr.lower().replace("-", "_") + for (alias, shortopt, name) in freshmeat_field_map: + if hdr == alias.lower().replace("-", "_"): + hdr = name + break + return hdr + + def getMetadata(self, stream): + "Make a Metadata object." + data = {} + (options, args) = self.argument_parser.parse_args() + if options.read: + message = self.message_parser.parse(stream) + for (key, value) in message.items(): + data.update({self.header_to_field(key) : value}) + if not 'comment' in data: + data['comment'] = message.get_payload() + self.verbose = options.verbose + + # Merge in options from the command line; + # they override what's on stdin. + data['verbose'] = False + for (key, value) in options.__dict__.items(): + if key not in ('read', 'verbose') and value != None: + data[key] = value + return data if __name__ == "__main__": + # First, gather update data from stdin and command-line switches + factory = FreshmeatMetadataFactory() + data = factory.getMetadata(sys.stdin) try: - session = FreshmeatSession() + # Establish session + session = FreshmeatSession(data['verbose']) + # Connect with the appropriate project + session.set_project(data['project']) except FreshmeatSessionException, e: print "meathook:", e.msg sys.exit(1) except xmlrpclib.Fault, f: - print "meathook: %d, %s" % (f.faultCode, f.faultString) + print "meathook: %d %s" % (f.faultCode, f.faultString) sys.exit(1) + # end