Esempio n. 1
0
	def process_request(self,req):
		options = get_options(self.config)
		build_type_match =  re.match('/builds/history/(bt\d+)?$',req.path_info)
		if build_type_match is None:
			query_string =  "&".join(['buildTypeId=%s' % id for id in options['builds']])
		else:
			build_type_id = build_type_match.groups()[0]
			query_string = 'buildTypeId=%s' % build_type_id
		add_stylesheet(req, 'teamcity/css/teamcity.css')
		query_string += '&sinceDate=-%d' % options['limit']
		feed_url = "%s/feed.html?%s" % (options['base_url'], query_string)
		tc = TeamCityQuery(self.options)
		feed = TeamCityQuery.xml_query(feed_url)
		if feed is None:
			raise HTTPNotFound("Can't load feed")
		data = {'entries': []}
		for entry in feed.iterfind('{http://www.w3.org/2005/Atom}entry'):
			title = entry.find('{http://www.w3.org/2005/Atom}title').text
			link = entry.find('{http://www.w3.org/2005/Atom}link').attrib['href']
			date = entry.find('{http://www.w3.org/2005/Atom}published').text
			date = datetime.strptime(date, '%Y-%m-%dT%H:%M:%SZ')
			summary = entry.find('{http://www.w3.org/2005/Atom}summary').text
			summary =  summary.split('<a href')[0]
			build_id_match = re.search('buildId=(\d+)', link)
			if build_id_match:
				summary += "<br/><a href='%s'>Build Log</a>" % \
						req.href.builds('download', build_id_match.groups()[0])
			data['entries'].append({
					'title': title,
					'link': link,
					'date': date,
					'summary': summary,
				})
		return 'teamcity_status.html', data, None
Esempio n. 2
0
    def get_timeline_events(self, req, start, stop, filters):
        """Returns a list of events in the time range given by the `start` and
		`stop` parameters.

		Full description here http://trac.edgewall.org/browser/trunk/trac/timeline/api.py
		"""
        if 'build' not in filters:
            return
        # exit if there is not any buildType in options
        if not self.options.get('builds', True):
            return
        # get rss feed
        query_string = "&".join(
            ['buildTypeId=%s' % id for id in self.options['builds']])
        query_string += '&sinceDate=-%d' % self.options['limit']
        feed_url = "%s/httpAuth/feed.html?%s" % (self.options['base_url'],
                                                 query_string)
        tc = TeamCityQuery(self.options)
        try:
            feed = tc.xml_query(feed_url)
        except TeamCityError as e:
            self.log.error("Error while proceed TeamCity events: %s" % e)
            return
        if feed is None:
            self.log.error("Can't get teamcity feed")
            return
        add_stylesheet(req, 'teamcity/css/teamcity.css')
        add_javascript(req, 'teamcity/js/loadlog.js')
        # iterate over resulted xml feed
        for entry in feed.iterfind('{http://www.w3.org/2005/Atom}entry'):
            event_date = entry.find(
                '{http://www.w3.org/2005/Atom}published').text
            event_date = datetime.strptime(event_date, '%Y-%m-%dT%H:%M:%SZ')
            event_date = event_date.replace(tzinfo=GMT0())
            if (event_date < start) or (event_date > stop): continue
            event_title = entry.find('{http://www.w3.org/2005/Atom}title').text
            event_status = entry.find(
                '{http://purl.org/dc/elements/1.1/}creator').text
            event_status = event_status.lower().replace(' ', '_')
            # get build id
            build_url = entry.find(
                '{http://www.w3.org/2005/Atom}link').attrib['href']
            build_id, build_type = get_build_ids(build_url)
            # get build message
            if event_status == 'successful_build':
                msg = 'Build was successful'
            else:
                msg = 'Build failed'
            data = {
                'date': event_date,
                'status': event_status,
                'title': event_title,
                'build_url': build_url,
                'build_type': build_type,
                'build_id': build_id,
                'message': msg,
            }
            yield event_status, event_date, 'ci server', data
Esempio n. 3
0
	def process_request(self,req):
		try:
			path = req.path_info.split('/builds/proxy/')[1]
		except IndexError: # no trailing slash ex.
			raise HTTPNotFound("Invalid proxy url, no trailing slash")
		t_url = "%s/httpAuth/%s?%s" % (self.options['base_url'],
							  path,req.environ['QUERY_STRING'])
		tc = TeamCityQuery(self.options)
		try:
			response = tc.http_query(t_url)
		except TeamCityError, e:
			raise HTTPBadGateway('An error occured during proxy request to %s: %s' % (t_url, e))
Esempio n. 4
0
	def get_timeline_events(self, req, start, stop, filters):
		"""Returns a list of events in the time range given by the `start` and
		`stop` parameters.

		Full description here http://trac.edgewall.org/browser/trunk/trac/timeline/api.py
		"""
		if 'build' not in filters:
			return
		# exit if there is not any buildType in options
		if not self.options.get('builds',True):
			return
		# get rss feed 
		query_string =  "&".join(['buildTypeId=%s' % id for id in self.options['builds']])
		query_string += '&sinceDate=-%d' % self.options['limit']
		feed_url = "%s/httpAuth/feed.html?%s" % (self.options['base_url'], query_string)
		tc = TeamCityQuery(self.options)
		try:
			feed = tc.xml_query(feed_url)
		except TeamCityError as e:
			self.log.error("Error while proceed TeamCity events: %s" % e)
			return
		if feed is None:
			self.log.error("Can't get teamcity feed")
			return
		add_stylesheet(req,'teamcity/css/teamcity.css')
		add_javascript(req,'teamcity/js/loadlog.js')
		# iterate over resulted xml feed
		for entry in feed.iterfind('{http://www.w3.org/2005/Atom}entry'):
			event_date = entry.find('{http://www.w3.org/2005/Atom}published').text
			event_date = datetime.strptime(event_date, '%Y-%m-%dT%H:%M:%SZ')
			event_date = event_date.replace(tzinfo=GMT0())
			if (event_date < start) or (event_date > stop): continue
			event_title = entry.find('{http://www.w3.org/2005/Atom}title').text
			event_status =  entry.find('{http://purl.org/dc/elements/1.1/}creator').text
			event_status = event_status.lower().replace(' ','_')
			# get build id
			build_url = entry.find('{http://www.w3.org/2005/Atom}link').attrib['href']
			build_id, build_type = get_build_ids(build_url)
			# get build message 
			if event_status == 'successful_build':
				msg = 'Build was successful'
			else:
				msg = 'Build failed'
			data = {
				'date': event_date,
				'status': event_status,
				'title': event_title,
				'build_url': build_url,
				'build_type': build_type,
				'build_id': build_id,
				'message': msg,
			}
			yield event_status, event_date, 'ci server', data
Esempio n. 5
0
 def render_admin_panel(self, req, category, page, path_info):
     if not req.perm.has_permission('TEAMCITY_ADMIN'):
         raise HTTPForbidden('You are not allowed to configure TC plugin')
     if req.method == 'POST':
         options, errors = self._save_options(req.args)
         if not errors:
             # redirect here
             req.redirect(req.href(req.path_info))
     else:
         options, errors = get_options(self.config), []
     tc = TeamCityQuery(options)
     url = "%s/httpAuth/app/rest/buildTypes" % options['base_url']
     # load builds from TC using REST API
     try:
         builds_xml = tc.xml_query(url)
     except TeamCityError, e:
         errors.append("Fix base config options: %s" % e)
         t_data = {'options': options, 'projects': {}, 'errors': errors}
         return 'teamcity_admin.html', t_data
Esempio n. 6
0
	def render_admin_panel(self,req,category,page,path_info):
		if not req.perm.has_permission('TEAMCITY_ADMIN'):
			raise HTTPForbidden('You are not allowed to configure TC plugin')
		if req.method == 'POST':
			options,errors = self._save_options(req.args)
			if not errors:
				# redirect here
				req.redirect(req.href(req.path_info))
		else:
			options,errors = get_options(self.config),[]
		tc = TeamCityQuery(options)
		url = "%s/httpAuth/app/rest/buildTypes" % options['base_url']
		# load builds from TC using REST API
		try:
			builds_xml = tc.xml_query(url)
		except TeamCityError,e: 
			errors.append("Fix base config options: %s" % e)
			t_data = {'options':options,'projects':{},'errors':errors}
			return 'teamcity_admin.html',t_data
Esempio n. 7
0
	def process_request(self,req):
		if not req.perm.has_permission('TEAMCITY_BUILD'):
			raise HTTPForbidden('You are not allowed to view/run TC builds')
		options = get_options(self.config)
		tc = TeamCityQuery(options)
		# projects variable will collect builds result in following format:
		# {'projectId': { 
		#			'name': 'Proj1', 
		#			'btypes': [{		# it's a list of build types assigned to this project
		#					'btype_id': 'bt1',
		#					'btype_name': 'PS3 builds'
		#					'build': {
		#							'number': 5555 # teamcity number
		#							'status': 'Success',
		#							'start_date': datetime_object,
		#							'end_date': datetime_object,
		#					},]
		#			}
		# }
		projects = {}
		for build_type in options['builds']:
			# load builds xml from teamcity
			url = "%s/httpAuth/app/rest/buildTypes/id:%s/builds" %\
										(options['base_url'],build_type)
			btype_xml = tc.xml_query(url)
			if btype_xml is None:
				self.log.error("Can't load builds xml at %s" % url)
				continue
			if len(btype_xml) < 1: # there is not any builds yet
				url = '%s/httpAuth/app/rest/buildTypes/id:%s' % (options['base_url'], build_type)
				build_xml = tc.xml_query(url)
				if build_xml is None:
					continue
				proj_id = build_xml.xpath('/buildType/project/@id')[0]
				# collect here as many build info as possible and continue
				build_info = {
					'btype_id': build_type,
					'btype_name': build_xml.attrib['name'],
					'build': {
						'id': None,
						'number': None,
						'status': 'unknown',
						'end_date': 'Never',
						'duration': 'Unknown'
					}
				}
				if proj_id in projects:
					projects[proj_id]['btypes'].append(build_info)
				else: # or create new item in projects
					projects[proj_id] = {
						'name': proj_name,
						'btypes': [build_info,]
					}
				continue

			# There is at least one finished build
			last_build = btype_xml[0].attrib
			# load this build xml
			url = "%s%s" % (options['base_url'],last_build['href'])
			build_xml = tc.xml_query(url)
			if build_xml is None:
				self.log.error("Can't load build xml at %s" % url)
			proj_id = build_xml.xpath('/build/buildType/@projectId')[0]
			proj_name =  build_xml.xpath('/build/buildType/@projectName')[0]
			# F**k! python2.5 has not support for timezones in datetime.strptime
			try:
				# datetime lacks timezone info
				start_date =  build_xml.xpath('/build/startDate/text()')[0].split('+')[0] 
				start_date = datetime.strptime(start_date, '%Y%m%dT%H%M%S')
				# datetime lacks timezone info
				end_date = build_xml.xpath('/build/finishDate/text()')[0].split('+')[0] 
				end_date = datetime.strptime(end_date, '%Y%m%dT%H%M%S')
			except IndexError: # no start_date or end_date, duration is unknown
				end_date = 'Never'
				duration = 'Unknown'
			else:
				duration = end_date - start_date
			# parse build status
			try:
				status = build_xml.xpath('/build/statusText/text()')[0].lower()
			except IndexError: # no last status yet
				status = 'unknown'
			# result build dictionary
			build_info = {
				'btype_id': build_type,
				'btype_name': build_xml.xpath('/build/buildType/@name')[0],
				'build': {
					'id': build_xml.attrib['id'],
					'number': build_xml.attrib['number'],
					'status': status,
					'end_date': end_date,
					'duration': duration
				}
			}
			# add new build to project
			if proj_id in projects:
				projects[proj_id]['btypes'].append(build_info)
			else: # or create new item in projects
				projects[proj_id] = {
					'name': proj_name,
					'btypes': [build_info,]
				}
		add_stylesheet(req,'teamcity/css/teamcity.css')
		add_javascript(req,'teamcity/js/jquery.timers-1.2.js')
		add_javascript(req,'teamcity/js/event_tracker.js')
		return 'teamcity_builds.html', {
					'projects':projects,
					'dpath':req.href('builds/download')
					}, None