NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

__init__.py (5934B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\bugreporter\__init__.py
      2 from __future__ import print_function
      3 import requests
      4 from bugreporter.util import GuessMimeType
      5 import json
      6 import mimetools
      7 import logging
      8 from cStringIO import StringIO
      9 import uthread2
     10 
     11 class BugReporter(object):
     12 
     13     def __init__(self, serverUrl, cacheFolder = None):
     14         if cacheFolder is None:
     15             cacheFolder = '.cache'
     16         self.cacheFolder = cacheFolder
     17         self.logger = logging.getLogger('bugreporter')
     18         self.baseUrl = serverUrl
     19 
     20     def GetCategories(self):
     21         ret = []
     22         for each in self._HttpGet('eve/issue/categories')['categories']:
     23             ret.append((each['value'], each['id']))
     24 
     25         return ret
     26 
     27     def SendBugReport(self, categoryName, title, description, reproSteps, sessionInfo, computerInfo, userID, labels, server, build, files):
     28         data = self._GetData(categoryName, title, description, reproSteps, sessionInfo, computerInfo, userID, labels, server, build)
     29         response = self._HttpPost('eve/issue/new', data)
     30         issueID = response['id']
     31         self._SendAttachments(issueID, files)
     32         return response
     33 
     34     def IsBugsServiceOnline(self):
     35         try:
     36             return self._HttpGet('status/health')['isOnline']
     37         except KeyError:
     38             return False
     39         except Exception:
     40             self.logger.exception('Bugs service not answering IsOnline')
     41             return False
     42 
     43     def _SendAttachments(self, issueID, files):
     44         try:
     45             for fileName, fileData in files:
     46                 self._SendAttachment(issueID, fileName, fileData)
     47 
     48         except Exception as e:
     49             self.logger.exception(e)
     50             raise SendAttachmentError()
     51 
     52     def _SendAttachment(self, issueID, fileName, fileData, retries = 5):
     53         contentType, buffer = self._MultipartEncode(fileName, fileData)
     54         urlAddition = 'eve/issue/{}/attachments/add'.format(issueID)
     55         exception = None
     56         while retries > 0 or exception is None:
     57             try:
     58                 self._Request(urlAddition, 'POST', body=buffer, contentType=contentType)
     59                 return
     60             except requests.ConnectionError as exception:
     61                 self.logger.info(exception)
     62                 uthread2.Sleep(2.0 / 2 ** retries)
     63                 retries -= 1
     64 
     65         raise exception
     66 
     67     def _MultipartEncode(self, fileName, fileData):
     68         boundary = mimetools.choose_boundary()
     69         buf = self._GetBufferForFile(boundary, fileData, fileName)
     70         contentType = self._GetContentTypeForFile(boundary)
     71         return (contentType, buf)
     72 
     73     def _GetContentTypeForFile(self, boundary):
     74         contentType = 'multipart/form-data; boundary={}'.format(boundary)
     75         return contentType
     76 
     77     def _GetBufferForFile(self, boundary, fileData, fileName):
     78         buf = StringIO()
     79         buf.write('--%s\r\n' % boundary)
     80         buf.write('Content-Disposition: form-data; name="File"; filename="%s"\r\n' % (fileName,))
     81         buf.write('Content-Type: %s\r\n' % GuessMimeType(fileName))
     82         buf.write('\r\n' + fileData + '\r\n')
     83         buf.write('--{}--\r\n'.format(boundary))
     84         buf = buf.getvalue()
     85         return buf
     86 
     87     def _GetData(self, categoryID, title, description, reproSteps, sessionInfo, computerInfo, userID, labels, server, build):
     88         description = '{} \n\nSession Info:\n{}'.format(description, sessionInfo)
     89         return {'categoryID': str(categoryID),
     90          'summary': title,
     91          'description': description,
     92          'reproductionSteps': reproSteps,
     93          'computerInfo': computerInfo,
     94          'originalReporterId': '{}'.format(userID),
     95          'Server': server,
     96          'Build': build,
     97          'labels': labels}
     98 
     99     def _HttpGet(self, urlAddition):
    100         return json.loads(self._Request(urlAddition, 'GET'))
    101 
    102     def _HttpPost(self, urlAddition, data):
    103         return json.loads(self._Request(urlAddition, 'POST', json.dumps(data)))
    104 
    105     def _Request(self, urlAddition, method, body = None, contentType = None):
    106         self.logger.info("making a '%s' call to the bugs service '%s'", method, urlAddition)
    107         url = '{}/{}'.format(self.baseUrl, urlAddition)
    108         self.logger.info('url: {}'.format(url))
    109         if contentType is None:
    110             contentType = 'application/json'
    111         headers = {}
    112         token = sm.GetService('connection').GetAccessToken()
    113         if token is not None:
    114             headers['Authorization'] = 'Bearer {}'.format(token)
    115         if contentType is not None:
    116             headers['Content-Type'] = contentType
    117         if method == 'GET':
    118             resp = requests.get(url, headers=headers)
    119         elif method == 'POST':
    120             resp = requests.post(url, data=body, headers=headers)
    121         else:
    122             raise RuntimeError('BugService unsupported method %s' % method)
    123         self.logger.info('response: {}'.format(resp))
    124         content = resp.content
    125         self.CheckResponse(resp, method)
    126         return content
    127 
    128     def CheckResponse(self, resp, method):
    129         status_code = resp.status_code
    130         if method == 'POST' and status_code not in (200, 201):
    131             self.logger.error('Bug Service Error Code: %s', status_code, extra={'response': resp,
    132              'fingerprint': ['bugservice', status_code]})
    133             raise RuntimeError('Unexpected error from the bugs service')
    134 
    135 
    136 class SendAttachmentError(Exception):
    137     pass
    138 
    139 
    140 def SendTestBugReport(serverUrl):
    141     bugReporter = BugReporter(serverUrl, '.cache')
    142     categoryName, categoryID = bugReporter.GetCategories()[0]
    143     response = bugReporter.SendBugReport(categoryID, 'title', 'description', 'repro steps', 'sessionInfo', 'computerInfo', 'charID', ['UI'], [])
    144     print("Bug Report successfully created '{}'".format(response['self']))
    145 
    146 
    147 if __name__ == '__main__':
    148     import sys
    149     if len(sys.argv) > 1:
    150         SendTestBugReport(sys.argv[1])