euscanwww: charts, about, etc...
Signed-off-by: Corentin Chary <corentincj@iksaif.net>
This commit is contained in:
		
							
								
								
									
										115
									
								
								euscanwww/euscan/charts.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								euscanwww/euscan/charts.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,115 @@
 | 
			
		||||
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 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 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
 | 
			
		||||
    return name + ".png"
 | 
			
		||||
 | 
			
		||||
def packages(**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(packages(**kwargs).aggregate(Sum('n_packaged'))['n_packaged__sum'])
 | 
			
		||||
    n_overlay = xint(packages(**kwargs).aggregate(Sum('n_overlay'))['n_overlay__sum'])
 | 
			
		||||
    n_versions = xint(packages(**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 = packages(**kwargs).count()
 | 
			
		||||
    n_packages_uptodate_main = packages(**kwargs).filter(n_versions=F('n_packaged')).count()
 | 
			
		||||
    n_packages_uptodate_all = packages(**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})
 | 
			
		||||
 | 
			
		||||
@@ -62,7 +62,7 @@ class Command(BaseCommand):
 | 
			
		||||
 | 
			
		||||
	matches = sorted(matches)
 | 
			
		||||
        pkg = matches.pop()
 | 
			
		||||
	if pkg.version == '9999' and len(matches):
 | 
			
		||||
	if '9999' in pkg.version and len(matches):
 | 
			
		||||
		pkg = matches.pop()
 | 
			
		||||
 | 
			
		||||
        obj, created = Package.objects.get_or_create(category=pkg.category, name=pkg.name)
 | 
			
		||||
 
 | 
			
		||||
@@ -103,14 +103,14 @@ class Command(BaseCommand):
 | 
			
		||||
            slot = match.group('slot')
 | 
			
		||||
            overlay = match.group('overlay')
 | 
			
		||||
 | 
			
		||||
            if not package or not cpv.startswith(str(package)):
 | 
			
		||||
                package = self.store_package(options, cpv)
 | 
			
		||||
            cat, pkg, ver, rev = portage.catpkgsplit(cpv)
 | 
			
		||||
 | 
			
		||||
            if not package or not (cat == package.category and pkg == package.name):
 | 
			
		||||
                package = self.store_package(options, cat, pkg)
 | 
			
		||||
 | 
			
		||||
            self.store_version(options, package, cpv, slot, overlay)
 | 
			
		||||
 | 
			
		||||
    def store_package(self, options, cpv):
 | 
			
		||||
        cat, pkg, ver, rev = portage.catpkgsplit(cpv)
 | 
			
		||||
 | 
			
		||||
    def store_package(self, options, cat, pkg):
 | 
			
		||||
        obj, created = Package.objects.get_or_create(category=cat, name=pkg)
 | 
			
		||||
 | 
			
		||||
        if created:
 | 
			
		||||
@@ -121,6 +121,7 @@ class Command(BaseCommand):
 | 
			
		||||
        Version.objects.filter(package=obj, packaged=True).delete()
 | 
			
		||||
 | 
			
		||||
        obj.n_packaged = 0
 | 
			
		||||
        obj.n_overlay = 0
 | 
			
		||||
        obj.n_versions = Version.objects.filter(package=obj).count()
 | 
			
		||||
        obj.save()
 | 
			
		||||
 | 
			
		||||
@@ -144,7 +145,10 @@ class Command(BaseCommand):
 | 
			
		||||
                                                     overlay=overlay)
 | 
			
		||||
 | 
			
		||||
        if created or not package.n_packaged:
 | 
			
		||||
            if overlay == 'gentoo':
 | 
			
		||||
                package.n_packaged += 1
 | 
			
		||||
            else:
 | 
			
		||||
                package.n_overlay += 1
 | 
			
		||||
        if created:
 | 
			
		||||
            package.n_versions += 1
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -51,40 +51,44 @@ class Command(BaseCommand):
 | 
			
		||||
        for package in Package.objects.all():
 | 
			
		||||
            # Should not be needed, but can't hurt
 | 
			
		||||
            package.n_versions = Version.objects.filter(package=package).count()
 | 
			
		||||
            package.n_packaged != Version.objects.filter(package=package,packaged=True).count()
 | 
			
		||||
            package.n_packaged = Version.objects.filter(package=package, packaged=True, overlay='gentoo').count()
 | 
			
		||||
            package.n_overlay = Version.objects.filter(package=package, packaged=True).exclude(overlay='gentoo').count()
 | 
			
		||||
            package.save()
 | 
			
		||||
 | 
			
		||||
            for herd in package.herds.all():
 | 
			
		||||
                herds[herd].n_packages += 1
 | 
			
		||||
                herds[herd].n_versions += package.n_versions
 | 
			
		||||
                herds[herd].n_packaged += package.n_packaged
 | 
			
		||||
                herds[herd].n_overlay += package.n_overlay
 | 
			
		||||
 | 
			
		||||
            for maintainer in package.maintainers.all():
 | 
			
		||||
                maintainers[maintainer].n_packages += 1
 | 
			
		||||
                maintainers[maintainer].n_versions += package.n_versions
 | 
			
		||||
                maintainers[maintainer].n_packaged += package.n_packaged
 | 
			
		||||
                maintainers[maintainer].n_overlay += package.n_overlay
 | 
			
		||||
 | 
			
		||||
            categories[package.category].n_packages += 1
 | 
			
		||||
            categories[package.category].n_versions += package.n_versions
 | 
			
		||||
            categories[package.category].n_packaged += package.n_packaged
 | 
			
		||||
            categories[package.category].n_overlay += package.n_overlay
 | 
			
		||||
 | 
			
		||||
        for clog in categories.values():
 | 
			
		||||
            if not options['quiet']:
 | 
			
		||||
                self.stdout.write('[c] %s - [%d, %d/%d]\n' %
 | 
			
		||||
                self.stdout.write('[c] %s - [%d, %d/%d/%d]\n' %
 | 
			
		||||
                                  (clog.category, clog.n_packages,
 | 
			
		||||
                                   clog.n_packaged, clog.n_versions))
 | 
			
		||||
                                   clog.n_packaged, clog.n_overlay, clog.n_versions))
 | 
			
		||||
            clog.save()
 | 
			
		||||
 | 
			
		||||
        for hlog in herds.values():
 | 
			
		||||
            if not options['quiet']:
 | 
			
		||||
                self.stdout.write('[h] %s - [%d, %d/%d]\n' %
 | 
			
		||||
                self.stdout.write('[h] %s - [%d, %d/%d/%d]\n' %
 | 
			
		||||
                                  (hlog.herd, hlog.n_packages,
 | 
			
		||||
                                   hlog.n_packaged, hlog.n_versions))
 | 
			
		||||
                                   hlog.n_packaged, hlog.n_overlay, hlog.n_versions))
 | 
			
		||||
            hlog.save()
 | 
			
		||||
 | 
			
		||||
        for mlog in maintainers.values():
 | 
			
		||||
            if not options['quiet']:
 | 
			
		||||
                self.stdout.write('[m] %s - [%d, %d/%d]\n' %
 | 
			
		||||
                self.stdout.write('[m] %s - [%d, %d/%d/%d]\n' %
 | 
			
		||||
                                  (mlog.maintainer, mlog.n_packages,
 | 
			
		||||
                                   mlog.n_packaged, mlog.n_versions))
 | 
			
		||||
                                   mlog.n_packaged, mlog.n_overlay, mlog.n_versions))
 | 
			
		||||
            mlog.save()
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,115 @@
 | 
			
		||||
# encoding: utf-8
 | 
			
		||||
import datetime
 | 
			
		||||
from south.db import db
 | 
			
		||||
from south.v2 import SchemaMigration
 | 
			
		||||
from django.db import models
 | 
			
		||||
 | 
			
		||||
class Migration(SchemaMigration):
 | 
			
		||||
 | 
			
		||||
    def forwards(self, orm):
 | 
			
		||||
        
 | 
			
		||||
        # Adding field 'CategoryLog.n_overlay'
 | 
			
		||||
        db.add_column('euscan_categorylog', 'n_overlay', self.gf('django.db.models.fields.IntegerField')(default=0), keep_default=False)
 | 
			
		||||
 | 
			
		||||
        # Adding field 'Package.n_overlay'
 | 
			
		||||
        db.add_column('euscan_package', 'n_overlay', self.gf('django.db.models.fields.IntegerField')(default=0), keep_default=False)
 | 
			
		||||
 | 
			
		||||
        # Adding field 'HerdLog.n_overlay'
 | 
			
		||||
        db.add_column('euscan_herdlog', 'n_overlay', self.gf('django.db.models.fields.IntegerField')(default=0), keep_default=False)
 | 
			
		||||
 | 
			
		||||
        # Adding field 'MaintainerLog.n_overlay'
 | 
			
		||||
        db.add_column('euscan_maintainerlog', 'n_overlay', self.gf('django.db.models.fields.IntegerField')(default=0), keep_default=False)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def backwards(self, orm):
 | 
			
		||||
        
 | 
			
		||||
        # Deleting field 'CategoryLog.n_overlay'
 | 
			
		||||
        db.delete_column('euscan_categorylog', 'n_overlay')
 | 
			
		||||
 | 
			
		||||
        # Deleting field 'Package.n_overlay'
 | 
			
		||||
        db.delete_column('euscan_package', 'n_overlay')
 | 
			
		||||
 | 
			
		||||
        # Deleting field 'HerdLog.n_overlay'
 | 
			
		||||
        db.delete_column('euscan_herdlog', 'n_overlay')
 | 
			
		||||
 | 
			
		||||
        # Deleting field 'MaintainerLog.n_overlay'
 | 
			
		||||
        db.delete_column('euscan_maintainerlog', 'n_overlay')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    models = {
 | 
			
		||||
        'euscan.categorylog': {
 | 
			
		||||
            'Meta': {'object_name': 'CategoryLog'},
 | 
			
		||||
            'category': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
 | 
			
		||||
            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
 | 
			
		||||
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
 | 
			
		||||
            'n_overlay': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
 | 
			
		||||
            'n_packaged': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
 | 
			
		||||
            'n_packages': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
 | 
			
		||||
            'n_versions': ('django.db.models.fields.IntegerField', [], {'default': '0'})
 | 
			
		||||
        },
 | 
			
		||||
        'euscan.euscanresult': {
 | 
			
		||||
            'Meta': {'object_name': 'EuscanResult'},
 | 
			
		||||
            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
 | 
			
		||||
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
 | 
			
		||||
            'package': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['euscan.Package']"}),
 | 
			
		||||
            'result': ('django.db.models.fields.TextField', [], {'blank': 'True'})
 | 
			
		||||
        },
 | 
			
		||||
        'euscan.herd': {
 | 
			
		||||
            'Meta': {'object_name': 'Herd'},
 | 
			
		||||
            'email': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
 | 
			
		||||
            'herd': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
 | 
			
		||||
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
 | 
			
		||||
        },
 | 
			
		||||
        'euscan.herdlog': {
 | 
			
		||||
            'Meta': {'object_name': 'HerdLog'},
 | 
			
		||||
            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
 | 
			
		||||
            'herd': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['euscan.Herd']"}),
 | 
			
		||||
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
 | 
			
		||||
            'n_overlay': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
 | 
			
		||||
            'n_packaged': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
 | 
			
		||||
            'n_packages': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
 | 
			
		||||
            'n_versions': ('django.db.models.fields.IntegerField', [], {'default': '0'})
 | 
			
		||||
        },
 | 
			
		||||
        'euscan.maintainer': {
 | 
			
		||||
            'Meta': {'object_name': 'Maintainer'},
 | 
			
		||||
            'email': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
 | 
			
		||||
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
 | 
			
		||||
            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'})
 | 
			
		||||
        },
 | 
			
		||||
        'euscan.maintainerlog': {
 | 
			
		||||
            'Meta': {'object_name': 'MaintainerLog'},
 | 
			
		||||
            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
 | 
			
		||||
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
 | 
			
		||||
            'maintainer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['euscan.Maintainer']"}),
 | 
			
		||||
            'n_overlay': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
 | 
			
		||||
            'n_packaged': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
 | 
			
		||||
            'n_packages': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
 | 
			
		||||
            'n_versions': ('django.db.models.fields.IntegerField', [], {'default': '0'})
 | 
			
		||||
        },
 | 
			
		||||
        'euscan.package': {
 | 
			
		||||
            'Meta': {'unique_together': "(['category', 'name'],)", 'object_name': 'Package'},
 | 
			
		||||
            'category': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
 | 
			
		||||
            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
 | 
			
		||||
            'herds': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['euscan.Herd']", 'symmetrical': 'False', 'blank': 'True'}),
 | 
			
		||||
            'homepage': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}),
 | 
			
		||||
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
 | 
			
		||||
            'maintainers': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['euscan.Maintainer']", 'symmetrical': 'False', 'blank': 'True'}),
 | 
			
		||||
            'n_overlay': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
 | 
			
		||||
            'n_packaged': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
 | 
			
		||||
            'n_versions': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
 | 
			
		||||
            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'})
 | 
			
		||||
        },
 | 
			
		||||
        'euscan.version': {
 | 
			
		||||
            'Meta': {'unique_together': "(['package', 'slot', 'revision', 'version', 'overlay'],)", 'object_name': 'Version'},
 | 
			
		||||
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
 | 
			
		||||
            'overlay': ('django.db.models.fields.CharField', [], {'default': "'gentoo'", 'max_length': '128'}),
 | 
			
		||||
            'package': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['euscan.Package']"}),
 | 
			
		||||
            'packaged': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
 | 
			
		||||
            'revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
 | 
			
		||||
            'slot': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
 | 
			
		||||
            'urls': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
 | 
			
		||||
            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    complete_apps = ['euscan']
 | 
			
		||||
@@ -27,6 +27,7 @@ class Package(models.Model):
 | 
			
		||||
    # For performance, we keep pre-computed counters
 | 
			
		||||
    n_versions = models.IntegerField(default=0)
 | 
			
		||||
    n_packaged = models.IntegerField(default=0)
 | 
			
		||||
    n_overlay = models.IntegerField(default=0)
 | 
			
		||||
 | 
			
		||||
    def __unicode__(self):
 | 
			
		||||
        return '%s/%s' % (self.category, self.name)
 | 
			
		||||
@@ -40,7 +41,7 @@ class Version(models.Model):
 | 
			
		||||
    revision = models.CharField(max_length=128)
 | 
			
		||||
    version = models.CharField(max_length=128)
 | 
			
		||||
    packaged = models.BooleanField()
 | 
			
		||||
    overlay = models.CharField(max_length=128)
 | 
			
		||||
    overlay = models.CharField(max_length=128, default='gentoo')
 | 
			
		||||
    urls = models.TextField(blank=True)
 | 
			
		||||
 | 
			
		||||
    def __unicode__(self):
 | 
			
		||||
@@ -64,6 +65,7 @@ class CategoryLog(models.Model):
 | 
			
		||||
    n_packages = models.IntegerField(default=0)
 | 
			
		||||
    n_versions = models.IntegerField(default=0)
 | 
			
		||||
    n_packaged = models.IntegerField(default=0)
 | 
			
		||||
    n_overlay = models.IntegerField(default=0)
 | 
			
		||||
 | 
			
		||||
class HerdLog(models.Model):
 | 
			
		||||
    herd = models.ForeignKey(Herd)
 | 
			
		||||
@@ -72,6 +74,7 @@ class HerdLog(models.Model):
 | 
			
		||||
    n_packages = models.IntegerField(default=0)
 | 
			
		||||
    n_versions = models.IntegerField(default=0)
 | 
			
		||||
    n_packaged = models.IntegerField(default=0)
 | 
			
		||||
    n_overlay = models.IntegerField(default=0)
 | 
			
		||||
 | 
			
		||||
class MaintainerLog(models.Model):
 | 
			
		||||
    maintainer = models.ForeignKey(Maintainer)
 | 
			
		||||
@@ -80,3 +83,4 @@ class MaintainerLog(models.Model):
 | 
			
		||||
    n_packages = models.IntegerField(default=0)
 | 
			
		||||
    n_versions = models.IntegerField(default=0)
 | 
			
		||||
    n_packaged = models.IntegerField(default=0)
 | 
			
		||||
    n_overlay = models.IntegerField(default=0)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								euscanwww/euscan/templatetags/div.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								euscanwww/euscan/templatetags/div.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
from django import template
 | 
			
		||||
 | 
			
		||||
register = template.Library()
 | 
			
		||||
 | 
			
		||||
def div(value, arg=None):
 | 
			
		||||
    return value/arg
 | 
			
		||||
 | 
			
		||||
register.filter('div', div)
 | 
			
		||||
@@ -5,3 +5,11 @@ register = template.Library()
 | 
			
		||||
@register.inclusion_tag('euscan/_packages.html')
 | 
			
		||||
def packages(packages):
 | 
			
		||||
    return { 'packages' : packages }
 | 
			
		||||
 | 
			
		||||
@register.inclusion_tag('euscan/_package_cols.html')
 | 
			
		||||
def package_cols(infos):
 | 
			
		||||
    return { 'infos' : infos }
 | 
			
		||||
 | 
			
		||||
@register.inclusion_tag('euscan/_package_bar.html')
 | 
			
		||||
def package_bar(infos):
 | 
			
		||||
    return { 'infos' : infos }
 | 
			
		||||
 
 | 
			
		||||
@@ -2,14 +2,19 @@ from django.conf.urls.defaults import *
 | 
			
		||||
 | 
			
		||||
urlpatterns = patterns('euscan.views',
 | 
			
		||||
    (r'^$', 'index'),
 | 
			
		||||
    (r'^logs/$', 'logs'),
 | 
			
		||||
    (r'^about/$', 'about'),
 | 
			
		||||
    (r'^statistics/$', 'statistics'),
 | 
			
		||||
    (r'^statistics/charts/(?P<chart>[\w\-]+).png$', 'chart'),
 | 
			
		||||
    (r'^world/$', 'world'),
 | 
			
		||||
    (r'^world/scan/$', 'world_scan'),
 | 
			
		||||
    (r'^categories/$', 'categories'),
 | 
			
		||||
    (r'^categories/(?P<category>[\w+][\w+.-]*)/view/$', 'category'),
 | 
			
		||||
    (r'^categories/(?P<category>[\w+][\w+.-]*)/charts/(?P<chart>[\w\-]+).png$', 'chart_category'),
 | 
			
		||||
    (r'^herds/$', 'herds'),
 | 
			
		||||
    (r'^herds/(?P<herd>[\{\}\w+.-]*)/view/$', 'herd'),
 | 
			
		||||
    (r'^herds/(?P<herd>[\{\}\w+.-]*)/charts/(?P<chart>[\w\-]+).png$', 'chart_herd'),
 | 
			
		||||
    (r'^maintainers/$', 'maintainers'),
 | 
			
		||||
    (r'^maintainers/(?P<maintainer_id>\d+)/view/$', 'maintainer'),
 | 
			
		||||
    (r'^maintainers/(?P<maintainer_id>\d+)/charts/(?P<chart>[\w\-]+).png$', 'chart_maintainer'),
 | 
			
		||||
    (r'^package/(?P<category>[\w+][\w+.-]*)/(?P<package>[\w+][\w+.-]*)/$', 'package'),
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
from annoying.decorators import render_to
 | 
			
		||||
from django.http import HttpResponse
 | 
			
		||||
from django.http import Http404
 | 
			
		||||
from django.shortcuts import get_object_or_404
 | 
			
		||||
from django.db.models import Sum, Max
 | 
			
		||||
@@ -6,13 +7,17 @@ from django.db.models import Sum, Max
 | 
			
		||||
from euscan.models import Version, Package, Herd, Maintainer, EuscanResult
 | 
			
		||||
from euscan.forms import WorldForm, PackagesForm
 | 
			
		||||
 | 
			
		||||
import charts
 | 
			
		||||
 | 
			
		||||
""" Views """
 | 
			
		||||
 | 
			
		||||
@render_to('euscan/index.html')
 | 
			
		||||
def index(request):
 | 
			
		||||
    ctx = {}
 | 
			
		||||
    ctx['n_packaged'] = Package.objects.aggregate(Sum('n_packaged'))['n_packaged__sum']
 | 
			
		||||
    ctx['n_versions'] = Package.objects.aggregate(Sum('n_versions'))['n_versions__sum']
 | 
			
		||||
    if ctx['n_versions'] is not None and ctx['n_packaged'] is not None:
 | 
			
		||||
        ctx['n_upstream'] = ctx['n_versions'] - ctx['n_packaged']
 | 
			
		||||
    ctx['n_packaged'] = charts.xint(Package.objects.aggregate(Sum('n_packaged'))['n_packaged__sum'])
 | 
			
		||||
    ctx['n_overlay'] = charts.xint(Package.objects.aggregate(Sum('n_overlay'))['n_overlay__sum'])
 | 
			
		||||
    ctx['n_versions'] = charts.xint(Package.objects.aggregate(Sum('n_versions'))['n_versions__sum'])
 | 
			
		||||
    ctx['n_upstream'] = ctx['n_versions'] - ctx['n_packaged'] - ctx['n_overlay']
 | 
			
		||||
    ctx['n_packages'] = Package.objects.count()
 | 
			
		||||
    ctx['n_herds'] = Herd.objects.count()
 | 
			
		||||
    ctx['n_maintainers'] = Maintainer.objects.count()
 | 
			
		||||
@@ -25,7 +30,10 @@ def logs(request):
 | 
			
		||||
 | 
			
		||||
@render_to('euscan/categories.html')
 | 
			
		||||
def categories(request):
 | 
			
		||||
    categories = Package.objects.values('category').annotate(n_packaged=Sum('n_packaged'), n_versions=Sum('n_versions'))
 | 
			
		||||
    categories = Package.objects.values('category').annotate(n_packaged=Sum('n_packaged'),
 | 
			
		||||
                                                             n_overlay=Sum('n_overlay'),
 | 
			
		||||
                                                             n_versions=Sum('n_versions'))
 | 
			
		||||
 | 
			
		||||
    return { 'categories' : categories }
 | 
			
		||||
 | 
			
		||||
@render_to('euscan/category.html')
 | 
			
		||||
@@ -38,7 +46,10 @@ def category(request, category):
 | 
			
		||||
@render_to('euscan/herds.html')
 | 
			
		||||
def herds(request):
 | 
			
		||||
    # FIXME: optimize the query, it uses 'LEFT OUTER JOIN' instead of 'INNER JOIN'
 | 
			
		||||
    herds = Package.objects.filter(herds__isnull=False).values('herds__herd').annotate(n_packaged=Sum('n_packaged'), n_versions=Sum('n_versions'))
 | 
			
		||||
    herds = Package.objects.filter(herds__isnull=False)
 | 
			
		||||
    herds = herds.values('herds__herd').annotate(n_packaged=Sum('n_packaged'),
 | 
			
		||||
                                            n_overlay=Sum('n_overlay'),
 | 
			
		||||
                                            n_versions=Sum('n_versions'))
 | 
			
		||||
    return { 'herds' : herds }
 | 
			
		||||
 | 
			
		||||
@render_to('euscan/herd.html')
 | 
			
		||||
@@ -49,7 +60,12 @@ def herd(request, herd):
 | 
			
		||||
 | 
			
		||||
@render_to('euscan/maintainers.html')
 | 
			
		||||
def maintainers(request):
 | 
			
		||||
    maintainers = Package.objects.filter(maintainers__isnull=False).values('maintainers__id', 'maintainers__name').annotate(n_packaged=Sum('n_packaged'), n_versions=Sum('n_versions'))
 | 
			
		||||
    maintainers = Package.objects.filter(maintainers__isnull=False)
 | 
			
		||||
    maintainers = maintainers.values('maintainers__id', 'maintainers__name')
 | 
			
		||||
    maintainers = maintainers.annotate(n_packaged=Sum('n_packaged'),
 | 
			
		||||
                                       n_overlay=Sum('n_overlay'),
 | 
			
		||||
                                       n_versions=Sum('n_versions'))
 | 
			
		||||
 | 
			
		||||
    return { 'maintainers' : maintainers }
 | 
			
		||||
 | 
			
		||||
@render_to('euscan/maintainer.html')
 | 
			
		||||
@@ -61,6 +77,7 @@ def maintainer(request, maintainer_id):
 | 
			
		||||
@render_to('euscan/package.html')
 | 
			
		||||
def package(request, category, package):
 | 
			
		||||
    package = get_object_or_404(Package, category=category, name=package)
 | 
			
		||||
    package.homepages = package.homepage.split(' ')
 | 
			
		||||
    packaged = Version.objects.filter(package=package, packaged=True)
 | 
			
		||||
    upstream = Version.objects.filter(package=package, packaged=False)
 | 
			
		||||
    log = EuscanResult.objects.filter(package=package).order_by('-datetime')[:1]
 | 
			
		||||
@@ -99,8 +116,42 @@ def world_scan(request):
 | 
			
		||||
                packages.extend(Package.objects.filter(name=pkg))
 | 
			
		||||
        except:
 | 
			
		||||
            pass
 | 
			
		||||
    print packages
 | 
			
		||||
 | 
			
		||||
    return { 'packages' : packages }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@render_to("euscan/about.html")
 | 
			
		||||
def about(request):
 | 
			
		||||
    return {}
 | 
			
		||||
 | 
			
		||||
@render_to("euscan/statistics.html")
 | 
			
		||||
def statistics(request):
 | 
			
		||||
    return {}
 | 
			
		||||
 | 
			
		||||
def chart(request, **kwargs):
 | 
			
		||||
    from django.views.static import serve
 | 
			
		||||
 | 
			
		||||
    chart = kwargs['chart'] if 'chart' in kwargs else None
 | 
			
		||||
 | 
			
		||||
    if 'maintainer_id' in kwargs:
 | 
			
		||||
        kwargs['maintainer'] = get_object_or_404(Maintainer, id=kwargs['maintainer_id'])
 | 
			
		||||
    if 'herd' in kwargs:
 | 
			
		||||
        kwargs['herd'] = get_object_or_404(Herd, herd=kwargs['herd'])
 | 
			
		||||
 | 
			
		||||
    if chart == 'pie-packages':
 | 
			
		||||
        path = charts.pie_packages(**kwargs)
 | 
			
		||||
    elif chart == 'pie-versions':
 | 
			
		||||
        path = charts.pie_versions(**kwargs)
 | 
			
		||||
    else:
 | 
			
		||||
        raise Http404()
 | 
			
		||||
 | 
			
		||||
    return serve(request, path, document_root=charts.CHARTS_ROOT)
 | 
			
		||||
 | 
			
		||||
def chart_maintainer(request, **kwargs):
 | 
			
		||||
    return chart(request, **kwargs)
 | 
			
		||||
 | 
			
		||||
def chart_herd(request, **kwargs):
 | 
			
		||||
    return chart(request, **kwargs)
 | 
			
		||||
 | 
			
		||||
def chart_category(request, **kwargs):
 | 
			
		||||
    return chart(request, **kwargs)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										0
									
								
								euscanwww/media/charts/.keep_git
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								euscanwww/media/charts/.keep_git
									
									
									
									
									
										Normal file
									
								
							@@ -148,10 +148,6 @@ h1 {
 | 
			
		||||
	color:#15B100;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.bad {
 | 
			
		||||
	color:#FFFFFF;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
hr
 | 
			
		||||
{
 | 
			
		||||
  margin: 0.3em 1em 0.3em 1em;
 | 
			
		||||
@@ -230,3 +226,26 @@ th
 | 
			
		||||
    clear: both;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.package_stat {
 | 
			
		||||
    width: 40px;
 | 
			
		||||
    float: right;
 | 
			
		||||
    height: 5px;
 | 
			
		||||
    border: 1px solid #ccc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.package_stat div {
 | 
			
		||||
    float: left;
 | 
			
		||||
    height: 5px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.package_stat .packaged {
 | 
			
		||||
    background: #85ACFF;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.package_stat .overlay {
 | 
			
		||||
    background: #C6D9FD;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.package_stat .upstream {
 | 
			
		||||
    background: #FDEADD;
 | 
			
		||||
}
 | 
			
		||||
@@ -184,20 +184,12 @@ table.display td.center {
 | 
			
		||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 | 
			
		||||
 * DataTables row classes
 | 
			
		||||
 */
 | 
			
		||||
table.display tr.gradeA {
 | 
			
		||||
	background-color: #ddffdd;
 | 
			
		||||
table.display td.bad {
 | 
			
		||||
	background-color: #FFDFDF;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.display tr.gradeC {
 | 
			
		||||
	background-color: #ddddff;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.display tr.gradeX {
 | 
			
		||||
	background-color: #ffdddd;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.display tr.gradeU {
 | 
			
		||||
	background-color: #ddd;
 | 
			
		||||
table.display td.ugly {
 | 
			
		||||
	background-color: #EDB9B9;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
tr {
 | 
			
		||||
@@ -335,22 +327,6 @@ table.KeyTable td.focus {
 | 
			
		||||
	border: 3px solid #3366FF;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.display tr.gradeA {
 | 
			
		||||
	background-color: #eeffee;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.display tr.gradeC {
 | 
			
		||||
	background-color: #ddddff;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.display tr.gradeX {
 | 
			
		||||
	background-color: #ffdddd;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.display tr.gradeU {
 | 
			
		||||
	background-color: #ddd;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.box {
 | 
			
		||||
	height: 100px;
 | 
			
		||||
	padding: 10px;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								euscanwww/media/img/django.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								euscanwww/media/img/django.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 1.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								euscanwww/media/img/python.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								euscanwww/media/img/python.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 3.1 KiB  | 
@@ -106,5 +106,6 @@ INSTALLED_APPS = (
 | 
			
		||||
    'django.contrib.admin',
 | 
			
		||||
    # Uncomment the next line to enable admin documentation:
 | 
			
		||||
    # 'django.contrib.admindocs',
 | 
			
		||||
    'GChartWrapper.charts'
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -25,26 +25,23 @@
 | 
			
		||||
	  <li><a href="{% url euscan.views.categories %}">Categories</a></li>
 | 
			
		||||
	  <li><a href="{% url euscan.views.herds %}">Herds</a></li>
 | 
			
		||||
	  <li><a href="{% url euscan.views.maintainers %}">Maintainers</a></li>
 | 
			
		||||
	  <li><a href="{% url euscan.views.world %}">World</a></li>
 | 
			
		||||
	  <li><a href="{% url euscan.views.world %}">Scan World</a></li>
 | 
			
		||||
	  <li><a href="{% url euscan.views.statistics %}">Statistics</a></li>
 | 
			
		||||
	  <!--
 | 
			
		||||
	  <li>---</li>
 | 
			
		||||
	  <li><a href="#">Login</a></li>
 | 
			
		||||
	  <li><a href="#">Register</a></li>
 | 
			
		||||
	  -->
 | 
			
		||||
	  <li>---</li>
 | 
			
		||||
	  <li><a href="#">About</a></li>
 | 
			
		||||
	  <li><a href="{% url euscan.views.about %}">About</a></li>
 | 
			
		||||
	  {% endblock %}
 | 
			
		||||
	</ul>
 | 
			
		||||
      </div>
 | 
			
		||||
      {% endblock %}
 | 
			
		||||
    </div>
 | 
			
		||||
    <div id="footer">
 | 
			
		||||
      Powered by:
 | 
			
		||||
      <a href="http://kernel.org" titke="Linux Kernel">
 | 
			
		||||
	<img  src="{{MEDIA_URL}}img/linux.png" alt="Linux" />
 | 
			
		||||
      </a>
 | 
			
		||||
      <a href="http://gentoo.org" title="Gentoo">
 | 
			
		||||
	<img  src="{{MEDIA_URL}}img/gentoo.png" alt="Gentoo Linux" />
 | 
			
		||||
      </a>
 | 
			
		||||
      -
 | 
			
		||||
      Questions, Comments, Corrections ?
 | 
			
		||||
      Email: corentin.chary at gmail.com<br />
 | 
			
		||||
      Copyright (C) 2011 <strong>Corentin Chary</strong>
 | 
			
		||||
    </div>
 | 
			
		||||
  </body>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								euscanwww/templates/euscan/_package_bar.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								euscanwww/templates/euscan/_package_bar.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
{% load mul %}
 | 
			
		||||
{% load sub %}
 | 
			
		||||
{% load div %}
 | 
			
		||||
 | 
			
		||||
<div class="package_stat">
 | 
			
		||||
  <div class="packaged" style="width: {{ infos.n_packaged|mul:100.0|div:infos.n_versions }}%"></div>
 | 
			
		||||
  <div class="overlay" style="width: {{ infos.n_overlay|mul:100.0|div:infos.n_versions }}%"></div>
 | 
			
		||||
  <div class="upstream" style="width: {{ infos.n_versions|sub:infos.n_overlay|sub:infos.n_packaged|mul:100.0|div:infos.n_versions }}%"></div>
 | 
			
		||||
</div>
 | 
			
		||||
							
								
								
									
										24
									
								
								euscanwww/templates/euscan/_package_cols.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								euscanwww/templates/euscan/_package_cols.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
{% load packages %}
 | 
			
		||||
{% load mul %}
 | 
			
		||||
{% load sub %}
 | 
			
		||||
{% load div %}
 | 
			
		||||
 | 
			
		||||
<td>{{ infos.n_packaged }}</td>
 | 
			
		||||
{% if infos.n_overlay == 0 or infos.n_overlay <= infos.n_packaged %}
 | 
			
		||||
<td>
 | 
			
		||||
{% else %}{% if infos.n_overlay < infos.n_packaged %}
 | 
			
		||||
<td class="bad">
 | 
			
		||||
{% else %}
 | 
			
		||||
<td class="ugly">
 | 
			
		||||
{% endif %}{% endif %}
 | 
			
		||||
  {{ infos.n_overlay }}
 | 
			
		||||
</td>
 | 
			
		||||
{% if infos.n_versions == infos.n_packaged|add:infos.n_overlay %}
 | 
			
		||||
<td>
 | 
			
		||||
{% else %}{% if infos.n_versions < infos.n_packaged|add:infos.n_overlay|mul:2 %}
 | 
			
		||||
<td class="bad">
 | 
			
		||||
{% else %}
 | 
			
		||||
<td class="ugly">
 | 
			
		||||
{% endif %}{% endif %}
 | 
			
		||||
{{ infos.n_versions|sub:infos.n_packaged|sub:infos.n_overlay }}
 | 
			
		||||
</td>
 | 
			
		||||
@@ -1,28 +1,22 @@
 | 
			
		||||
{% load sub %}
 | 
			
		||||
{% load mul %}
 | 
			
		||||
{% load packages %}
 | 
			
		||||
 | 
			
		||||
<table id="table" class="display">
 | 
			
		||||
  <thead>
 | 
			
		||||
    <th>Package</th>
 | 
			
		||||
    <th>Ebuilds</th>
 | 
			
		||||
    <th>Gentoo</th>
 | 
			
		||||
    <th>Overlays</th>
 | 
			
		||||
    <th>Unpackaged</th>
 | 
			
		||||
  </thead>
 | 
			
		||||
  <tbody>
 | 
			
		||||
  {% for package in packages %}
 | 
			
		||||
  {% if package.n_versions == package.n_packaged %}
 | 
			
		||||
  <tr class="gradeA">
 | 
			
		||||
  {% else %}{% if package.n_versions < package.n_packaged|mul:2 %}
 | 
			
		||||
  <tr class="gradeC">
 | 
			
		||||
  {% else %}
 | 
			
		||||
  <tr class="gradeX">
 | 
			
		||||
  {% endif %}{% endif %}
 | 
			
		||||
  <tr>
 | 
			
		||||
    <td>
 | 
			
		||||
      <a href="{% url euscan.views.package package.category package.name %}">
 | 
			
		||||
	{{ package.category }}/{{ package.name }}
 | 
			
		||||
      </a>
 | 
			
		||||
      {% package_bar package %}
 | 
			
		||||
    </td>
 | 
			
		||||
    <td>{{ package.n_packaged }}</td>
 | 
			
		||||
    <td>{{ package.n_versions|sub:package.n_packaged }}</td>
 | 
			
		||||
    {% package_cols package %}
 | 
			
		||||
  </tr>
 | 
			
		||||
  {% endfor %}
 | 
			
		||||
  </tbody>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										37
									
								
								euscanwww/templates/euscan/about.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								euscanwww/templates/euscan/about.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
{% extends "_base.html" %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
<h2>What's euscan ?</h2>
 | 
			
		||||
<p>
 | 
			
		||||
Euscan is both a tool to check if an ebuild is outdated (app-portage/euscan) and a web interface.
 | 
			
		||||
</p>
 | 
			
		||||
<p>
 | 
			
		||||
This web interface allow you to browse the portage tree, and find outdated ebuilds. It is designed to help maintainers monitor their packages and bump them.
 | 
			
		||||
</p>
 | 
			
		||||
<p>
 | 
			
		||||
euscan code source is available at <a href="http://git.iksaif.net/?p=euscan.git;a=summary">http://git.iksaif.net/?p=euscan.git;a=summary</a>.
 | 
			
		||||
</p>
 | 
			
		||||
<p>
 | 
			
		||||
<em>This site is not an official Gentoo website.</em>
 | 
			
		||||
</p>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
  Copyright (C) 2011 <strong>Corentin Chary</strong>
 | 
			
		||||
</p>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
  Powered by:
 | 
			
		||||
  <a href="http://kernel.org" titke="Linux Kernel">
 | 
			
		||||
    <img  src="{{MEDIA_URL}}img/linux.png" alt="Linux Kernel" />
 | 
			
		||||
  </a>
 | 
			
		||||
  <a href="http://gentoo.org" title="Gentoo">
 | 
			
		||||
    <img  src="{{MEDIA_URL}}img/gentoo.png" alt="Gentoo Linux" />
 | 
			
		||||
  </a>
 | 
			
		||||
  <a href="http://www.djangoproject.com/" title="Django">
 | 
			
		||||
    <img  src="{{MEDIA_URL}}img/django.png" alt="Django" />
 | 
			
		||||
  </a>
 | 
			
		||||
  <a href="http://python.org" title="Python">
 | 
			
		||||
    <img  src="{{MEDIA_URL}}img/python.png" alt="Python" />
 | 
			
		||||
  </a>
 | 
			
		||||
</p>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
{% extends "euscan/_datatable.html" %}
 | 
			
		||||
 | 
			
		||||
{% load sub %}
 | 
			
		||||
{% load mul %}
 | 
			
		||||
{% load packages %}
 | 
			
		||||
 | 
			
		||||
{% block title %}
 | 
			
		||||
{{ block.super }} - categories
 | 
			
		||||
@@ -9,24 +8,22 @@
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
<h2>Categories</h2>
 | 
			
		||||
 | 
			
		||||
<table id="table" class="display">
 | 
			
		||||
  <thead>
 | 
			
		||||
    <th>Category</th>
 | 
			
		||||
    <th>Ebuilds</th>
 | 
			
		||||
    <th>Gentoo</th>
 | 
			
		||||
    <th>Overlays</th>
 | 
			
		||||
    <th>Unpackaged</th>
 | 
			
		||||
  </thead>
 | 
			
		||||
  <tbody>
 | 
			
		||||
  {% for category in categories %}
 | 
			
		||||
  {% if category.n_versions == category.n_packaged %}
 | 
			
		||||
  <tr class="gradeA">
 | 
			
		||||
  {% else %}{% if category.n_versions < category.n_packaged|mul:1.5 %}
 | 
			
		||||
  <tr class="gradeC">
 | 
			
		||||
  {% else %}
 | 
			
		||||
  <tr class="gradeX">
 | 
			
		||||
  {% endif %}{% endif %}
 | 
			
		||||
    <td><a href="{% url euscan.views.category category.category %}">{{ category.category }}</a></td>
 | 
			
		||||
    <td>{{ category.n_packaged }}</td>
 | 
			
		||||
    <td>{{ category.n_versions|sub:category.n_packaged }}</td>
 | 
			
		||||
  <tr>
 | 
			
		||||
    <td>
 | 
			
		||||
      <a href="{% url euscan.views.category category.category %}">{{ category.category }}</a>
 | 
			
		||||
      {% package_bar category %}
 | 
			
		||||
    </td>
 | 
			
		||||
    {% package_cols category %}
 | 
			
		||||
  </tr>
 | 
			
		||||
  {% endfor %}
 | 
			
		||||
  </tbody>
 | 
			
		||||
 
 | 
			
		||||
@@ -9,4 +9,9 @@
 | 
			
		||||
{% block content %}
 | 
			
		||||
<h2>Category: {{ category }}</h2>
 | 
			
		||||
{% packages packages %}
 | 
			
		||||
 | 
			
		||||
<h3>Statistics</h2>
 | 
			
		||||
<h4>Current statistics</h4>
 | 
			
		||||
<img src="{% url euscan.views.chart_category category 'pie-versions' %}" />
 | 
			
		||||
<img src="{% url euscan.views.chart_category category 'pie-packages' %}" />
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 
 | 
			
		||||
@@ -9,4 +9,9 @@
 | 
			
		||||
{% block content %}
 | 
			
		||||
<h2>Herd: {{ herd.herd }}</h2>
 | 
			
		||||
{% packages packages %}
 | 
			
		||||
 | 
			
		||||
<h3>Statistics</h2>
 | 
			
		||||
<h4>Current statistics</h4>
 | 
			
		||||
<img src="{% url euscan.views.chart_herd herd.herd 'pie-versions' %}" />
 | 
			
		||||
<img src="{% url euscan.views.chart_herd herd.herd 'pie-packages' %}" />
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
{% extends "euscan/_datatable.html" %}
 | 
			
		||||
 | 
			
		||||
{% load sub %}
 | 
			
		||||
{% load mul %}
 | 
			
		||||
{% load packages %}
 | 
			
		||||
 | 
			
		||||
{% block title %}
 | 
			
		||||
{{ block.super }} - herds
 | 
			
		||||
@@ -12,25 +11,20 @@
 | 
			
		||||
<table id="table" class="display">
 | 
			
		||||
  <thead>
 | 
			
		||||
    <th>Herd</th>
 | 
			
		||||
    <th>Ebuilds</th>
 | 
			
		||||
    <th>Gentoo</th>
 | 
			
		||||
    <th>Overlays</th>
 | 
			
		||||
    <th>Unpackaged</th>
 | 
			
		||||
  </thead>
 | 
			
		||||
  <tbody>
 | 
			
		||||
  {% for herd in herds %}
 | 
			
		||||
  {% if herd.n_versions == herd.n_packaged %}
 | 
			
		||||
  <tr class="gradeA">
 | 
			
		||||
  {% else %}{% if herd.n_versions < herd.n_packaged|mul:2 %}
 | 
			
		||||
  <tr class="gradeC">
 | 
			
		||||
  {% else %}
 | 
			
		||||
  <tr class="gradeX">
 | 
			
		||||
  {% endif %}{% endif %}
 | 
			
		||||
  <tr>
 | 
			
		||||
    <td>
 | 
			
		||||
      <a href="{% url euscan.views.herd herd.herds__herd %}">
 | 
			
		||||
	{{ herd.herds__herd }}
 | 
			
		||||
      </a>
 | 
			
		||||
      {% package_bar herd %}
 | 
			
		||||
    </td>
 | 
			
		||||
    <td>{{ herd.n_packaged }}</td>
 | 
			
		||||
    <td>{{ herd.n_versions|sub:herd.n_packaged }}</td>
 | 
			
		||||
    {% package_cols herd %}
 | 
			
		||||
  </tr>
 | 
			
		||||
  {% endfor %}
 | 
			
		||||
  </tbody>
 | 
			
		||||
 
 | 
			
		||||
@@ -8,12 +8,10 @@
 | 
			
		||||
Euscan is both a tool to check if an ebuild is outdated (app-portage/euscan) and a web interface.
 | 
			
		||||
</p>
 | 
			
		||||
<p>
 | 
			
		||||
This web interface allow you to browse the portage tree, and find outdated ebuilds. It was designed to help maintainers monitor their packages and bump them.
 | 
			
		||||
This web interface allow you to browse the portage tree, and find outdated ebuilds. It is designed to help maintainers monitor their packages and bump them.
 | 
			
		||||
</p>
 | 
			
		||||
<p>
 | 
			
		||||
euscan code source is available at <a href="http://git.iksaif.net/?p=euscan.git;a=summary">http://git.iksaif.net/?p=euscan.git;a=summary</a>.
 | 
			
		||||
</p>
 | 
			
		||||
<h2>Statistics</h2>
 | 
			
		||||
 | 
			
		||||
<h2>Overview</h2>
 | 
			
		||||
<ul>
 | 
			
		||||
  <li>Packages: {{ n_packages }}</li>
 | 
			
		||||
  <li>Versions: {{ n_packaged }}</li>
 | 
			
		||||
 
 | 
			
		||||
@@ -9,4 +9,10 @@
 | 
			
		||||
{% block content %}
 | 
			
		||||
<h2>Maintainer: {{ maintainer.name }} <{{ maintainer.email }}></h2>
 | 
			
		||||
{% packages packages %}
 | 
			
		||||
 | 
			
		||||
<h3>Statistics</h2>
 | 
			
		||||
<h4>Current statistics</h4>
 | 
			
		||||
<img src="{% url euscan.views.chart_maintainer maintainer.id 'pie-versions' %}" />
 | 
			
		||||
<img src="{% url euscan.views.chart_maintainer maintainer.id 'pie-packages' %}" />
 | 
			
		||||
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
{% extends "euscan/_datatable.html" %}
 | 
			
		||||
 | 
			
		||||
{% load sub %}
 | 
			
		||||
{% load mul %}
 | 
			
		||||
{% load packages %}
 | 
			
		||||
 | 
			
		||||
{% block title %}
 | 
			
		||||
{{ block.super }} - maintainers
 | 
			
		||||
@@ -12,25 +11,20 @@
 | 
			
		||||
<table id="table" class="display">
 | 
			
		||||
  <thead>
 | 
			
		||||
    <th>Maintainer</th>
 | 
			
		||||
    <th>Ebuilds</th>
 | 
			
		||||
    <th>Gentoo</th>
 | 
			
		||||
    <th>Overlays</th>
 | 
			
		||||
    <th>Unpackaged</th>
 | 
			
		||||
  </thead>
 | 
			
		||||
  <tbody>
 | 
			
		||||
  {% for maintainer in maintainers %}
 | 
			
		||||
  {% if maintainer.n_versions == maintainer.n_packaged %}
 | 
			
		||||
  <tr class="gradeA">
 | 
			
		||||
  {% else %}{% if maintainer.n_versions < maintainer.n_packaged|mul:2 %}
 | 
			
		||||
  <tr class="gradeC">
 | 
			
		||||
  {% else %}
 | 
			
		||||
  <tr class="gradeX">
 | 
			
		||||
  {% endif %}{% endif %}
 | 
			
		||||
  <tr>
 | 
			
		||||
    <td>
 | 
			
		||||
      <a href="{% url euscan.views.maintainer maintainer.maintainers__id %}">
 | 
			
		||||
	{{ maintainer.maintainers__name }}
 | 
			
		||||
      </a>
 | 
			
		||||
      {% package_bar maintainer %}
 | 
			
		||||
    </td>
 | 
			
		||||
    <td>{{ maintainer.n_packaged }}</td>
 | 
			
		||||
    <td>{{ maintainer.n_versions|sub:maintainer.n_packaged }}</td>
 | 
			
		||||
    {% package_cols maintainer %}
 | 
			
		||||
  </tr>
 | 
			
		||||
  {% endfor %}
 | 
			
		||||
  </tbody>
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@
 | 
			
		||||
  <dt>Homepage</dt>
 | 
			
		||||
  <dd>
 | 
			
		||||
    {% for homepage in package.homepages %}
 | 
			
		||||
    <a href="{{ homepage }}">{{ homepage }}<br />
 | 
			
		||||
    <a href="{{ homepage }}">{{ homepage }}</a><br />
 | 
			
		||||
    {% endfor %}
 | 
			
		||||
  </dd>
 | 
			
		||||
  {% endif %}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										13
									
								
								euscanwww/templates/euscan/statistics.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								euscanwww/templates/euscan/statistics.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
{% extends "_base.html" %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
<h2>What's euscan ?</h2>
 | 
			
		||||
<h2>Statistics</h2>
 | 
			
		||||
 | 
			
		||||
<h3>Current statistics</h3>
 | 
			
		||||
<img src="{% url euscan.views.chart 'pie-versions' %}" />
 | 
			
		||||
<img src="{% url euscan.views.chart 'pie-packages' %}" />
 | 
			
		||||
 | 
			
		||||
<h3>All time statistics</h3>
 | 
			
		||||
 | 
			
		||||
{% endblock %}
 | 
			
		||||
		Reference in New Issue
	
	Block a user