mirror of
https://github.com/odoo/runbot.git
synced 2025-03-15 23:45:44 +07:00
[FIX] runbot: resurrect badges
This commit is contained in:
parent
e9a292373f
commit
9ff0e171e0
@ -21,6 +21,7 @@
|
||||
'templates/assets.xml',
|
||||
'templates/dashboard.xml',
|
||||
'templates/nginx.xml',
|
||||
'templates/badge.xml',
|
||||
'data/runbot_cron.xml'
|
||||
],
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import frontend
|
||||
from . import hook
|
||||
from . import hook
|
||||
from . import badge
|
||||
|
84
runbot/controllers/badge.py
Normal file
84
runbot/controllers/badge.py
Normal file
@ -0,0 +1,84 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import hashlib
|
||||
|
||||
import werkzeug
|
||||
from matplotlib.font_manager import FontProperties
|
||||
from matplotlib.textpath import TextToPath
|
||||
|
||||
from odoo.http import request, route, Controller
|
||||
|
||||
|
||||
class RunbotBadge(Controller):
|
||||
|
||||
@route([
|
||||
'/runbot/badge/<int:repo_id>/<branch>.svg',
|
||||
'/runbot/badge/<any(default,flat):theme>/<int:repo_id>/<branch>.svg',
|
||||
], type="http", auth="public", methods=['GET', 'HEAD'])
|
||||
def badge(self, repo_id, branch, theme='default'):
|
||||
|
||||
domain = [('repo_id', '=', repo_id),
|
||||
('branch_id.branch_name', '=', branch),
|
||||
('branch_id.sticky', '=', True),
|
||||
('state', 'in', ['testing', 'running', 'done']),
|
||||
('result', 'not in', ['skipped', 'manually_killed']),
|
||||
]
|
||||
|
||||
last_update = '__last_update'
|
||||
builds = request.env['runbot.build'].sudo().search_read(
|
||||
domain, ['state', 'result', 'job_age', last_update],
|
||||
order='id desc', limit=1)
|
||||
|
||||
if not builds:
|
||||
return request.not_found()
|
||||
|
||||
build = builds[0]
|
||||
etag = request.httprequest.headers.get('If-None-Match')
|
||||
retag = hashlib.md5(build[last_update].encode()).hexdigest()
|
||||
|
||||
if etag == retag:
|
||||
return werkzeug.wrappers.Response(status=304)
|
||||
|
||||
if build['state'] == 'testing':
|
||||
state = 'testing'
|
||||
cache_factor = 1
|
||||
else:
|
||||
cache_factor = 2
|
||||
if build['result'] == 'ok':
|
||||
state = 'success'
|
||||
elif build['result'] == 'warn':
|
||||
state = 'warning'
|
||||
else:
|
||||
state = 'failed'
|
||||
|
||||
# from https://github.com/badges/shields/blob/master/colorscheme.json
|
||||
color = {
|
||||
'testing': "#dfb317",
|
||||
'success': "#4c1",
|
||||
'failed': "#e05d44",
|
||||
'warning': "#fe7d37",
|
||||
}[state]
|
||||
|
||||
def text_width(s):
|
||||
fp = FontProperties(family='DejaVu Sans', size=11)
|
||||
w, h, d = TextToPath().get_text_width_height_descent(s, fp, False)
|
||||
return int(w + 1)
|
||||
|
||||
class Text(object):
|
||||
__slot__ = ['text', 'color', 'width']
|
||||
|
||||
def __init__(self, text, color):
|
||||
self.text = text
|
||||
self.color = color
|
||||
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)
|
47
runbot/templates/badge.xml
Normal file
47
runbot/templates/badge.xml
Normal file
@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<template id="runbot.badge_default"><?xml version="1.0"?>
|
||||
<svg t-attf-xmlns="http://www.w3.org/2000/svg" t-attf-width="{{left.width + right.width}}" height="18">
|
||||
<!-- from https://github.com/badges/shields/tree/master/templates -->
|
||||
<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"><?xml version="1.0"?>
|
||||
<svg t-attf-xmlns="http://www.w3.org/2000/svg" t-attf-width="{{left.width + right.width}}" height="20">
|
||||
<!-- from https://github.com/badges/shields/tree/master/templates -->
|
||||
<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 rx="3" t-attf-width="{{ left.width + right.width }}" height="20" t-att-fill="left.color"/>
|
||||
<rect rx="3" 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 rx="3" 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="15" fill="#010101" fill-opacity=".3"><t t-esc="left.text"/></text>
|
||||
<text t-attf-x="{{left.width/2+1}}" y="14"><t t-esc="left.text"/></text>
|
||||
<text t-attf-x="{{left.width+right.width/2-1}}" y="15" fill="#010101" fill-opacity=".3"><t t-esc="right.text"/></text>
|
||||
<text t-attf-x="{{left.width+right.width/2-1}}" y="14"><t t-esc="right.text"/></text>
|
||||
</g>
|
||||
</svg>
|
||||
</template>
|
||||
</data>
|
||||
</odoo>
|
Loading…
Reference in New Issue
Block a user