Package moap :: Package publish :: Module freshmeat
[hide private]
[frames] | no frames]

Source Code for Module moap.publish.freshmeat

  1  # -*- Mode: Python -*- 
  2  # vi:si:et:sw=4:sts=4:ts=4 
  3   
  4  # routines to interface with Freshmeat through XML-RPC 
  5  # see http://freshmeat.net/faq/view/49/ 
  6  # taken from "shipper" and adapted 
  7   
  8  import xmlrpclib 
  9  import netrc 
 10   
 11  # This is how we sanity-check against the XML-RPC API version. 
 12  required_major = "1" 
 13  required_minor = "02" 
 14   
15 -class SessionException(Exception):
16 - def __init__(self, message):
17 self.message = message
18
19 - def __repr__(self):
20 return '<SessionException: %s>' % self.message
21 22 __str__ = __repr__
23
24 -class SessionError(SessionException):
25 """ 26 One of the XML-RPC errors from the Freshmeat API. 27 """
28 - def __init__(self, code, message):
29 self.code = code 30 self.message = message
31
32 - def __repr__(self):
33 return '<SessionError %d: %s>' % (self.code, self.message)
34
35 -class Session:
36 "Encapsulate the state of a Freshmeat session." 37 freshmeat_xmlrpc = "http://freshmeat.net/xmlrpc/" 38
39 - def __init__(self, login=None, password=None, verbose=0):
40 """ 41 Create an XML-RPC session to Freshmeat. 42 """ 43 self.verbose = verbose 44 self._sid = None # set to session ID if logged in 45 46 # Open xml-rpc connection to Freshmeat 47 self._session = xmlrpclib.Server(Session.freshmeat_xmlrpc, 48 verbose=verbose)
49
50 - def _assert_logged_in(self):
51 if not self._sid: 52 raise SessionException("Not logged in")
53
54 - def fetch_available_licenses(self):
55 return self._session.fetch_available_licenses()
56
57 - def login(self, login=None, password=None):
58 # If user didn't supply credentials, fetch from ~/.netrc 59 if not login: 60 try: 61 credentials = netrc.netrc() 62 except netrc.NetrcParseError, e: 63 raise SessionException("ill-formed .netrc: %s:%s %s" \ 64 % (e.filename, e.lineno, e.msg)) 65 except IOError, e: 66 raise SessionException(("missing .netrc file %s" % \ 67 str(e).split()[-1])) 68 ret = credentials.authenticators("freshmeat") 69 if not ret: 70 raise SessionException("no credentials for Freshmeat") 71 login, account, password = ret 72 73 # Log in to Freshmeat 74 response = self._session.login( \ 75 {"username":login, "password":password}) 76 self._sid = response['SID'] 77 self.lifetime = response['Lifetime'] 78 api_version = response['API Version'] 79 # Sanity-check against the version 80 (major, minor) = api_version.split(".") 81 if major != required_major or minor < required_minor: 82 raise SessionException("this version is out of date; get a replacement from Freshmeat.") 83 if self.verbose: 84 print "Session ID = %s, lifetime = %s" % (self._sid, self.lifetime)
85
86 - def fetch_branch_list(self, project_name):
87 "Get the branch list for the current project." 88 self._assert_logged_in() 89 if self.verbose: 90 print "About to look up project" 91 branch_list = self._session.fetch_branch_list({ 92 'SID': self._sid, 93 'project_name': project_name 94 }) 95 if self.verbose: 96 print "Project branch list is:", branch_list 97 return branch_list
98
99 - def fetch_release(self, project_name, branch_name, version):
100 """ 101 @returns: dict with 102 release_focus, version, changes, hide_from_frontpage 103 """ 104 self._assert_logged_in() 105 args = ({ 106 'SID': self._sid, 107 'project_name': project_name, 108 'branch_name': branch_name, 109 'version': version, 110 }) 111 112 try: 113 result = self._session.fetch_release(args) 114 except xmlrpclib.Fault, e: 115 raise SessionError(e.faultCode, e.faultString) 116 117 return result
118
119 - def publish_release(self, **data):
120 """ 121 Add a new release. 122 123 The "license" and "url_*" fields are optional and will be taken from 124 the branch record if they are omitted from the submission. The 125 'hide_from_frontpage' option can be omitted an defaults to 'do not 126 hide'. 127 128 @param project_name: Project name to submit a release for 129 @param branch_name: Branch name to submit a release for 130 @param version: Version string of new release 131 @param changes: Changes list, no HTML, 132 character limit 600 chars 133 Empty will return error code 60. 134 @param release_focus: Release focus ID of new release 135 (see Appendix A) 136 @param hide_from_frontpage: 'Y' if release is to be hidden from 137 frontpage, everything else does not hide it 138 @param license: Branch license 139 @param url_homepage: Homepage 140 @param url_tgz: Tar/GZ 141 @param url_bz2: Tar/BZ2 142 @param url_zip: Zip 143 @param url_changelog: Changelog 144 @param url_rpm: RPM package 145 @param url_deb: Debian package 146 @param url_osx: OS X package 147 @param url_bsdport: BSD Ports URL 148 @param url_purchase: Purchase 149 @param url_cvs: CVS tree (cvsweb) 150 @param url_list: Mailing list archive 151 @param url_mirror: Mirror site 152 @param url_demo: Demo site 153 """ 154 data['SID'] = self._sid 155 try: 156 response = self._session.publish_release(data) 157 except xmlrpclib.Fault, e: 158 raise SessionError(e.faultCode, e.faultString) 159 160 if "OK" not in response: 161 raise SessionException(response)
162
163 - def withdraw_release(self, release):
164 response = self._session.withdraw_release(release) 165 if "OK" not in response: 166 raise SessionException(response)
167
168 - def logout(self):
169 "End the session." 170 ret = self._session.logout({ 171 "SID": self._sid 172 }) 173 self._sid = None 174 return ret
175 176 freshmeat_field_map = ( 177 ("Project", "p", "project_name"), 178 ("Branch", "b", "branch_name"), 179 ("Version", "v", "version"), 180 ("Changes", "c", "changes"), 181 ("Release-Focus", "r", "release_focus"), 182 ("Hide", "x", "hide_from_frontpage"), 183 ("License", "l", "license"), 184 ("Home-Page-URL", "H", "url_homepage"), 185 ("Gzipped-Tar-URL", "G", "url_tgz"), 186 ("Bzipped-Tar-URL", "B", "url_bz2"), 187 ("Zipped-Tar-URL", "Z", "url_zip"), 188 ("Changelog-URL", "C", "url_changelog"), 189 ("RPM-URL", "R", "url_rpm"), 190 ("Debian-URL", "D", "url_deb"), 191 ("OSX-URL", "O", "url_osx"), 192 ("BSD-Port-URL", "P", "url_bsdport"), 193 ("Purchase-URL", "U", "url_purchase"), 194 ("CVS-URL", "S", "url_cvs"), 195 ("Mailing-List-URL", "L", "url_list"), 196 ("Mirror-Site-URL", "M", "url_mirror"), 197 ("Demo-URL", "E", "url_demo"), 198 ) 199