diff options
38 files changed, 880 insertions, 172 deletions
diff --git a/devel/admin.py b/devel/admin.py index 717ba1b2..5a704c0b 100644 --- a/devel/admin.py +++ b/devel/admin.py @@ -1,6 +1,18 @@ from django.contrib import admin +from django.contrib.auth.admin import UserAdmin +from django.contrib.auth.models import User -from .models import MasterKey, PGPSignature +from .models import UserProfile, MasterKey, PGPSignature + + +class UserProfileInline(admin.StackedInline): + model = UserProfile + + +class UserProfileAdmin(UserAdmin): + inlines = [UserProfileInline] + list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff', 'is_active') + list_filter = ('is_staff', 'is_superuser', 'is_active') class MasterKeyAdmin(admin.ModelAdmin): @@ -8,6 +20,7 @@ class MasterKeyAdmin(admin.ModelAdmin): search_fields = ('pgp_key', 'owner', 'revoker') date_hierarchy = 'created' + class PGPSignatureAdmin(admin.ModelAdmin): list_display = ('signer', 'signee', 'created', 'expires', 'valid') list_filter = ('valid',) @@ -15,6 +28,9 @@ class PGPSignatureAdmin(admin.ModelAdmin): date_hierarchy = 'created' +admin.site.unregister(User) +admin.site.register(User, UserProfileAdmin) + admin.site.register(MasterKey, MasterKeyAdmin) admin.site.register(PGPSignature, PGPSignatureAdmin) diff --git a/devel/fields.py b/devel/fields.py new file mode 100644 index 00000000..606ca63c --- /dev/null +++ b/devel/fields.py @@ -0,0 +1,30 @@ +from django.db import models +from django.core.validators import RegexValidator + + +class PGPKeyField(models.CharField): + _south_introspects = True + + def __init__(self, *args, **kwargs): + super(PGPKeyField, self).__init__(*args, **kwargs) + self.validators.append(RegexValidator(r'^[0-9A-F]{40}$', + "Ensure this value consists of 40 hex characters.", 'hex_char')) + + def to_python(self, value): + if value == '' or value is None: + return None + value = super(PGPKeyField, self).to_python(value) + # remove all spaces + value = value.replace(' ', '') + # prune prefixes, either 0x or 2048R/ type + if value.startswith('0x'): + value = value[2:] + value = value.split('/')[-1] + # make all (hex letters) uppercase + return value.upper() + + def formfield(self, **kwargs): + # override so we don't set max_length form field attribute + return models.Field.formfield(self, **kwargs) + +# vim: set ts=4 sw=4 et: diff --git a/devel/management/commands/generate_keyring.py b/devel/management/commands/generate_keyring.py index 062c738b..b9117c84 100644 --- a/devel/management/commands/generate_keyring.py +++ b/devel/management/commands/generate_keyring.py @@ -13,8 +13,7 @@ import logging import subprocess import sys -from devel.models import MasterKey -from main.models import UserProfile +from devel.models import MasterKey, UserProfile logging.basicConfig( level=logging.INFO, diff --git a/devel/migrations/0002_auto__add_masterkey.py b/devel/migrations/0002_auto__add_masterkey.py index ac1f745a..ba9a3e5f 100644 --- a/devel/migrations/0002_auto__add_masterkey.py +++ b/devel/migrations/0002_auto__add_masterkey.py @@ -15,7 +15,7 @@ class Migration(SchemaMigration): ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ('owner', self.gf('django.db.models.fields.related.ForeignKey')(related_name='masterkey_owner', to=orm['auth.User'])), ('revoker', self.gf('django.db.models.fields.related.ForeignKey')(related_name='masterkey_revoker', to=orm['auth.User'])), - ('pgp_key', self.gf('main.fields.PGPKeyField')(max_length=40)), + ('pgp_key', self.gf('devel.fields.PGPKeyField')(max_length=40)), ('created', self.gf('django.db.models.fields.DateTimeField')()), ('revoked', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)), )) @@ -67,7 +67,7 @@ class Migration(SchemaMigration): 'created': ('django.db.models.fields.DateTimeField', [], {}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'masterkey_owner'", 'to': "orm['auth.User']"}), - 'pgp_key': ('main.fields.PGPKeyField', [], {'max_length': '40'}), + 'pgp_key': ('devel.fields.PGPKeyField', [], {'max_length': '40'}), 'revoked': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), 'revoker': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'masterkey_revoker'", 'to': "orm['auth.User']"}) } diff --git a/devel/migrations/0003_auto__add_pgpsignature.py b/devel/migrations/0003_auto__add_pgpsignature.py index f9ac5021..e16de1ca 100644 --- a/devel/migrations/0003_auto__add_pgpsignature.py +++ b/devel/migrations/0003_auto__add_pgpsignature.py @@ -8,8 +8,8 @@ class Migration(SchemaMigration): def forwards(self, orm): db.create_table('devel_pgpsignature', ( ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('signer', self.gf('main.fields.PGPKeyField')(max_length=40)), - ('signee', self.gf('main.fields.PGPKeyField')(max_length=40)), + ('signer', self.gf('devel.fields.PGPKeyField')(max_length=40)), + ('signee', self.gf('devel.fields.PGPKeyField')(max_length=40)), ('created', self.gf('django.db.models.fields.DateField')()), ('expires', self.gf('django.db.models.fields.DateField')(null=True)), ('valid', self.gf('django.db.models.fields.BooleanField')(default=True)), @@ -63,7 +63,7 @@ class Migration(SchemaMigration): 'created': ('django.db.models.fields.DateTimeField', [], {}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'masterkey_owner'", 'to': "orm['auth.User']"}), - 'pgp_key': ('main.fields.PGPKeyField', [], {'max_length': '40'}), + 'pgp_key': ('devel.fields.PGPKeyField', [], {'max_length': '40'}), 'revoked': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), 'revoker': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'masterkey_revoker'", 'to': "orm['auth.User']"}) }, @@ -72,8 +72,8 @@ class Migration(SchemaMigration): 'created': ('django.db.models.fields.DateField', [], {}), 'expires': ('django.db.models.fields.DateField', [], {'null': 'True'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'signee': ('main.fields.PGPKeyField', [], {'max_length': '40'}), - 'signer': ('main.fields.PGPKeyField', [], {'max_length': '40'}), + 'signee': ('devel.fields.PGPKeyField', [], {'max_length': '40'}), + 'signer': ('devel.fields.PGPKeyField', [], {'max_length': '40'}), 'valid': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) } } diff --git a/devel/migrations/0004_masterkey_dates.py b/devel/migrations/0004_masterkey_dates.py index dc7750dc..f2020dd7 100644 --- a/devel/migrations/0004_masterkey_dates.py +++ b/devel/migrations/0004_masterkey_dates.py @@ -56,7 +56,7 @@ class Migration(SchemaMigration): 'created': ('django.db.models.fields.DateField', [], {}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'masterkey_owner'", 'to': "orm['auth.User']"}), - 'pgp_key': ('main.fields.PGPKeyField', [], {'max_length': '40'}), + 'pgp_key': ('devel.fields.PGPKeyField', [], {'max_length': '40'}), 'revoked': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), 'revoker': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'masterkey_revoker'", 'to': "orm['auth.User']"}) }, @@ -65,8 +65,8 @@ class Migration(SchemaMigration): 'created': ('django.db.models.fields.DateField', [], {}), 'expires': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'signee': ('main.fields.PGPKeyField', [], {'max_length': '40'}), - 'signer': ('main.fields.PGPKeyField', [], {'max_length': '40'}), + 'signee': ('devel.fields.PGPKeyField', [], {'max_length': '40'}), + 'signer': ('devel.fields.PGPKeyField', [], {'max_length': '40'}), 'valid': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) } } diff --git a/devel/migrations/0005_auto__add_userprofile.py b/devel/migrations/0005_auto__add_userprofile.py new file mode 100644 index 00000000..ff6f9785 --- /dev/null +++ b/devel/migrations/0005_auto__add_userprofile.py @@ -0,0 +1,113 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + depends_on = ( + ('main', '0059_auto__del_userprofile'), + ) + + def forwards(self, orm): + if not db.dry_run: + db.send_create_signal('devel', ['UserProfile']) + orm['contenttypes.ContentType'].objects.filter( + app_label='main', model='userprofile').update( + app_label='devel') + + def backwards(self, orm): + pass + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'devel.masterkey': { + 'Meta': {'ordering': "('created',)", 'object_name': 'MasterKey'}, + 'created': ('django.db.models.fields.DateField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'masterkey_owner'", 'to': "orm['auth.User']"}), + 'pgp_key': ('devel.fields.PGPKeyField', [], {'max_length': '40'}), + 'revoked': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'revoker': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'masterkey_revoker'", 'to': "orm['auth.User']"}) + }, + 'devel.pgpsignature': { + 'Meta': {'object_name': 'PGPSignature'}, + 'created': ('django.db.models.fields.DateField', [], {}), + 'expires': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'signee': ('devel.fields.PGPKeyField', [], {'max_length': '40'}), + 'signer': ('devel.fields.PGPKeyField', [], {'max_length': '40'}), + 'valid': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + 'devel.userprofile': { + 'Meta': {'object_name': 'UserProfile', 'db_table': "'user_profiles'"}, + 'alias': ('django.db.models.fields.CharField', [], {'max_length': '50'}), + 'allowed_repos': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['main.Repo']", 'symmetrical': 'False', 'blank': 'True'}), + 'favorite_distros': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'interests': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'languages': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), + 'latin_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'location': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), + 'notify': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'occupation': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), + 'other_contact': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'pgp_key': ('devel.fields.PGPKeyField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), + 'picture': ('django.db.models.fields.files.FileField', [], {'default': "'devs/silhouette.png'", 'max_length': '100'}), + 'public_email': ('django.db.models.fields.CharField', [], {'max_length': '50'}), + 'roles': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'time_zone': ('django.db.models.fields.CharField', [], {'default': "'UTC'", 'max_length': '100'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'userprofile'", 'unique': 'True', 'to': "orm['auth.User']"}), + 'website': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'yob': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}) + }, + 'main.repo': { + 'Meta': {'ordering': "['name']", 'object_name': 'Repo', 'db_table': "'repos'"}, + 'bugs_category': ('django.db.models.fields.SmallIntegerField', [], {'default': '2'}), + 'bugs_project': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'staging': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'svn_root': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'testing': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) + } + } + + complete_apps = ['devel'] diff --git a/devel/models.py b/devel/models.py index 2fc61060..79c56f2a 100644 --- a/devel/models.py +++ b/devel/models.py @@ -1,8 +1,66 @@ # -*- coding: utf-8 -*- +import pytz + from django.db import models from django.contrib.auth.models import User -from main.fields import PGPKeyField +from .fields import PGPKeyField +from main.utils import make_choice + + +class UserProfile(models.Model): + notify = models.BooleanField( + "Send notifications", + default=True, + help_text="When enabled, send user 'flag out-of-date' notifications") + time_zone = models.CharField( + max_length=100, + choices=make_choice(pytz.common_timezones), + default="UTC", + help_text="Used for developer clock page") + alias = models.CharField( + max_length=50, + help_text="Required field") + public_email = models.CharField( + max_length=50, + help_text="Required field") + other_contact = models.CharField(max_length=100, null=True, blank=True) + pgp_key = PGPKeyField(max_length=40, null=True, blank=True, + verbose_name="PGP key fingerprint", + help_text="consists of 40 hex digits; use `gpg --fingerprint`") + website = models.CharField(max_length=200, null=True, blank=True) + yob = models.IntegerField("Year of birth", null=True, blank=True) + location = models.CharField(max_length=50, null=True, blank=True) + languages = models.CharField(max_length=50, null=True, blank=True) + interests = models.CharField(max_length=255, null=True, blank=True) + occupation = models.CharField(max_length=50, null=True, blank=True) + roles = models.CharField(max_length=255, null=True, blank=True) + favorite_distros = models.CharField(max_length=255, null=True, blank=True) + picture = models.FileField(upload_to='devs', default='devs/silhouette.png', + help_text="Ideally 125px by 125px") + user = models.OneToOneField(User, related_name='userprofile') + allowed_repos = models.ManyToManyField('main.Repo', blank=True) + latin_name = models.CharField(max_length=255, null=True, blank=True, + help_text="Latin-form name; used only for non-Latin full names") + + class Meta: + db_table = 'user_profiles' + verbose_name = 'Additional Profile Data' + verbose_name_plural = 'Additional Profile Data' + + def get_absolute_url(self): + # TODO: this is disgusting. find a way to consolidate this logic with + # public.views.userlist among other places, and make some constants or + # something so we aren't using copies of string names everywhere. + group_names = self.user.groups.values_list('name', flat=True) + if "Developers" in group_names: + prefix = "developers" + elif "Trusted Users" in group_names: + prefix = "trustedusers" + else: + prefix = "fellows" + return '/%s/#%s' % (prefix, self.user.username) + class MasterKey(models.Model): diff --git a/devel/tests.py b/devel/tests.py index 01eed0fc..5c736a30 100644 --- a/devel/tests.py +++ b/devel/tests.py @@ -1,8 +1,8 @@ +from django.contrib.auth.models import User from django.test import TestCase -from django.contrib.auth.models import User -from devel.utils import UserFinder -from main.models import UserProfile +from .utils import UserFinder +from .models import UserProfile class DevelTest(TestCase): def test_index(self): diff --git a/devel/views.py b/devel/views.py index 2b003bf7..0b9f8f18 100644 --- a/devel/views.py +++ b/devel/views.py @@ -22,8 +22,9 @@ from django.views.decorators.cache import never_cache from django.views.generic.simple import direct_to_template from django.utils.http import http_date +from .models import UserProfile from main.models import Package, PackageDepend, PackageFile, TodolistPkg -from main.models import Arch, Repo, UserProfile +from main.models import Arch, Repo from main.utils import utc_now from packages.models import PackageRelation from packages.utils import get_signoff_groups @@ -160,8 +161,8 @@ def report(request, report_name, username=None): type=PackageRelation.MAINTAINER).values('user')) if report_name == 'old': - title = 'Packages last built more than two years ago' - cutoff = utc_now() - timedelta(days=365 * 2) + title = 'Packages last built more than one year ago' + cutoff = utc_now() - timedelta(days=365) packages = packages.filter( build_date__lt=cutoff).order_by('build_date') elif report_name == 'long-out-of-date': diff --git a/main/admin.py b/main/admin.py index 783d07e4..741f6665 100644 --- a/main/admin.py +++ b/main/admin.py @@ -1,7 +1,5 @@ from django.contrib import admin -from django.contrib.auth.models import User -from django.contrib.auth.admin import UserAdmin -from main.models import Arch, Donor, Package, Repo, Todolist, UserProfile +from main.models import Arch, Donor, Package, Repo, Todolist class DonorAdmin(admin.ModelAdmin): list_display = ('name', 'visible', 'created') @@ -31,17 +29,7 @@ class TodolistAdmin(admin.ModelAdmin): list_display = ('name', 'date_added', 'creator', 'description') search_fields = ('name', 'description') -admin.site.unregister(User) -class UserProfileInline(admin.StackedInline): - model = UserProfile -class UserProfileAdmin(UserAdmin): - inlines = [UserProfileInline] - list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff', 'is_active') - list_filter = ('is_staff', 'is_superuser', 'is_active') - - -admin.site.register(User, UserProfileAdmin) admin.site.register(Donor, DonorAdmin) admin.site.register(Package, PackageAdmin) diff --git a/main/fields.py b/main/fields.py index 948cb5d9..2d5703ef 100644 --- a/main/fields.py +++ b/main/fields.py @@ -1,5 +1,4 @@ from django.db import models -from django.core.validators import RegexValidator class PositiveBigIntegerField(models.BigIntegerField): @@ -13,30 +12,4 @@ class PositiveBigIntegerField(models.BigIntegerField): defaults.update(kwargs) return super(PositiveBigIntegerField, self).formfield(**defaults) -class PGPKeyField(models.CharField): - _south_introspects = True - - def __init__(self, *args, **kwargs): - super(PGPKeyField, self).__init__(*args, **kwargs) - self.validators.append(RegexValidator(r'^[0-9A-F]{40}$', - "Ensure this value consists of 40 hex characters.", 'hex_char')) - - def to_python(self, value): - if value == '' or value is None: - return None - value = super(PGPKeyField, self).to_python(value) - # remove all spaces - value = value.replace(' ', '') - # prune prefixes, either 0x or 2048R/ type - if value.startswith('0x'): - value = value[2:] - value = value.split('/')[-1] - # make all (hex letters) uppercase - return value.upper() - - def formfield(self, **kwargs): - # override so we don't set max_length form field attribute - return models.Field.formfield(self, **kwargs) - - # vim: set ts=4 sw=4 et: diff --git a/main/fixtures/groups.json b/main/fixtures/groups.json index 0a3c966c..60db1635 100644 --- a/main/fixtures/groups.json +++ b/main/fixtures/groups.json @@ -422,12 +422,12 @@ ], [ "add_userprofile", - "main", + "devel", "userprofile" ], [ "change_userprofile", - "main", + "devel", "userprofile" ] ] diff --git a/main/migrations/0030_move_mirror_models.py b/main/migrations/0030_move_mirror_models.py index 998ff6a2..1fe0c7e9 100644 --- a/main/migrations/0030_move_mirror_models.py +++ b/main/migrations/0030_move_mirror_models.py @@ -6,10 +6,6 @@ from django.db import models class Migration(SchemaMigration): - depends_on = ( - ('mirrors', '0002_rename_model_tables'), - ) - def forwards(self, orm): pass diff --git a/main/migrations/0031_move_news_out.py b/main/migrations/0031_move_news_out.py index a730f4f3..28f4b750 100644 --- a/main/migrations/0031_move_news_out.py +++ b/main/migrations/0031_move_news_out.py @@ -6,10 +6,6 @@ from django.db import models class Migration(SchemaMigration): - depends_on = ( - ('news', '0002_move_news_in'), - ) - def forwards(self, orm): pass diff --git a/main/migrations/0034_update_content_type.py b/main/migrations/0034_update_content_type.py index 779021da..59c6f6ad 100644 --- a/main/migrations/0034_update_content_type.py +++ b/main/migrations/0034_update_content_type.py @@ -5,31 +5,15 @@ from south.v2 import DataMigration from django.db import models class Migration(DataMigration): - - depends_on = ( - ('mirrors', '0002_rename_model_tables'), - ('news', '0002_move_news_in'), - ) - - mirror_apps = [ 'mirror', 'mirrorprotocol', 'mirrorurl', 'mirrorrsync' ] + '''This is a defunct migration now, things have been moved to their proper + places, but removing it would cause all existing setups migrated past this + to complain.''' def forwards(self, orm): - ct = orm['contenttypes.ContentType'].objects - - # somehow these got in there already; remove them in favor of the old - ct.filter(app_label='news').delete() - ct.filter(app_label='mirrors').delete() - - ct.filter(app_label='main', model='news').update(app_label='news') - ct.filter(app_label='main', model__in=self.mirror_apps).update( - app_label='mirrors') + pass def backwards(self, orm): - ct = orm['contenttypes.ContentType'].objects - - ct.filter(app_label='mirrors', model__in=self.mirror_apps).update( - app_label='main') - ct.filter(app_label='news', model='news').update(app_label='main') + pass models = { 'auth.group': { diff --git a/main/migrations/0051_auto__chg_field_userprofile_pgp_key.py b/main/migrations/0051_auto__chg_field_userprofile_pgp_key.py index 6b8abf6e..4905eb80 100644 --- a/main/migrations/0051_auto__chg_field_userprofile_pgp_key.py +++ b/main/migrations/0051_auto__chg_field_userprofile_pgp_key.py @@ -7,7 +7,7 @@ from django.db import models class Migration(SchemaMigration): def forwards(self, orm): - db.alter_column('user_profiles', 'pgp_key', self.gf('main.models.PGPKeyField')(max_length=40, null=True)) + db.alter_column('user_profiles', 'pgp_key', self.gf('devel.fields.PGPKeyField')(max_length=40, null=True)) def backwards(self, orm): @@ -146,7 +146,7 @@ class Migration(SchemaMigration): 'notify': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), 'occupation': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), 'other_contact': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), - 'pgp_key': ('main.models.PGPKeyField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), + 'pgp_key': ('devel.fields.PGPKeyField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), 'picture': ('django.db.models.fields.files.FileField', [], {'default': "'devs/silhouette.png'", 'max_length': '100'}), 'public_email': ('django.db.models.fields.CharField', [], {'max_length': '50'}), 'roles': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), diff --git a/main/migrations/0052_auto__del_signoff.py b/main/migrations/0052_auto__del_signoff.py index 8da6becc..a9ee633e 100644 --- a/main/migrations/0052_auto__del_signoff.py +++ b/main/migrations/0052_auto__del_signoff.py @@ -152,7 +152,7 @@ class Migration(SchemaMigration): 'notify': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), 'occupation': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), 'other_contact': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), - 'pgp_key': ('main.models.PGPKeyField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), + 'pgp_key': ('devel.fields.PGPKeyField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), 'picture': ('django.db.models.fields.files.FileField', [], {'default': "'devs/silhouette.png'", 'max_length': '100'}), 'public_email': ('django.db.models.fields.CharField', [], {'max_length': '50'}), 'roles': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), diff --git a/main/migrations/0053_auto__add_field_package_pgp_signature.py b/main/migrations/0053_auto__add_field_package_pgp_signature.py index a828d1ef..a3df5266 100644 --- a/main/migrations/0053_auto__add_field_package_pgp_signature.py +++ b/main/migrations/0053_auto__add_field_package_pgp_signature.py @@ -138,7 +138,7 @@ class Migration(SchemaMigration): 'notify': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), 'occupation': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), 'other_contact': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), - 'pgp_key': ('main.models.PGPKeyField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), + 'pgp_key': ('devel.fields.PGPKeyField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), 'picture': ('django.db.models.fields.files.FileField', [], {'default': "'devs/silhouette.png'", 'max_length': '100'}), 'public_email': ('django.db.models.fields.CharField', [], {'max_length': '50'}), 'roles': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), diff --git a/main/migrations/0054_auto__add_field_donor_created.py b/main/migrations/0054_auto__add_field_donor_created.py index c96c0f5d..81946c36 100644 --- a/main/migrations/0054_auto__add_field_donor_created.py +++ b/main/migrations/0054_auto__add_field_donor_created.py @@ -146,7 +146,7 @@ class Migration(SchemaMigration): 'notify': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), 'occupation': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), 'other_contact': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), - 'pgp_key': ('main.models.PGPKeyField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), + 'pgp_key': ('devel.fields.PGPKeyField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), 'picture': ('django.db.models.fields.files.FileField', [], {'default': "'devs/silhouette.png'", 'max_length': '100'}), 'public_email': ('django.db.models.fields.CharField', [], {'max_length': '50'}), 'roles': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), diff --git a/main/migrations/0055_unique_package_in_repo.py b/main/migrations/0055_unique_package_in_repo.py index 63951a08..36cc7193 100644 --- a/main/migrations/0055_unique_package_in_repo.py +++ b/main/migrations/0055_unique_package_in_repo.py @@ -141,7 +141,7 @@ class Migration(SchemaMigration): 'notify': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), 'occupation': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), 'other_contact': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), - 'pgp_key': ('main.models.PGPKeyField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), + 'pgp_key': ('devel.fields.PGPKeyField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), 'picture': ('django.db.models.fields.files.FileField', [], {'default': "'devs/silhouette.png'", 'max_length': '100'}), 'public_email': ('django.db.models.fields.CharField', [], {'max_length': '50'}), 'roles': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), diff --git a/main/migrations/0056_auto__chg_field_package_pkgdesc.py b/main/migrations/0056_auto__chg_field_package_pkgdesc.py index 21dd43af..90856fab 100644 --- a/main/migrations/0056_auto__chg_field_package_pkgdesc.py +++ b/main/migrations/0056_auto__chg_field_package_pkgdesc.py @@ -139,7 +139,7 @@ class Migration(SchemaMigration): 'notify': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), 'occupation': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), 'other_contact': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), - 'pgp_key': ('main.models.PGPKeyField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), + 'pgp_key': ('devel.fields.PGPKeyField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), 'picture': ('django.db.models.fields.files.FileField', [], {'default': "'devs/silhouette.png'", 'max_length': '100'}), 'public_email': ('django.db.models.fields.CharField', [], {'max_length': '50'}), 'roles': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), diff --git a/main/migrations/0057_auto__add_field_userprofile_latin_name.py b/main/migrations/0057_auto__add_field_userprofile_latin_name.py index ffde1885..b9328af0 100644 --- a/main/migrations/0057_auto__add_field_userprofile_latin_name.py +++ b/main/migrations/0057_auto__add_field_userprofile_latin_name.py @@ -139,7 +139,7 @@ class Migration(SchemaMigration): 'notify': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), 'occupation': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), 'other_contact': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), - 'pgp_key': ('main.models.PGPKeyField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), + 'pgp_key': ('devel.fields.PGPKeyField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), 'picture': ('django.db.models.fields.files.FileField', [], {'default': "'devs/silhouette.png'", 'max_length': '100'}), 'public_email': ('django.db.models.fields.CharField', [], {'max_length': '50'}), 'roles': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), diff --git a/main/migrations/0058_auto__add_on_delete_attributes.py b/main/migrations/0058_auto__add_on_delete_attributes.py new file mode 100644 index 00000000..e66e4da2 --- /dev/null +++ b/main/migrations/0058_auto__add_on_delete_attributes.py @@ -0,0 +1,160 @@ +# -*- coding: utf-8 -*- +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + db.alter_column('todolists', 'creator_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], on_delete=models.PROTECT)) + db.alter_column('packages', 'repo_id', self.gf('django.db.models.fields.related.ForeignKey')(on_delete=models.PROTECT, to=orm['main.Repo'])) + db.alter_column('packages', 'packager_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True, on_delete=models.SET_NULL)) + db.alter_column('packages', 'arch_id', self.gf('django.db.models.fields.related.ForeignKey')(on_delete=models.PROTECT, to=orm['main.Arch'])) + + def backwards(self, orm): + db.alter_column('todolists', 'creator_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])) + db.alter_column('packages', 'repo_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['main.Repo'])) + db.alter_column('packages', 'packager_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True)) + db.alter_column('packages', 'arch_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['main.Arch'])) + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'main.arch': { + 'Meta': {'ordering': "['name']", 'object_name': 'Arch', 'db_table': "'arches'"}, + 'agnostic': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}) + }, + 'main.donor': { + 'Meta': {'ordering': "('name',)", 'object_name': 'Donor', 'db_table': "'donors'"}, + 'created': ('django.db.models.fields.DateTimeField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'visible': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + 'main.package': { + 'Meta': {'ordering': "('pkgname',)", 'unique_together': "(('pkgname', 'repo', 'arch'),)", 'object_name': 'Package', 'db_table': "'packages'"}, + 'arch': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'packages'", 'on_delete': 'models.PROTECT', 'to': "orm['main.Arch']"}), + 'build_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), + 'compressed_size': ('main.fields.PositiveBigIntegerField', [], {}), + 'epoch': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'filename': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'files_last_update': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'flag_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'installed_size': ('main.fields.PositiveBigIntegerField', [], {}), + 'last_update': ('django.db.models.fields.DateTimeField', [], {}), + 'packager': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'on_delete': 'models.SET_NULL'}), + 'packager_str': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pgp_signature': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'pkgbase': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'pkgdesc': ('django.db.models.fields.TextField', [], {'null': 'True'}), + 'pkgname': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pkgrel': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pkgver': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'repo': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'packages'", 'on_delete': 'models.PROTECT', 'to': "orm['main.Repo']"}), + 'url': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}) + }, + 'main.packagedepend': { + 'Meta': {'object_name': 'PackageDepend', 'db_table': "'package_depends'"}, + 'depname': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'depvcmp': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}), + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'optional': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'pkg': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'depends'", 'to': "orm['main.Package']"}) + }, + 'main.packagefile': { + 'Meta': {'object_name': 'PackageFile', 'db_table': "'package_files'"}, + 'directory': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'filename': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_directory': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'pkg': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Package']"}) + }, + 'main.repo': { + 'Meta': {'ordering': "['name']", 'object_name': 'Repo', 'db_table': "'repos'"}, + 'bugs_category': ('django.db.models.fields.SmallIntegerField', [], {'default': '2'}), + 'bugs_project': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'staging': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'svn_root': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'testing': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) + }, + 'main.todolist': { + 'Meta': {'object_name': 'Todolist', 'db_table': "'todolists'"}, + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'on_delete': 'models.PROTECT'}), + 'date_added': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + 'main.todolistpkg': { + 'Meta': {'unique_together': "(('list', 'pkg'),)", 'object_name': 'TodolistPkg', 'db_table': "'todolist_pkgs'"}, + 'complete': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'list': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Todolist']"}), + 'pkg': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Package']"}) + }, + 'main.userprofile': { + 'Meta': {'object_name': 'UserProfile', 'db_table': "'user_profiles'"}, + 'alias': ('django.db.models.fields.CharField', [], {'max_length': '50'}), + 'allowed_repos': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['main.Repo']", 'symmetrical': 'False', 'blank': 'True'}), + 'favorite_distros': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'interests': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'languages': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), + 'latin_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'location': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), + 'notify': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'occupation': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), + 'other_contact': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'pgp_key': ('devel.fields.PGPKeyField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), + 'picture': ('django.db.models.fields.files.FileField', [], {'default': "'devs/silhouette.png'", 'max_length': '100'}), + 'public_email': ('django.db.models.fields.CharField', [], {'max_length': '50'}), + 'roles': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'time_zone': ('django.db.models.fields.CharField', [], {'default': "'UTC'", 'max_length': '100'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'userprofile'", 'unique': 'True', 'to': "orm['auth.User']"}), + 'website': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'yob': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}) + } + } + + complete_apps = ['main'] diff --git a/main/migrations/0059_auto__del_userprofile.py b/main/migrations/0059_auto__del_userprofile.py new file mode 100644 index 00000000..2db87eeb --- /dev/null +++ b/main/migrations/0059_auto__del_userprofile.py @@ -0,0 +1,137 @@ +# -*- coding: 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): + pass + + def backwards(self, orm): + if not db.dry_run: + db.send_create_signal('main', ['UserProfile']) + orm['contenttypes.ContentType'].objects.filter( + app_label='devel', model='userprofile').update( + app_label='main') + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'main.arch': { + 'Meta': {'ordering': "['name']", 'object_name': 'Arch', 'db_table': "'arches'"}, + 'agnostic': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}) + }, + 'main.donor': { + 'Meta': {'ordering': "('name',)", 'object_name': 'Donor', 'db_table': "'donors'"}, + 'created': ('django.db.models.fields.DateTimeField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'visible': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + 'main.package': { + 'Meta': {'ordering': "('pkgname',)", 'unique_together': "(('pkgname', 'repo', 'arch'),)", 'object_name': 'Package', 'db_table': "'packages'"}, + 'arch': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'packages'", 'on_delete': 'models.PROTECT', 'to': "orm['main.Arch']"}), + 'build_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), + 'compressed_size': ('main.fields.PositiveBigIntegerField', [], {}), + 'epoch': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'filename': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'files_last_update': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'flag_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'installed_size': ('main.fields.PositiveBigIntegerField', [], {}), + 'last_update': ('django.db.models.fields.DateTimeField', [], {}), + 'packager': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'on_delete': 'models.SET_NULL'}), + 'packager_str': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pgp_signature': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'pkgbase': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'pkgdesc': ('django.db.models.fields.TextField', [], {'null': 'True'}), + 'pkgname': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pkgrel': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pkgver': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'repo': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'packages'", 'on_delete': 'models.PROTECT', 'to': "orm['main.Repo']"}), + 'url': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}) + }, + 'main.packagedepend': { + 'Meta': {'object_name': 'PackageDepend', 'db_table': "'package_depends'"}, + 'depname': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'depvcmp': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}), + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'optional': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'pkg': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'depends'", 'to': "orm['main.Package']"}) + }, + 'main.packagefile': { + 'Meta': {'object_name': 'PackageFile', 'db_table': "'package_files'"}, + 'directory': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'filename': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_directory': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'pkg': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Package']"}) + }, + 'main.repo': { + 'Meta': {'ordering': "['name']", 'object_name': 'Repo', 'db_table': "'repos'"}, + 'bugs_category': ('django.db.models.fields.SmallIntegerField', [], {'default': '2'}), + 'bugs_project': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'staging': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'svn_root': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'testing': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) + }, + 'main.todolist': { + 'Meta': {'object_name': 'Todolist', 'db_table': "'todolists'"}, + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'on_delete': 'models.PROTECT'}), + 'date_added': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + 'main.todolistpkg': { + 'Meta': {'unique_together': "(('list', 'pkg'),)", 'object_name': 'TodolistPkg', 'db_table': "'todolist_pkgs'"}, + 'complete': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'list': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Todolist']"}), + 'pkg': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Package']"}) + } + } + + complete_apps = ['main'] diff --git a/main/migrations/0060_add_packages_last_update_index.py b/main/migrations/0060_add_packages_last_update_index.py new file mode 100644 index 00000000..8e3bb892 --- /dev/null +++ b/main/migrations/0060_add_packages_last_update_index.py @@ -0,0 +1,131 @@ +# -*- coding: utf-8 -*- +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + def forwards(self, orm): + db.create_index('packages', ['last_update']) + + def backwards(self, orm): + db.delete_index('packages', ['last_update']) + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'main.arch': { + 'Meta': {'ordering': "['name']", 'object_name': 'Arch', 'db_table': "'arches'"}, + 'agnostic': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}) + }, + 'main.donor': { + 'Meta': {'ordering': "('name',)", 'object_name': 'Donor', 'db_table': "'donors'"}, + 'created': ('django.db.models.fields.DateTimeField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'visible': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + 'main.package': { + 'Meta': {'ordering': "('pkgname',)", 'unique_together': "(('pkgname', 'repo', 'arch'),)", 'object_name': 'Package', 'db_table': "'packages'"}, + 'arch': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'packages'", 'on_delete': 'models.PROTECT', 'to': "orm['main.Arch']"}), + 'build_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), + 'compressed_size': ('main.fields.PositiveBigIntegerField', [], {}), + 'epoch': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'filename': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'files_last_update': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'flag_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'installed_size': ('main.fields.PositiveBigIntegerField', [], {}), + 'last_update': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}), + 'packager': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'on_delete': 'models.SET_NULL'}), + 'packager_str': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pgp_signature': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'pkgbase': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'pkgdesc': ('django.db.models.fields.TextField', [], {'null': 'True'}), + 'pkgname': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pkgrel': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pkgver': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'repo': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'packages'", 'on_delete': 'models.PROTECT', 'to': "orm['main.Repo']"}), + 'url': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}) + }, + 'main.packagedepend': { + 'Meta': {'object_name': 'PackageDepend', 'db_table': "'package_depends'"}, + 'depname': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'depvcmp': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}), + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'optional': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'pkg': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'depends'", 'to': "orm['main.Package']"}) + }, + 'main.packagefile': { + 'Meta': {'object_name': 'PackageFile', 'db_table': "'package_files'"}, + 'directory': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'filename': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_directory': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'pkg': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Package']"}) + }, + 'main.repo': { + 'Meta': {'ordering': "['name']", 'object_name': 'Repo', 'db_table': "'repos'"}, + 'bugs_category': ('django.db.models.fields.SmallIntegerField', [], {'default': '2'}), + 'bugs_project': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'staging': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'svn_root': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'testing': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) + }, + 'main.todolist': { + 'Meta': {'object_name': 'Todolist', 'db_table': "'todolists'"}, + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'on_delete': 'models.PROTECT'}), + 'date_added': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + 'main.todolistpkg': { + 'Meta': {'unique_together': "(('list', 'pkg'),)", 'object_name': 'TodolistPkg', 'db_table': "'todolist_pkgs'"}, + 'complete': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'list': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Todolist']"}), + 'pkg': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Package']"}) + } + } + + complete_apps = ['main'] diff --git a/main/models.py b/main/models.py index db926dda..c532ed56 100644 --- a/main/models.py +++ b/main/models.py @@ -2,68 +2,14 @@ from base64 import b64decode from datetime import datetime from itertools import groupby from pgpdump import BinaryData -import pytz from django.db import models from django.contrib.auth.models import User from django.contrib.sites.models import Site -from .fields import PositiveBigIntegerField, PGPKeyField -from .utils import cache_function, make_choice, set_created_field, utc_now - - -class UserProfile(models.Model): - notify = models.BooleanField( - "Send notifications", - default=True, - help_text="When enabled, send user 'flag out-of-date' notifications") - time_zone = models.CharField( - max_length=100, - choices=make_choice(pytz.common_timezones), - default="UTC", - help_text="Used for developer clock page") - alias = models.CharField( - max_length=50, - help_text="Required field") - public_email = models.CharField( - max_length=50, - help_text="Required field") - other_contact = models.CharField(max_length=100, null=True, blank=True) - pgp_key = PGPKeyField(max_length=40, null=True, blank=True, - verbose_name="PGP key fingerprint", - help_text="consists of 40 hex digits; use `gpg --fingerprint`") - website = models.CharField(max_length=200, null=True, blank=True) - yob = models.IntegerField("Year of birth", null=True, blank=True) - location = models.CharField(max_length=50, null=True, blank=True) - languages = models.CharField(max_length=50, null=True, blank=True) - interests = models.CharField(max_length=255, null=True, blank=True) - occupation = models.CharField(max_length=50, null=True, blank=True) - roles = models.CharField(max_length=255, null=True, blank=True) - favorite_distros = models.CharField(max_length=255, null=True, blank=True) - picture = models.FileField(upload_to='devs', default='devs/silhouette.png', - help_text="Ideally 125px by 125px") - user = models.OneToOneField(User, related_name='userprofile') - allowed_repos = models.ManyToManyField('Repo', blank=True) - latin_name = models.CharField(max_length=255, null=True, blank=True, - help_text="Latin-form name; used only for non-Latin full names") +from .fields import PositiveBigIntegerField +from .utils import cache_function, set_created_field, utc_now - class Meta: - db_table = 'user_profiles' - verbose_name = 'Additional Profile Data' - verbose_name_plural = 'Additional Profile Data' - - def get_absolute_url(self): - # TODO: this is disgusting. find a way to consolidate this logic with - # public.views.userlist among other places, and make some constants or - # something so we aren't using copies of string names everywhere. - group_names = self.user.groups.values_list('name', flat=True) - if "Developers" in group_names: - prefix = "developers" - elif "Trusted Users" in group_names: - prefix = "trustedusers" - else: - prefix = "fellows" - return '/%s/#%s' % (prefix, self.user.username) class TodolistManager(models.Manager): def incomplete(self): @@ -147,7 +93,7 @@ class Package(models.Model): compressed_size = PositiveBigIntegerField() installed_size = PositiveBigIntegerField() build_date = models.DateTimeField(null=True) - last_update = models.DateTimeField() + last_update = models.DateTimeField(db_index=True) files_last_update = models.DateTimeField(null=True, blank=True) packager_str = models.CharField(max_length=255) packager = models.ForeignKey(User, null=True, diff --git a/mirrors/migrations/0002_rename_model_tables.py b/mirrors/migrations/0002_rename_model_tables.py index d510bada..087edd68 100644 --- a/mirrors/migrations/0002_rename_model_tables.py +++ b/mirrors/migrations/0002_rename_model_tables.py @@ -7,21 +7,33 @@ from django.db import models class Migration(SchemaMigration): depends_on = ( - ('main', '0014_mirror_notes_rsync_optional'), + ('main', '0030_move_mirror_models'), ) + mirror_apps = [ 'mirror', 'mirrorprotocol', 'mirrorurl', 'mirrorrsync' ] + def forwards(self, orm): db.rename_table('main_mirror', 'mirrors_mirror') db.rename_table('main_mirrorurl', 'mirrors_mirrorurl') db.rename_table('main_mirrorrsync', 'mirrors_mirrorrsync') db.rename_table('main_mirrorprotocol', 'mirrors_mirrorprotocol') + if not db.dry_run: + ct = orm['contenttypes.ContentType'].objects + ct.filter(app_label='main', model__in=self.mirror_apps).update( + app_label='mirrors') + def backwards(self, orm): db.rename_table('mirrors_mirror', 'main_mirror') db.rename_table('mirrors_mirrorurl', 'main_mirrorurl') db.rename_table('mirrors_mirrorrsync', 'main_mirrorrsync') db.rename_table('mirrors_mirrorprotocol', 'main_mirrorprotocol') + if not db.dry_run: + ct = orm['contenttypes.ContentType'].objects + ct.filter(app_label='mirrors', model__in=self.mirror_apps).update( + app_label='main') + models = { 'mirrors.mirror': { 'Meta': {'ordering': "('country', 'name')", 'object_name': 'Mirror'}, @@ -55,6 +67,13 @@ class Migration(SchemaMigration): 'mirror': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'urls'", 'to': "orm['mirrors.Mirror']"}), 'protocol': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'urls'", 'to': "orm['mirrors.MirrorProtocol']"}), 'url': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) } } diff --git a/mirrors/migrations/0012_auto__add_on_delete_attribute.py b/mirrors/migrations/0012_auto__add_on_delete_attribute.py new file mode 100644 index 00000000..3990d466 --- /dev/null +++ b/mirrors/migrations/0012_auto__add_on_delete_attribute.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + db.alter_column('mirrors_mirror', 'upstream_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['mirrors.Mirror'], null=True, on_delete=models.SET_NULL)) + db.alter_column('mirrors_mirrorurl', 'protocol_id', self.gf('django.db.models.fields.related.ForeignKey')(on_delete=models.PROTECT, to=orm['mirrors.MirrorProtocol'])) + + def backwards(self, orm): + db.alter_column('mirrors_mirror', 'upstream_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['mirrors.Mirror'], null=True)) + db.alter_column('mirrors_mirrorurl', 'protocol_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['mirrors.MirrorProtocol'])) + + models = { + 'mirrors.mirror': { + 'Meta': {'ordering': "('country', 'name')", 'object_name': 'Mirror'}, + 'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'admin_email': ('django.db.models.fields.EmailField', [], {'max_length': '255', 'blank': 'True'}), + 'country': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'isos': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'notes': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'rsync_password': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '50', 'blank': 'True'}), + 'rsync_user': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '50', 'blank': 'True'}), + 'tier': ('django.db.models.fields.SmallIntegerField', [], {'default': '2'}), + 'upstream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['mirrors.Mirror']", 'null': 'True', 'on_delete': 'models.SET_NULL'}) + }, + 'mirrors.mirrorlog': { + 'Meta': {'object_name': 'MirrorLog'}, + 'check_time': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}), + 'duration': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'error': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_success': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_sync': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), + 'url': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'logs'", 'to': "orm['mirrors.MirrorUrl']"}) + }, + 'mirrors.mirrorprotocol': { + 'Meta': {'ordering': "('protocol',)", 'object_name': 'MirrorProtocol'}, + 'default': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_download': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'protocol': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '10'}) + }, + 'mirrors.mirrorrsync': { + 'Meta': {'object_name': 'MirrorRsync'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ip': ('django.db.models.fields.CharField', [], {'max_length': '24'}), + 'mirror': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'rsync_ips'", 'to': "orm['mirrors.Mirror']"}) + }, + 'mirrors.mirrorurl': { + 'Meta': {'object_name': 'MirrorUrl'}, + 'country': ('mirrors.models.NullCharField', [], {'db_index': 'True', 'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'has_ipv4': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'has_ipv6': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mirror': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'urls'", 'to': "orm['mirrors.Mirror']"}), + 'protocol': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'urls'", 'on_delete': 'models.PROTECT', 'to': "orm['mirrors.MirrorProtocol']"}), + 'url': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}) + } + } + + complete_apps = ['mirrors'] diff --git a/mirrors/utils.py b/mirrors/utils.py index 619d5f5c..ddecb095 100644 --- a/mirrors/utils.py +++ b/mirrors/utils.py @@ -108,7 +108,7 @@ def get_mirror_url_for_download(cutoff=default_cutoff): status_data = MirrorLog.objects.filter( check_time__gte=cutoff_time).aggregate( Max('check_time'), Max('last_sync')) - if status_data: + if status_data['check_time__max'] is not None: min_check_time = status_data['check_time__max'] - timedelta(minutes=5) min_sync_time = status_data['last_sync__max'] - timedelta(minutes=30) best_logs = MirrorLog.objects.filter(is_success=True, diff --git a/news/migrations/0002_move_news_in.py b/news/migrations/0002_move_news_in.py index d6dafad4..43d68df4 100644 --- a/news/migrations/0002_move_news_in.py +++ b/news/migrations/0002_move_news_in.py @@ -7,14 +7,19 @@ from django.db import models class Migration(SchemaMigration): depends_on = ( - ('main', '0001_initial'), + ('main', '0031_move_news_out'), ) def forwards(self, orm): - pass + db.send_create_signal('news', ['News']) + if not db.dry_run: + ct = orm['contenttypes.ContentType'].objects + ct.filter(app_label='main', model='news').update(app_label='news') def backwards(self, orm): - pass + if not db.dry_run: + ct = orm['contenttypes.ContentType'].objects + ct.filter(app_label='news', model='news').update(app_label='main') models = { 'auth.group': { diff --git a/news/migrations/0010_auto__chg_field_news_author.py b/news/migrations/0010_auto__chg_field_news_author.py new file mode 100644 index 00000000..64fdc580 --- /dev/null +++ b/news/migrations/0010_auto__chg_field_news_author.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + db.alter_column('news', 'author_id', self.gf('django.db.models.fields.related.ForeignKey')(on_delete=models.PROTECT, to=orm['auth.User'])) + + def backwards(self, orm): + db.alter_column('news', 'author_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])) + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'news.news': { + 'Meta': {'ordering': "['-postdate']", 'object_name': 'News', 'db_table': "'news'"}, + 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'news_author'", 'on_delete': 'models.PROTECT', 'to': "orm['auth.User']"}), + 'content': ('django.db.models.fields.TextField', [], {}), + 'guid': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}), + 'postdate': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + } + } + + complete_apps = ['news'] diff --git a/releng/views.py b/releng/views.py index 007c8c84..33e8fb31 100644 --- a/releng/views.py +++ b/releng/views.py @@ -177,12 +177,18 @@ def submit_test_thanks(request): def iso_overview(request): isos = Iso.objects.all().order_by('-pk') - successes = dict(Iso.objects.values_list('pk').filter(test__success=True).annotate(ct=Count('test'))) - failures = dict(Iso.objects.values_list('pk').filter(test__success=False).annotate(ct=Count('test'))) + successes = dict(Iso.objects.values_list('pk').filter( + test__success=True).annotate(ct=Count('test'))) + failures = dict(Iso.objects.values_list('pk').filter( + test__success=False).annotate(ct=Count('test'))) for iso in isos: iso.successes = successes.get(iso.pk, 0) iso.failures = failures.get(iso.pk, 0) + # only show "useful" rows, currently active ISOs or those with results + isos = [iso for iso in isos if + iso.active == True or iso.successes > 0 or iso.failures > 0] + context = { 'isos': isos } diff --git a/settings.py b/settings.py index 735bf8b8..431c5579 100644 --- a/settings.py +++ b/settings.py @@ -43,7 +43,7 @@ LOGIN_URL = '/login/' LOGIN_REDIRECT_URL = '/' # Set django's User stuff to use our profile model -AUTH_PROFILE_MODULE = 'main.UserProfile' +AUTH_PROFILE_MODULE = 'devel.UserProfile' # We add a processor to determine if the request is secure or not TEMPLATE_CONTEXT_PROCESSORS = ( diff --git a/templates/devel/index.html b/templates/devel/index.html index cda510e4..9f897317 100644 --- a/templates/devel/index.html +++ b/templates/devel/index.html @@ -148,7 +148,7 @@ <h3>Developer Reports</h3> <ul> <li><a href="reports/old/">Old</a>: - Packages last built more than two years ago + Packages last built more than one year ago (<a href="reports/old/{{ user.username }}/">yours only</a>)</li> <li><a href="reports/long-out-of-date/">Long Out-of-date</a>: Packages marked out-of-date more than 90 days ago diff --git a/templates/packages/details.html b/templates/packages/details.html index 00b2c70c..8e4b2bb0 100644 --- a/templates/packages/details.html +++ b/templates/packages/details.html @@ -81,7 +81,7 @@ {% with pkg.split_packages as splits %}{% if splits %} <tr> <th>Split Packages:</th> - <td>{% for s in splits %}{% pkg_details_link s %}<br/>{% endfor %}</td> + <td class="wrap">{% for s in splits %}{% pkg_details_link s %}{% if not forloop.last %}, {% endif %}{% endfor %}</td> </tr> {% endif %}{% endwith %} {% else %} @@ -104,22 +104,33 @@ title="Visit the website for {{ pkg.pkgname }}">{{ pkg.url|url_unquote }}</a>{% endif %}</td> </tr><tr> <th>License(s):</th> - <td>{{ pkg.licenses.all|join:", " }}</td> + <td class="wrap">{{ pkg.licenses.all|join:", " }}</td> </tr> {% with pkg.groups.all as groups %}{% if groups %} <tr> <th>Groups:</th> - <td>{% for g in groups %} + <td class="wrap">{% for g in groups %} <a href="/groups/{{ pkg.arch.name }}/{{ g.name }}/" - title="Group details for {{ g.name }}">{{ g.name }}</a><br/> - {% endfor %} + title="Group details for {{ g.name }}">{{ g.name }}</a>{% if not forloop.last %}, {% endif %}{% endfor %} </td> </tr> {% endif %}{% endwith %} {% with pkg.provides.all as provides %}{% if provides %} <tr> <th>Provides:</th> - <td>{% for p in provides %}{{ p.name }}{% if p.version %}={{ p.version }}{% endif %}<br/>{% endfor %}</td> + <td class="wrap">{{ provides|join:", " }}</td> + </tr> + {% endif %}{% endwith %} + {% with pkg.conflicts.all as conflicts %}{% if conflicts %} + <tr> + <th>Conflicts:</th> + <td class="wrap">{{ conflicts|join:", " }}</td> + </tr> + {% endif %}{% endwith %} + {% with pkg.replaces.all as replaces %}{% if replaces %} + <tr> + <th>Replaces:</th> + <td class="wrap">{{ replaces|join:", " }}</td> </tr> {% endif %}{% endwith %} <tr> diff --git a/templates/releng/iso_overview.html b/templates/releng/iso_overview.html index ca5a8c08..447ba487 100644 --- a/templates/releng/iso_overview.html +++ b/templates/releng/iso_overview.html @@ -6,6 +6,12 @@ <div class="box"> <h2>Failures and Successes for Testing ISOs</h2> + <p>This is an overview showing all current or tested release engineering + produced ISOs. Past but now unavailable ISOs are ommitted if there were + never any testing results submitted. To help improve ISO quality, you are + encouraged to <a href="{% url 'releng-test-submit' %}">give feedback</a> + if you have tested and used any ISOs. Both successful and failed results + are encouraged and welcome.</p> <p><a href="{% url 'releng-test-overview' %}">Go back to testing results</a></p> <table id="releng-result" class="results"> diff --git a/templates/releng/results.html b/templates/releng/results.html index fa694cc6..49d81ec4 100644 --- a/templates/releng/results.html +++ b/templates/releng/results.html @@ -7,7 +7,7 @@ <div class="box"> <h2>Release Engineering Testbuild Results</h2> - <p>This is an overview screen showing a test results matrix of release + <p>This is an overview showing a test results matrix of release engineering produced ISOs. Various options and configurations are shown with last success and last failure results, if known. To help improve ISO quality, you are encouraged to <a href="{% url 'releng-test-submit' %}">give feedback</a> |