blob: 8de129be4f4eb66eaa3a389aebaa5bc7cc569fc7 [file] [log] [blame]
# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Upload crash client ID to Issue Tracker by using Issue Tracker API.
Crash client ID and release notes update to the Chromium Issue Tracker system.
"""
import getpass
import httplib
import os
import re
import sys
import urllib
# Create crash client ID and sent to "Consent To Send Stats".
def _get_client_id():
if not os.path.isfile('/home/chronos/Consent To Send Stats'):
sys.exit('Please consent to ending stats in Chromium and rerun.')
else:
id = open('/home/chronos/Consent To Send Stats', 'r')
client_id = id.read()
return client_id
# Get sender's login credentials.
def _get_credential():
valid_email = False
while not valid_email:
email = raw_input('Enter your email : ')
# Allowing user to use these email domains
email_domain = re.compile(r'(@chromium.org|@google.com|@gmail.com)$')
valid_email = (email_domain.search(email))
if not valid_email:
print 'Please check email address, and try again'
pwd = getpass.getpass('Enter your password : ')
return email, pwd
# Get bug ID corresponding to the crashing report.
def _get_bug_id():
valid_number = False
while not valid_number:
print ('You are about to publish crashing client ID and lsb-release '
'info to this bug')
bug_id = raw_input('Enter bug id that you would like to update : ')
valid_number = re.match(r'^\d+$', bug_id) is not None
# TODO(tturchetto): Verify bug number is in the chrome OS database.
return int(bug_id)
# Get lsb_release information from the crashed system.
def _get_lsb_release():
lsb_info = open('/etc/lsb-release', 'r')
lsb_release = lsb_info.read()
return lsb_release
# Get authetication token to access code.google.com
def _get_auth_token(email, pwd):
google_login_host = 'google.com:443'
client_login_url = '/accounts/ClientLogin'
login_values = {
'Email': email,
'Passwd': pwd,
'accountType': 'GOOGLE',
'service': 'code',
'source': 'google-crash_uploader-1.0'
}
params = urllib.urlencode(login_values)
headers = {
'Content-type': 'application/x-www-form-urlencoded',
'Accept': 'text/plain'
}
conn = httplib.HTTPSConnection(google_login_host)
# Send the request
conn.request('POST', client_login_url, params, headers)
response = conn.getresponse()
response_data = response.read()
error_code = response.status
# 200 is expected response status
if 200 == response.status:
body = response_data.split('\n')
for line in body:
if re.match('Auth=', line):
token = line.split('=')[1]
return token
if 403 == response.status:
sys.exit('Error: unsupported standard parameter, or authentication'
'or authorization failed.')
# Create the XML string to be sent as data.
def _create_xml(client_id, lsb_release, email):
# Create the XML string to be sent as data.
issue_tracker_xml = (
'<?xml version="1.0" encoding="UTF-8"?>\n'
' <entry xmlns="http://www.w3.org/2005/Atom" '
'xmlns:issues="http://schemas.google.com/projecthosting/issues/2009">\n'
' <content type="html">crashing report client ID: "%(client_id)s "\n'
'lsb_release is\n" %(lsb_release)s"\n'
' </content>\n'
' <author>\n'
' <name>"%(author)s"</name>\n'
' </author>\n'
' <issues:updates>\n'
' </issues:updates>\n'
'</entry>\n'
)
issue_tracker_xml = issue_tracker_xml % {
'author' : email,
'client_id' : client_id,
'lsb_release' : lsb_release
}
return issue_tracker_xml
# Comment information to the bug.
def _update_bug(email, bug_id, token, issue_tracker_xml):
"""Updates the bug.
Args:
email: An user email to access the Issue Tracker.
bug_id: Bug ID that user want to update.
token: Authenticated ClientLogin token to access issue tracker
issue_tracker_xml: Project hosting on Google Code uses xml entry to updates
bug
"""
# Get headers.
headers = {'Content-type': 'application/atom+xml',
'Accept': 'text/plain',
'Authorization': 'GoogleLogin auth=' + token}
conn = httplib.HTTPConnection('code.google.com:80')
google_login_host = 'google.com:443'
issue_update_url = \
'/feeds/issues/p/chromium-os/issues/%s/comments/full' % ( bug_id )
# Send the request
conn.request("POST", issue_update_url, issue_tracker_xml, headers)
response = conn.getresponse()
conn.set_debuglevel(1)
data = response.read()
conn.close()
# 201 is expected response status
if 201 == response.status:
print ('%s updated bug # %s successfully.' % ( email, bug_id ))
else:
print ('Your update is not successful posted on the bug # %s' % ( bug_id ))
def main():
os.system('clear')
client_id = _get_client_id()
(email, password) = _get_credential()
lsb_release = _get_lsb_release()
token = _get_auth_token(email, password)
bug_id = _get_bug_id()
xml = _create_xml(client_id, lsb_release, email)
_update_bug(email, bug_id, token, xml)
if __name__ == '__main__':
main()