euscan-ng/euscanwww/djeuscan/models.py
volpino d1058aed8b euscanwww: initial implementation of euscan updates email
Signed-off-by: volpino <fox91@anche.no>
2012-08-11 15:09:42 +02:00

373 lines
11 KiB
Python

import json
from django.db import models
from django.core.validators import RegexValidator, validate_email, URLValidator
from django.core.exceptions import ValidationError
from django.contrib.auth.models import User
from djeuscan.managers import PackageManager, VersionLogManager, \
EuscanResultManager
validate_category = RegexValidator("^(?:\w+?-\w+?)|virtual$")
validate_name = RegexValidator("^\S+?$")
validate_revision = RegexValidator("^r\d+?$")
validate_url = URLValidator()
class Herd(models.Model):
"""
A herd is a collection of packages
"""
herd = models.CharField(max_length=128, unique=True,
validators=[validate_name])
email = models.CharField(max_length=128, blank=True, null=True,
validators=[validate_email])
maintainers = models.ManyToManyField("Maintainer")
def __unicode__(self):
if self.email:
return '%s <%s>' % (self.herd, self.email)
return self.herd
def save(self, *args, **kwargs):
self.full_clean()
super(Herd, self).save(*args, **kwargs)
class Maintainer(models.Model):
"""
The person who maintains a package
"""
name = models.CharField(max_length=128)
email = models.CharField(max_length=128, unique=True,
validators=[validate_email])
def __unicode__(self):
return '%s <%s>' % (self.name, self.email)
def save(self, *args, **kwargs):
self.full_clean()
super(Maintainer, self).save(*args, **kwargs)
class Package(models.Model):
"""
A portage package
"""
category = models.CharField(max_length=128, validators=[validate_category])
name = models.CharField(max_length=128, validators=[validate_name])
description = models.TextField(blank=True)
homepage = models.TextField(blank=True)
herds = models.ManyToManyField(Herd, blank=True)
maintainers = models.ManyToManyField(Maintainer, blank=True)
# 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)
# And we also pre-compute last versions
last_version_gentoo = models.ForeignKey(
'Version', blank=True, null=True, related_name="last_version_gentoo",
on_delete=models.SET_NULL
)
last_version_overlay = models.ForeignKey(
'Version', blank=True, null=True, related_name="last_version_overlay",
on_delete=models.SET_NULL
)
last_version_upstream = models.ForeignKey(
'Version', blank=True, null=True, related_name="last_version_upstream",
on_delete=models.SET_NULL
)
objects = PackageManager()
class Meta:
unique_together = ['category', 'name']
def cp(self):
return '%s/%s' % (self.category, self.name)
def __unicode__(self):
return self.cp()
def save(self, *args, **kwargs):
self.full_clean()
# Clean urls, accept only real urls
urls = []
for url in self.homepages:
try:
validate_url(url)
except ValidationError:
pass
else:
urls.append(url)
self.homepage = " ".join(urls)
super(Package, self).save(*args, **kwargs)
@property
def homepages(self):
return self.homepage.split(' ')
class Version(models.Model):
"""
Version associated to a package
"""
package = models.ForeignKey(Package)
slot = models.CharField(max_length=128, blank=True, default="")
revision = models.CharField(max_length=128)
version = models.CharField(max_length=128)
packaged = models.BooleanField()
overlay = models.CharField(max_length=128, default='gentoo', db_index=True,
validators=[validate_name], blank=True)
urls = models.TextField(blank=True)
alive = models.BooleanField(default=True, db_index=True)
vtype = models.CharField(max_length=128, blank=True)
handler = models.CharField(max_length=128, blank=True)
confidence = models.IntegerField(default=0)
ebuild_path = models.CharField(blank=True, max_length=256)
metadata_path = models.CharField(blank=True, max_length=256)
class Meta:
unique_together = ['package', 'slot', 'revision', 'version', 'overlay']
def cpv(self):
return '%s/%s-%s%s' % (
self.package.category, self.package.name, self.version,
'-' + self.revision if self.revision != '-r0' else ''
)
def __unicode__(self):
return '%s/%s-%s%s:%s [%s]' % (
self.package.category, self.package.name, self.version,
'-' + self.revision if self.revision != '-r0' else '',
self.slot, self.overlay or "<upstream>"
)
def save(self, *args, **kwargs):
self.full_clean()
super(Version, self).save(*args, **kwargs)
class VersionLog(models.Model):
VERSION_ADDED = 1
VERSION_REMOVED = 2
VERSION_ACTIONS = (
(VERSION_ADDED, 'Added'),
(VERSION_REMOVED, 'Removed')
)
package = models.ForeignKey(Package)
datetime = models.DateTimeField(auto_now_add=True)
slot = models.CharField(max_length=128, blank=True, default="")
revision = models.CharField(max_length=128)
version = models.CharField(max_length=128)
packaged = models.BooleanField()
overlay = models.CharField(max_length=128, default='gentoo',
validators=[validate_name], blank=True)
action = models.IntegerField(choices=VERSION_ACTIONS)
vtype = models.CharField(max_length=128, blank=True)
objects = VersionLogManager()
def __unicode__(self):
txt = '+ ' if self.action == self.VERSION_ADDED else '- '
txt += '%s/%s-%s-%s:%s [%s]' % (
self.package.category, self.package.name, self.version,
self.revision, self.slot,
self.overlay or '<upstream>'
)
return txt
def save(self, *args, **kwargs):
self.full_clean()
super(VersionLog, self).save(*args, **kwargs)
def tag(self):
return '%s-%s:%s-[%s]' % (self.version, self.revision, self.slot,
self.overlay)
class EuscanResult(models.Model):
package = models.ForeignKey(Package)
datetime = models.DateTimeField()
result = models.TextField(blank=True)
scan_time = models.FloatField(null=True, blank=True)
ebuild = models.CharField(blank=True, max_length=256)
objects = EuscanResultManager()
class Meta:
get_latest_by = "datetime"
def save(self, *args, **kwargs):
self.full_clean()
super(EuscanResult, self).save(*args, **kwargs)
@property
def messages(self):
try:
result = json.loads(self.result)
except ValueError:
return self.result
if result and self.package.cp() in result:
return result[self.package.cp()]['messages']
else:
return ""
def __unicode__(self):
return '[%s] %s/%s' % (
self.datetime, self.package.category, self.package.name
)
class Category(models.Model):
name = models.CharField(max_length=128, validators=[validate_category],
unique=True)
def __unicode__(self):
return self.name
class Overlay(models.Model):
name = models.CharField(max_length=128, validators=[validate_name],
unique=True)
def __unicode__(self):
return self.name
class UserProfile(models.Model):
EMAIL_SCAN = 1
EMAIL_WEEKLY = 2
EMAIL_MONTHLY = 3
EMAIL_OPTS = (
(EMAIL_SCAN, 'On updates'),
(EMAIL_WEEKLY, 'Weekly'),
(EMAIL_MONTHLY, 'Monthly')
)
user = models.OneToOneField(User)
herds = models.ManyToManyField(Herd)
maintainers = models.ManyToManyField(Maintainer)
packages = models.ManyToManyField(Package)
categories = models.ManyToManyField(Category)
overlays = models.ManyToManyField(Overlay)
feed_upstream_info = models.BooleanField(default=True)
feed_portage_info = models.BooleanField(default=False)
feed_show_adds = models.BooleanField(default=True)
feed_show_removals = models.BooleanField(default=True)
feed_ignore_pre = models.BooleanField(default=False)
feed_ignore_pre_if_stable = models.BooleanField(default=False)
email_activated = models.BooleanField(default=True)
email_every = models.IntegerField(choices=EMAIL_OPTS, default=EMAIL_SCAN)
email_ignore_pre = models.BooleanField(default=False)
email_ignore_pre_if_stable = models.BooleanField(default=False)
last_email = models.DateTimeField(auto_now_add=True)
class Log(models.Model):
"""
Model used for keeping data for charts
"""
datetime = models.DateTimeField()
# Packages up to date in the main portage tree
n_packages_gentoo = models.IntegerField(default=0)
# Packages up to date in an overlay
n_packages_overlay = models.IntegerField(default=0)
# Packages outdated
n_packages_outdated = models.IntegerField(default=0)
# Versions in the main portage tree
n_versions_gentoo = models.IntegerField(default=0)
# Versions in overlays
n_versions_overlay = models.IntegerField(default=0)
# Upstream versions, not in the main tree or overlays
n_versions_upstream = models.IntegerField(default=0)
def __unicode__(self):
return u'[%d:%d:%d] [%d:%d:%d]' % (
self.n_packages_gentoo, self.n_packages_overlay,
self.n_packages_outdated, self.n_versions_gentoo,
self.n_versions_overlay, self.n_versions_upstream
)
def save(self, *args, **kwargs):
self.full_clean()
super(Log, self).save(*args, **kwargs)
class WorldLog(Log):
def __unicode__(self):
return u'world ' + Log.__unicode__(self)
class CategoryLog(Log):
category = models.CharField(max_length=128, validators=[validate_category])
def __unicode__(self):
return u'%s %s' % (self.category, Log.__unicode__(self))
class HerdLog(Log):
herd = models.ForeignKey(Herd)
def __unicode__(self):
return u'%s %s' % (self.herd, Log.__unicode__(self))
class MaintainerLog(Log):
maintainer = models.ForeignKey(Maintainer)
def __unicode__(self):
return u'%s %s' % (self.maintainer, Log.__unicode__(self))
class RefreshPackageQuery(models.Model):
package = models.ForeignKey(Package)
priority = models.IntegerField(default=0)
users = models.ManyToManyField(User)
@property
def position(self):
ordered = RefreshPackageQuery.objects.all().order_by("-priority")
for pos, obj in enumerate(ordered, start=1):
if obj == self:
return pos
def __unicode__(self):
return u'[%d] %s' % (self.priority, self.package)
class ProblemReport(models.Model):
package = models.ForeignKey(Package)
version = models.ForeignKey(Version, null=True, blank=True)
subject = models.CharField(max_length=128)
message = models.TextField()
datetime = models.DateTimeField(auto_now_add=True)
def __unicode__(self):
return u"[%s] %s" % (self.datetime, self.package)