import os.path import time from euscanwww import settings from django.db.models import F, Sum, Max from euscan.models import Version, Package, Herd, Maintainer from euscan.models import CategoryLog import rrdtool import pylab import matplotlib CHARTS_ROOT = os.path.join(settings.MEDIA_ROOT, "charts") CHARTS_URL = os.path.join(settings.MEDIA_URL, "charts") CHARTS_TTL = (24 * 60 * 60) pylab.rcParams['font.size'] = 10.0 pylab.rcParams['axes.titlesize'] = 10.0 pylab.rcParams['xtick.labelsize'] = 8.0 pylab.rcParams['legend.fontsize'] = 8.0 def xint(i): try: return int(i) except: return 0 def chart_alive(name): path = os.path.join(CHARTS_ROOT, name) if not os.path.exists(path): return False if os.path.getmtime(__file__) > os.path.getmtime(path): return False if os.path.getmtime(path) + CHARTS_TTL < time.time(): return False return True def rrd_name(**kwargs): name = "" if 'category' in kwargs and kwargs['category']: name = 'category-%s' % kwargs['category'] elif 'herd' in kwargs and kwargs['herd']: name = 'herd-%d' % kwargs['herd'].id elif 'maintainer' in kwargs and kwargs['maintainer']: name = 'maintainer-%d' % kwargs['maintainer'].id else: name = 'world' return name def chart_name(name, **kwargs): if 'category' in kwargs and kwargs['category']: name += '-%s' % kwargs['category'] if 'herd' in kwargs and kwargs['herd']: name += '-h-%d' % kwargs['herd'].id if 'maintainer' in kwargs and kwargs['maintainer']: name += '-m-%d' % kwargs['maintainer'].id for kw in ('-small', '-weekly', '-monthly', '-yearly'): if kw in kwargs: name += kw return name + ".png" def getpackages(**kwargs): packages = Package.objects if 'category' in kwargs and kwargs['category']: packages = packages.filter(category=kwargs['category']) if 'herd' in kwargs and kwargs['herd']: packages = packages.filter(herds__id=kwargs['herd'].id) if 'maintainer' in kwargs and kwargs['maintainer']: packages = packages.filter(maintainers__id=kwargs['maintainer'].id) return packages def cached_pylab_chart(f): def new_f(*args, **kwds): name = chart_name(f.func_name, **kwds) if not chart_alive(name): f(*args, **kwds) pylab.savefig(os.path.join(CHARTS_ROOT, name)) pylab.close() return name new_f.func_name = f.func_name return new_f @cached_pylab_chart def pie_versions(**kwargs): n_packaged = xint(getpackages(**kwargs).aggregate(Sum('n_packaged'))['n_packaged__sum']) n_overlay = xint(getpackages(**kwargs).aggregate(Sum('n_overlay'))['n_overlay__sum']) n_versions = xint(getpackages(**kwargs).aggregate(Sum('n_versions'))['n_versions__sum']) n_upstream = n_versions - n_packaged - n_overlay pylab.figure(1, figsize=(3.5,3.5)) if n_overlay: labels = 'Gentoo', 'Overlays', 'Upstream' fracs = [n_packaged, n_overlay, n_upstream] colors = '#008000', '#0B17FD', '#FF0000' else: labels = 'Gentoo', 'Upstream' fracs = [n_packaged, n_upstream] colors = '#008000', '#FF0000' pylab.pie(fracs, labels=labels, colors=colors, autopct='%1.1f%%', shadow=True) pylab.title('Versions', bbox={'facecolor':'0.8', 'pad':5}) @cached_pylab_chart def pie_packages(**kwargs): n_packages = getpackages(**kwargs).count() n_packages_uptodate_main = getpackages(**kwargs).filter(n_versions=F('n_packaged')).count() n_packages_uptodate_all = getpackages(**kwargs).filter(n_versions=F('n_packaged') + F('n_overlay')).count() n_packages_outdated = n_packages - n_packages_uptodate_all n_packages_uptodate_ovl = n_packages_uptodate_all - n_packages_uptodate_main pylab.figure(1, figsize=(3.5,3.5)) if n_packages_uptodate_ovl: labels = 'Ok (gentoo)', 'Ok (overlays)', 'Outdated' fracs = [n_packages_uptodate_main, n_packages_uptodate_ovl, n_packages_outdated] colors = '#008000', '#0B17FD', '#FF0000' else: labels = 'Ok (gentoo)', 'Outdated' fracs = [n_packages_uptodate_main, n_packages_outdated] colors = '#008000', '#FF0000' pylab.pie(fracs, labels=labels, colors=colors, autopct='%1.1f%%', shadow=True) pylab.title('Packages', bbox={'facecolor':'0.8', 'pad':5}) def rrd_path(name): return str(os.path.join(settings.RRD_ROOT, name + '.rrd')) def rrd_create(name, start): path = rrd_path(name) if os.path.exists(path): return rrdtool.create(path, '--step', '86400', '--start', '%s' % int(start - 10), 'DS:n_packages_gentoo:GAUGE:4294967295:0:U', 'DS:n_packages_overlay:GAUGE:4294967295:0:U', 'DS:n_packages_outdated:GAUGE:4294967295:0:U', 'DS:n_versions_gentoo:GAUGE:4294967295:0:U', 'DS:n_versions_overlay:GAUGE:4294967295:0:U', 'DS:n_versions_upstream:GAUGE:4294967295:0:U', 'RRA:AVERAGE:0.5:1:100', 'RRA:AVERAGE:0.5:5:200', 'RRA:AVERAGE:0.5:10:200') def rrd_update(name, datetime, values): now = time.mktime(datetime.timetuple()) rrd_create(name, now) rrdtool.update(rrd_path(name), '%d:%d:%d:%d:%d:%d:%d' % \ (now, values.n_packages_gentoo, values.n_packages_overlay, values.n_packages_outdated, \ values.n_versions_gentoo, values.n_versions_overlay, values.n_versions_upstream)) """ [-s|--start time] [-e|--end time] [-S|--step seconds] [-t|--title string] [-v|--vertical-label string] [-w|--width pixels] [-h|--height pixels] [-j|--only-graph] [-D|--full-size-mode][-u|--upper-limit value] [-l|--lower-limit value] [-u|--upper-limit value] [-l|--lower-limit value] [-r|--rigid] [-A|--alt-autoscale] [-M|--alt-autoscale-max] [-J|--alt-autoscale-min] """ def cached_rrd_chart(f): def new_f(*args, **kwds): if 'period' not in kwds: kwds['period'] = '-yearly' name = chart_name(f.func_name, **kwds) path = os.path.join(CHARTS_ROOT, name) if not chart_alive(name): kwds['title'] = '%s (%s)' % (f.func_name, kwds['period']) kwds['steps'] = kwds['period'] kwds['vertical-label'] = f.func_name kwds['rrd'] = rrd_path(rrd_name(**kwds)) kwds['path'] = path kwds['end'] = 'now' if kwds['period'] == '-weekly': kwds['start'] = 'now-4weeks' elif kwds['period'] == '-monthly': kwds['start'] = 'now-12months' else: kwds['start'] = 'now-4years' if '-small' in kwds and kwds['-small']: kwds['width'] = '100' kwds['height'] = '30' kwds['graph-mode'] = '--only-graph' else: kwds['width'] = '500' kwds['height'] = '170' kwds['graph-mode'] = '--full-size-mode' f(*args, **kwds) return name new_f.func_name = f.func_name return new_f @cached_rrd_chart def packages(**kwargs): rrdtool.graph(str(kwargs['path']), '--imgformat', 'PNG', '--width', kwargs['width'], '--height', kwargs['height'], kwargs['graph-mode'], '--start', kwargs['start'], '--end', kwargs['end'], '--vertical-label', kwargs['vertical-label'], '--title', kwargs['title'], '--lower-limit', '0', 'DEF:n_packages_gentoo=%s:n_packages_gentoo:AVERAGE' % (kwargs['rrd']), 'DEF:n_packages_overlay=%s:n_packages_overlay:AVERAGE' % (kwargs['rrd']), 'DEF:n_packages_outdated=%s:n_packages_outdated:AVERAGE' % (kwargs['rrd']), 'LINE1.25:n_packages_gentoo#008000:Gentoo', 'LINE1.25:n_packages_overlay#0B17FD:Overlay', 'LINE1.25:n_packages_outdated#FF0000:Outdated') @cached_rrd_chart def versions(**kwargs): rrdtool.graph(str(kwargs['path']), '--imgformat', 'PNG', '--width', kwargs['width'], '--height', kwargs['height'], kwargs['graph-mode'], '--start', kwargs['start'], '--end', kwargs['end'], '--vertical-label', kwargs['vertical-label'], '--title', kwargs['title'], '--lower-limit', '0', 'DEF:n_versions_gentoo=%s:n_versions_gentoo:AVERAGE' % (kwargs['rrd']), 'DEF:n_versions_overlay=%s:n_versions_overlay:AVERAGE' % (kwargs['rrd']), 'DEF:n_versions_outdated=%s:n_versions_upstream:AVERAGE' % (kwargs['rrd']), 'LINE1.25:n_versions_gentoo#008000:Gentoo', 'LINE1.25:n_versions_overlay#0B17FD:Overlay', 'LINE1.25:n_versions_outdated#FF0000:Outdated')