blob: 8de129be4f4eb66eaa3a389aebaa5bc7cc569fc7 [file] [log] [blame]
Ken Mixter92a44ab2010-04-12 22:10:181# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Upload crash client ID to Issue Tracker by using Issue Tracker API.
6
7Crash client ID and release notes update to the Chromium Issue Tracker system.
8
9"""
10
11import getpass
12import httplib
13import os
14import re
15import sys
16import urllib
17
18
19# Create crash client ID and sent to "Consent To Send Stats".
20def _get_client_id():
21 if not os.path.isfile('/home/chronos/Consent To Send Stats'):
22 sys.exit('Please consent to ending stats in Chromium and rerun.')
23 else:
24 id = open('/home/chronos/Consent To Send Stats', 'r')
25 client_id = id.read()
26 return client_id
27
28# Get sender's login credentials.
29def _get_credential():
30 valid_email = False
31 while not valid_email:
32 email = raw_input('Enter your email : ')
33 # Allowing user to use these email domains
34 email_domain = re.compile(r'(@chromium.org|@google.com|@gmail.com)$')
35 valid_email = (email_domain.search(email))
36 if not valid_email:
37 print 'Please check email address, and try again'
38 pwd = getpass.getpass('Enter your password : ')
39 return email, pwd
40
41# Get bug ID corresponding to the crashing report.
42def _get_bug_id():
43 valid_number = False
44 while not valid_number:
45 print ('You are about to publish crashing client ID and lsb-release '
46 'info to this bug')
47 bug_id = raw_input('Enter bug id that you would like to update : ')
48 valid_number = re.match(r'^\d+$', bug_id) is not None
49 # TODO(tturchetto): Verify bug number is in the chrome OS database.
50 return int(bug_id)
51
52# Get lsb_release information from the crashed system.
53def _get_lsb_release():
54 lsb_info = open('/etc/lsb-release', 'r')
55 lsb_release = lsb_info.read()
56 return lsb_release
57
58# Get authetication token to access code.google.com
59def _get_auth_token(email, pwd):
60 google_login_host = 'google.com:443'
61 client_login_url = '/accounts/ClientLogin'
62 login_values = {
63 'Email': email,
64 'Passwd': pwd,
65 'accountType': 'GOOGLE',
66 'service': 'code',
67 'source': 'google-crash_uploader-1.0'
68 }
69
70 params = urllib.urlencode(login_values)
71 headers = {
72 'Content-type': 'application/x-www-form-urlencoded',
73 'Accept': 'text/plain'
74 }
75
76 conn = httplib.HTTPSConnection(google_login_host)
77 # Send the request
78 conn.request('POST', client_login_url, params, headers)
79 response = conn.getresponse()
80 response_data = response.read()
81 error_code = response.status
82 # 200 is expected response status
83 if 200 == response.status:
84 body = response_data.split('\n')
85 for line in body:
86 if re.match('Auth=', line):
87 token = line.split('=')[1]
88 return token
89 if 403 == response.status:
90 sys.exit('Error: unsupported standard parameter, or authentication'
91 'or authorization failed.')
92
93# Create the XML string to be sent as data.
94def _create_xml(client_id, lsb_release, email):
95 # Create the XML string to be sent as data.
96 issue_tracker_xml = (
97 '<?xml version="1.0" encoding="UTF-8"?>\n'
98 ' <entry xmlns="http://www.w3.org/2005/Atom" '
99 'xmlns:issues="http://schemas.google.com/projecthosting/issues/2009">\n'
100 ' <content type="html">crashing report client ID: "%(client_id)s "\n'
101 'lsb_release is\n" %(lsb_release)s"\n'
102 ' </content>\n'
103 ' <author>\n'
104 ' <name>"%(author)s"</name>\n'
105 ' </author>\n'
106 ' <issues:updates>\n'
107 ' </issues:updates>\n'
108 '</entry>\n'
109 )
110
111 issue_tracker_xml = issue_tracker_xml % {
112 'author' : email,
113 'client_id' : client_id,
114 'lsb_release' : lsb_release
115 }
116 return issue_tracker_xml
117
118# Comment information to the bug.
119def _update_bug(email, bug_id, token, issue_tracker_xml):
120 """Updates the bug.
121 Args:
122 email: An user email to access the Issue Tracker.
123 bug_id: Bug ID that user want to update.
124 token: Authenticated ClientLogin token to access issue tracker
125 issue_tracker_xml: Project hosting on Google Code uses xml entry to updates
126 bug
127 """
128
129 # Get headers.
130 headers = {'Content-type': 'application/atom+xml',
131 'Accept': 'text/plain',
132 'Authorization': 'GoogleLogin auth=' + token}
133 conn = httplib.HTTPConnection('code.google.com:80')
134 google_login_host = 'google.com:443'
135 issue_update_url = \
136 '/feeds/issues/p/chromium-os/issues/%s/comments/full' % ( bug_id )
137 # Send the request
138 conn.request("POST", issue_update_url, issue_tracker_xml, headers)
139 response = conn.getresponse()
140 conn.set_debuglevel(1)
141 data = response.read()
142 conn.close()
143 # 201 is expected response status
144 if 201 == response.status:
145 print ('%s updated bug # %s successfully.' % ( email, bug_id ))
146 else:
147 print ('Your update is not successful posted on the bug # %s' % ( bug_id ))
148
149def main():
150 os.system('clear')
151 client_id = _get_client_id()
152 (email, password) = _get_credential()
153 lsb_release = _get_lsb_release()
154 token = _get_auth_token(email, password)
155 bug_id = _get_bug_id()
156 xml = _create_xml(client_id, lsb_release, email)
157 _update_bug(email, bug_id, token, xml)
158
159if __name__ == '__main__':
160 main()