Package diffpy :: Package srrietveld :: Module bugreport
[frames] | no frames]

Source Code for Module diffpy.srrietveld.bugreport

  1  ############################################################################## 
  2  # 
  3  # diffpy.srrietveld by DANSE Diffraction group 
  4  #                   Simon J. L. Billinge 
  5  #                   (c) 2010 Trustees of the Columbia University 
  6  #                   in the City of New York.  All rights reserved. 
  7  # 
  8  # File coded by:    Pavol Juhas, Peng Tian 
  9  # 
 10  # See AUTHORS.txt for a list of people who contributed. 
 11  # See LICENSE.txt for license information. 
 12  # 
 13  ############################################################################## 
 14   
 15  """Routines for submitting bugreport through www.diffpy.org. 
 16  """ 
 17   
 18  # version 
 19  __id__ = "$Id: bugreport.py 6462 2011-04-02 00:41:29Z yshang $" 
 20   
 21  import urlparse 
 22  import HTMLParser 
 23  from diffpy.srrietveld.exceptions import SrrIOError, SrrValueError 
 24   
 25  # constants: 
 26   
 27  ROOT_URL = "http://www.diffpy.org/" 
 28  FORM_URL = urlparse.urljoin(ROOT_URL, "bugreport/srrietveld/") 
 29  FORM_REALM = "diffpy" 
 30  FORM_USER = "diffuser" 
 31  FORM_ENCPW = "LPR3rU9s" 
 32   
 33   
 34  # Routines 
 35   
36 -def submitBugReport(formfields):
37 """Fill in and submit bugreport form at FORM_URL. 38 The post url is obtained by parsing the first HTML form. 39 40 formfields -- dictionary containing the keys. When optional 41 fields are not specified, use defaults as listed: 42 43 "reporter" optional, ["anonymous"] 44 "summary" required 45 "description" required 46 "component" optional, ["srrietveld"] 47 "version" optional, [current version of SrRietveld] 48 "traceback" optional, [""] 49 50 All values get stripped from leading and trailing spaces. 51 Any other keys in formfields are ignored. 52 53 No return value. 54 Raise KeyError when formfields does not have required keys. 55 Raise IOError on failed posting. 56 """ 57 import urllib 58 import urllib2 59 import cookielib 60 from diffpy.srrietveld import __version__ 61 # build dictionary with default values: 62 formdata_user = { 63 "reporter" : formfields.get("reporter", "").strip() or "anonymous", 64 "summary" : formfields["summary"], 65 "description" : formfields["description"], 66 "component" : formfields.get("component", "srrietveld"), 67 "version" : formfields.get("version", __version__), 68 "traceback" : formfields.get("traceback", ""), 69 } 70 # format formdata_user items: 71 for k in formdata_user: 72 formdata_user[k] = formdata_user[k].strip() 73 if formdata_user["description"]: 74 formdata_user["description"] += "\n" 75 if formdata_user["traceback"]: 76 formdata_user["traceback"] = "\n" + formdata_user["traceback"] + "\n" 77 # open FORM_URL 78 handler = urllib2.HTTPBasicAuthHandler() 79 handler.add_password(FORM_REALM, ROOT_URL, 80 FORM_USER, FORM_ENCPW.encode('rot13')) 81 cookier = urllib2.HTTPCookieProcessor(cookielib.LWPCookieJar()) 82 opener = urllib2.build_opener(handler, cookier) 83 formcontent = opener.open(FORM_URL).read() 84 # find where does the form post its data 85 try: 86 formattr, formdata = getFormData(formcontent) 87 # invalid web form would throw ValueError, raise this as 88 # IOError so we get a meaningful error message from the gui. 89 except ValueError, err: 90 emsg = "Invalid webform - %s" % err 91 raise SrrIOError(emsg) 92 # build the formadata dictionary 93 formdata.update(formdata_user) 94 post_url = urlparse.urljoin(FORM_URL, formattr['action']) 95 post_headers = {'User-agent' : 'SrRietveld (compatible; MSIE 5.5; WindowsNT)'} 96 post_content = urllib.urlencode(formdata) 97 post_request = urllib2.Request(post_url, post_content, post_headers) 98 post_handle = opener.open(post_request) 99 # result can be obtained by post_handle.read(), but it is not needed 100 return
101 102
103 -def getFormData(content, index=0):
104 """Extract action attribute from the first form in HTML document. 105 106 content -- HTML code 107 index -- zero-based index of the form in the HTML document 108 109 Return a tuple of (formattr, formdata) dictionaries, where 110 formattr -- has all the attributes of the <form> element 111 formdata -- has all the contain input field names and their values 112 """ 113 datagetter = _HTMLFormDataGetter() 114 fmattr, fmdata = datagetter(content) 115 rv = (fmattr[index], fmdata[index]) 116 return rv
117 118 119 # Helper classes 120 121
122 -class _HTMLFormDataGetter(HTMLParser.HTMLParser):
123 """Helper HTMLParser for extracting form data attributes from 124 the first form. 125 126 Instance data: 127 128 _formattrs -- list of attribute dictionaries for all <form> tags 129 _formdata -- list of input data dictionaries from all <form> tags 130 131 See also getFormData(). 132 """ 133 134 135 # declaration of instance data attributes 136 _formattrs = None 137 _formdata = None 138 139
140 - def handle_starttag(self, tag, attrs):
141 """Store data dictionary for all HTML forms in the document. 142 """ 143 dattr = dict(attrs) 144 if tag == "form": 145 self._formattrs.append(dattr) 146 self._formdata.append({}) 147 if tag == "input" and 'name' in dattr: 148 name = dattr['name'] 149 value = dattr.get('value', '') 150 self._formdata[-1][name] = value 151 return
152 153
154 - def __call__(self, content):
155 """Return a list of data dictionaries for all HTML forms in the document. 156 157 content -- HTML code 158 159 Return two lists of dictionaries for form attributes and form data. 160 Raise ValueError for invalid HTML code or when no form is present. 161 """ 162 self.reset() 163 self._formattrs = [] 164 self._formdata = [] 165 try: 166 self.feed(content) 167 self.close() 168 except HTMLParser.HTMLParseError, err: 169 raise SrrValueError, str(err) 170 return (self._formattrs, self._formdata)
171 172 173 # End of class _HTMLFormDataGetter 174 175 176 # test code 177 178 if __name__ == "__main__": 179 import time 180 submitBugReport({ 181 "summary" : "test, do not post", 182 "description" : "posted from submitBugReport on " + time.ctime(), 183 }) 184