Skip to content

Instantly share code, notes, and snippets.

@gatopeich
Last active August 17, 2018 09:16
Show Gist options
  • Save gatopeich/e2d2a2b549744e0c5e9f3997f91ede7b to your computer and use it in GitHub Desktop.
Save gatopeich/e2d2a2b549744e0c5e9f3997f91ede7b to your computer and use it in GitHub Desktop.
Simple tray icon to display status of Jenkins builds, based on Python, wget, GTK StatusIcon, and some random art
#!/usr/bin/env python
# Display status of several Jenkins jobs in system tray
# Tooltip shows the list of builds and status
# SVG-based art represents the jobs status (random circles whose color reflects build status, green for OK etc.)
# On click, point default browser to ON_CLICK_URL
JOBS_URL = 'http://jenkins/job/'
ON_CLICK_URL = 'http://jenkins/user/myself/my-views/view/My%20Dashboard/'
WGET_AUTH = '--auth-no-challenge --user=XXX --password=YYY'
JOBS = 'job1 job2 job3'.split()
# End of company-specific info
COLORS = { 'passing' : 'lawngreen', 'passed' : 'forestgreen', 'running' : 'deepskyblue', 'unknown' : 'grey', 'failing' : 'red' }
# Preiods in milliseconds
ANIMATION_PERIOD = 2000
REFRESH_PERIOD = 10000
import gtk
import gobject
import random
import subprocess
import tempfile
import time
import ast, urllib2, base64
def pyJenkins(url):
request = urllib2.Request(url+'/api/python')
request.add_header('Authorization', 'Basic YWd1c3RpbnA6NFJhczFTNWE=')
return ast.literal_eval(urllib2.urlopen(request).read())
my_dashboard = pyJenkins(ON_CLICK_URL)
print (my_dashboard)
JOBS = []
for job in my_dashboard['jobs']:
details = pyJenkins(job['url']+'/lastBuild')
details['actions'] = len(details['actions'])
details['changeSet'] = len(details['changeSet'])
print job['name'], details
JOBS += [job['name']]
icon = gtk.StatusIcon()
icon.set_from_stock(gtk.STOCK_CANCEL)
icon.set_visible(True)
svg = tempfile.NamedTemporaryFile()
time_to_refresh = 0
def refresh():
global time_to_refresh, all_status
if time_to_refresh > 0:
time_to_refresh -= ANIMATION_PERIOD
else:
time_to_refresh = REFRESH_PERIOD
all_status = []
tooltip = ''
for job in JOBS:
lastBuild = pyJenkins(JOBS_URL+job+'/lastBuild')
status = 'running' if lastBuild['building'] else 'passing' if lastBuild['result'] == 'SUCCESS' else 'failing'
hours_ago = (time.time() - lastBuild['timestamp']/1000) / 3600
if status == 'passing' and hours_ago > 24: status = 'passed'
# print (job,status)
color = COLORS.get(status,'yellow')
line = '%s: <span color="%s">%s</span>'%(job,color,status)
if status not in ('passed','unknown'): line = '<big>'+line+'</big>'
line += ' %d hours ago'%hours_ago if hours_ago < 24 else ' %d days ago'%(hours_ago/24)
tooltip += '\n'+line if tooltip else line
print (line)
all_status += [color]
icon.set_tooltip_markup('<b>'+tooltip+'</b>')
# Animate status icon every second:
svg.seek(0)
svg.write('<svg width="99" height="99">')
random.shuffle(all_status)
for color in all_status:
style = 'fill="%s" fill-opacity="0.8"'%color
# style += 'stroke="%s" stroke-width="3"'%color # Looks nicer at higher scale
def rnd(): return random.randint(20,80)
x,y = rnd(),rnd()
svg.write('<circle cx="%d" cy="%d" r="%d" %s/>'%(x,y,min(x,y,99-x,99-y),style))
svg.write('</svg>')
svg.truncate()
svg.flush()
icon.set_from_file(svg.name)
return True
gobject.timeout_add(ANIMATION_PERIOD, refresh)
refresh()
def on_click(icon):
refresh();
subprocess.call("xdg-open " + ON_CLICK_URL, shell=True)
icon.connect('activate', on_click)
menu = gtk.Menu()
quit_item = gtk.MenuItem("Quit MyJenkinsTray")
menu.append(quit_item)
quit_item.connect('activate', gtk.main_quit)
quit_item.show()
icon.connect('popup-menu', lambda data, button, time: menu.popup(None, None, None, button, time))
gtk.main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment