mirror of
https://github.com/odoo/runbot.git
synced 2025-03-27 13:25:47 +07:00
[IMP] runbot: badge is now directly rendered via a qweb template instead of depending on shields.io service
This commit is contained in:
parent
e3fe1ef28d
commit
52b10975e9
@ -3,6 +3,7 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import fcntl
|
import fcntl
|
||||||
import glob
|
import glob
|
||||||
|
import hashlib
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
@ -12,6 +13,8 @@ import signal
|
|||||||
import simplejson
|
import simplejson
|
||||||
import subprocess
|
import subprocess
|
||||||
import time
|
import time
|
||||||
|
import Tkinter
|
||||||
|
import tkFont
|
||||||
|
|
||||||
import dateutil.parser
|
import dateutil.parser
|
||||||
import requests
|
import requests
|
||||||
@ -897,9 +900,11 @@ class RunbotController(http.Controller):
|
|||||||
_logger.exception("github error while adding label %s" % label_name)
|
_logger.exception("github error while adding label %s" % label_name)
|
||||||
return werkzeug.utils.redirect('/runbot/repo/%s' % build.repo_id.id)
|
return werkzeug.utils.redirect('/runbot/repo/%s' % build.repo_id.id)
|
||||||
|
|
||||||
@http.route('/runbot/badge/<model("runbot.repo"):repo>/<branch>.<any(svg,png):ext>',
|
@http.route([
|
||||||
type="http", auth="public", methods=['GET', 'HEAD'])
|
'/runbot/badge/<model("runbot.repo"):repo>/<branch>.svg',
|
||||||
def badge(self, repo, branch, ext):
|
'/runbot/badge/<any(default,flat):theme>/<model("runbot.repo"):repo>/<branch>.svg',
|
||||||
|
], type="http", auth="public", methods=['GET', 'HEAD'])
|
||||||
|
def badge(self, repo, branch, theme='default'):
|
||||||
|
|
||||||
domain = [('repo_id', '=', repo.id),
|
domain = [('repo_id', '=', repo.id),
|
||||||
('branch_id.branch_name', '=', branch),
|
('branch_id.branch_name', '=', branch),
|
||||||
@ -907,38 +912,57 @@ class RunbotController(http.Controller):
|
|||||||
('state', 'in', ['testing', 'running', 'done']),
|
('state', 'in', ['testing', 'running', 'done']),
|
||||||
]
|
]
|
||||||
|
|
||||||
builds = request.registry['runbot.build'].search_read(request.cr, request.uid,
|
last_update = '__last_update'
|
||||||
domain, ['state', 'result'],
|
builds = request.registry['runbot.build'].search_read(
|
||||||
order='id desc', limit=1)
|
request.cr, request.uid,
|
||||||
|
domain, ['state', 'result', 'job_age', last_update],
|
||||||
|
order='id desc', limit=1)
|
||||||
|
|
||||||
if not builds:
|
if not builds:
|
||||||
return request.not_found()
|
return request.not_found()
|
||||||
|
|
||||||
build = builds[0]
|
build = builds[0]
|
||||||
|
etag = request.httprequest.headers.get('If-None-Match')
|
||||||
|
retag = hashlib.md5(build[last_update]).hexdigest()
|
||||||
|
|
||||||
|
if etag == retag:
|
||||||
|
return werkzeug.wrappers.Response(status=304)
|
||||||
|
|
||||||
badge = {
|
|
||||||
'name': branch.replace('-', '--'),
|
|
||||||
'format': ext,
|
|
||||||
}
|
|
||||||
if build['state'] == 'testing':
|
if build['state'] == 'testing':
|
||||||
badge['status'] = 'testing'
|
state = 'testing'
|
||||||
|
cache_factor = 1
|
||||||
else:
|
else:
|
||||||
badge['status'] = 'success' if build['result'] == 'ok' else 'failed'
|
state = 'success' if build['result'] == 'ok' else 'failed'
|
||||||
|
cache_factor = 2
|
||||||
|
|
||||||
badge['color'] = {
|
# from https://github.com/badges/shields/blob/master/colorscheme.json
|
||||||
'testing': 'yellow',
|
color = {
|
||||||
'success': 'brightgreen',
|
'testing': "#dfb317",
|
||||||
'failed': 'red',
|
'success': "#4c1",
|
||||||
# 'warning': 'orange',
|
'failed': "#e05d44",
|
||||||
}[badge['status']]
|
'warning': "#fe7d37",
|
||||||
|
}[state]
|
||||||
|
|
||||||
url = 'http://img.shields.io/badge/{name}-{status}-{color}.{format}'.format(**badge)
|
text_width = tkFont.Font(Tkinter.Tk(), family='Verdana', size=11).measure
|
||||||
image = requests.get(url)
|
|
||||||
content = image.content
|
class Text(object):
|
||||||
headers = werkzeug.datastructures.Headers()
|
__slot__ = ['text', 'color', 'width']
|
||||||
headers.extend(image.headers.items())
|
def __init__(self, text, color):
|
||||||
headers['Content-Length'] = len(content)
|
self.text = text
|
||||||
headers.remove('content-encoding')
|
self.color = color
|
||||||
return werkzeug.wrappers.Response(content, status=image.status_code, headers=headers.items())
|
self.width = text_width(text) + 10
|
||||||
|
|
||||||
|
data = {
|
||||||
|
'left': Text(branch, '#555'),
|
||||||
|
'right': Text(state, color),
|
||||||
|
}
|
||||||
|
five_minutes = 5 * 60
|
||||||
|
headers = [
|
||||||
|
('Content-Type', 'image/svg+xml'),
|
||||||
|
('Cache-Control', 'max-age=%d' % (five_minutes * cache_factor,)),
|
||||||
|
('ETag', retag),
|
||||||
|
]
|
||||||
|
return request.render("runbot.badge_" + theme, data, headers=headers)
|
||||||
|
|
||||||
|
|
||||||
LABELS = {
|
LABELS = {
|
||||||
|
@ -534,6 +534,47 @@ http {
|
|||||||
}
|
}
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template id="runbot.badge_default">
|
||||||
|
<!-- from https://github.com/badges/shields/tree/master/templates -->
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" t-attf-width="{{left.width + right.width}}" height="18">
|
||||||
|
<linearGradient id="smooth" x2="0" y2="100%">
|
||||||
|
<stop offset="0" stop-color="#fff" stop-opacity=".7"/>
|
||||||
|
<stop offset=".1" stop-color="#aaa" stop-opacity=".1"/>
|
||||||
|
<stop offset=".9" stop-color="#000" stop-opacity=".3"/>
|
||||||
|
<stop offset="1" stop-color="#000" stop-opacity=".5"/>
|
||||||
|
</linearGradient>
|
||||||
|
<rect rx="4" t-attf-width="{{ left.width + right.width }}" height="18" t-att-fill="left.color"/>
|
||||||
|
<rect rx="4" t-att-x="left.width" t-att-width="right.width" height="18" t-att-fill="right.color"/>
|
||||||
|
<rect t-att-x="left.width" width="4" height="18" t-att-fill="right.color"/>
|
||||||
|
<rect rx="4" t-attf-width="{{ left.width + right.width }}" height="18" fill="url(#smooth)"/>
|
||||||
|
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
|
||||||
|
<text t-attf-x="{{left.width/2+1}}" y="13" fill="#010101" fill-opacity=".3"><t t-esc="left.text"/></text>
|
||||||
|
<text t-attf-x="{{left.width/2+1}}" y="12"><t t-esc="left.text"/></text>
|
||||||
|
<text t-attf-x="{{left.width+right.width/2-1}}" y="13" fill="#010101" fill-opacity=".3"><t t-esc="right.text"/></text>
|
||||||
|
<text t-attf-x="{{left.width+right.width/2-1}}" y="12"><t t-esc="right.text"/></text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
|
<template id="runbot.badge_flat">
|
||||||
|
<!-- from https://github.com/badges/shields/tree/master/templates -->
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" t-attf-width="{{left.width + right.width}}" height="20">
|
||||||
|
<linearGradient id="smooth" x2="0" y2="100%">
|
||||||
|
<stop offset="0" stop-color="#fff" stop-opacity=".1"/>
|
||||||
|
<stop offset=".1" stop-color="#fff" stop-opacity=".1"/>
|
||||||
|
<stop offset=".9" stop-color="#fff" stop-opacity=".1"/>
|
||||||
|
<stop offset="1" stop-color="#fff" stop-opacity=".1"/>
|
||||||
|
</linearGradient>
|
||||||
|
<rect t-attf-width="{{ left.width + right.width }}" height="20" t-att-fill="left.color"/>
|
||||||
|
<rect t-att-x="left.width" t-att-width="right.width" height="20" t-att-fill="right.color"/>
|
||||||
|
<rect t-att-x="left.width" width="4" height="20" t-att-fill="right.color"/>
|
||||||
|
<rect t-attf-width="{{ left.width + right.width }}" height="20" fill="url(#smooth)"/>
|
||||||
|
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
|
||||||
|
<text t-attf-x="{{left.width/2+1}}" y="13"><t t-esc="left.text"/></text>
|
||||||
|
<text t-attf-x="{{left.width+right.width/2-1}}" y="13"><t t-esc="right.text"/></text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
|
|
||||||
<!-- Cron -->
|
<!-- Cron -->
|
||||||
<record model="ir.cron" id="repo_cron">
|
<record model="ir.cron" id="repo_cron">
|
||||||
<field name='name'>Runbot Cron</field>
|
<field name='name'>Runbot Cron</field>
|
||||||
|
Loading…
Reference in New Issue
Block a user