diff options
author | Luke Shumaker <LukeShu@sbcglobal.net> | 2013-04-21 02:22:44 -0400 |
---|---|---|
committer | Luke Shumaker <LukeShu@sbcglobal.net> | 2013-04-21 02:22:44 -0400 |
commit | 03fa7e4f27bdb39a8f8f5ed91a87d18bf8357b47 (patch) | |
tree | c67eafcbda55706f18400b3115a2b8a5be318394 /todolists | |
parent | 91c451821ce7000cbc268cec8427d208a6cedd7e (diff) | |
parent | b8ee7b1ee281b45b245fb454228b8ad847c56200 (diff) |
Merge branch 'archweb' into archweb-generic2
Conflicts:
devel/views.py
feeds.py
public/views.py
settings.py
sitestatic/archweb.js
templates/base.html
templates/devel/profile.html
templates/mirrors/status.html
templates/news/view.html
templates/packages/flaghelp.html
templates/packages/opensearch.xml
templates/public/download.html
templates/public/feeds.html
templates/public/index.html
templates/registration/login.html
templates/releng/results.html
templates/todolists/public_list.html
Diffstat (limited to 'todolists')
-rw-r--r-- | todolists/admin.py | 15 | ||||
-rw-r--r-- | todolists/migrations/0001_initial.py | 19 | ||||
-rw-r--r-- | todolists/migrations/0002_add_todolist_and_todolistpackage.py | 155 | ||||
-rw-r--r-- | todolists/migrations/0003_migrate_todolist_data.py | 184 | ||||
-rw-r--r-- | todolists/migrations/0004_auto__add_field_todolist_slug.py | 123 | ||||
-rw-r--r-- | todolists/migrations/0005_add_slugs.py | 133 | ||||
-rw-r--r-- | todolists/migrations/0006_auto__chg_field_todolist_slug.py | 119 | ||||
-rw-r--r-- | todolists/migrations/0007_auto__add_field_todolistpackage_removed.py | 124 | ||||
-rw-r--r-- | todolists/migrations/0008_auto__add_field_todolistpackage_last_modified.py | 129 | ||||
-rw-r--r-- | todolists/migrations/0009_update_last_modified_todolist_package.py | 122 | ||||
-rw-r--r-- | todolists/migrations/__init__.py | 0 | ||||
-rw-r--r-- | todolists/models.py | 94 | ||||
-rw-r--r-- | todolists/templatetags/__init__.py | 0 | ||||
-rw-r--r-- | todolists/templatetags/todolists.py | 19 | ||||
-rw-r--r-- | todolists/urls.py | 29 | ||||
-rw-r--r-- | todolists/utils.py | 61 | ||||
-rw-r--r-- | todolists/views.py | 185 |
17 files changed, 1418 insertions, 93 deletions
diff --git a/todolists/admin.py b/todolists/admin.py new file mode 100644 index 00000000..246a8bca --- /dev/null +++ b/todolists/admin.py @@ -0,0 +1,15 @@ +from django.contrib import admin + +from .models import Todolist + + +class TodolistAdmin(admin.ModelAdmin): + list_display = ('name', 'creator', 'created', 'description') + list_filter = ('created', 'creator') + search_fields = ('name', 'description') + date_hierarchy = 'created' + + +admin.site.register(Todolist, TodolistAdmin) + +# vim: set ts=4 sw=4 et: diff --git a/todolists/migrations/0001_initial.py b/todolists/migrations/0001_initial.py new file mode 100644 index 00000000..48d38aae --- /dev/null +++ b/todolists/migrations/0001_initial.py @@ -0,0 +1,19 @@ +# -*- 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): + pass + + def backwards(self, orm): + pass + + models = { + + } + + complete_apps = ['todolists'] diff --git a/todolists/migrations/0002_add_todolist_and_todolistpackage.py b/todolists/migrations/0002_add_todolist_and_todolistpackage.py new file mode 100644 index 00000000..ba8f7ebe --- /dev/null +++ b/todolists/migrations/0002_add_todolist_and_todolistpackage.py @@ -0,0 +1,155 @@ +# -*- coding: utf-8 -*- +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + depends_on = ( + ('main', '0024_set_initial_flag_date'), + ) + + def forwards(self, orm): + db.create_table('todolists_todolist', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('old_id', self.gf('django.db.models.fields.IntegerField')(unique=True, null=True)), + ('name', self.gf('django.db.models.fields.CharField')(max_length=255)), + ('description', self.gf('django.db.models.fields.TextField')()), + ('creator', self.gf('django.db.models.fields.related.ForeignKey')(related_name='created_todolists', on_delete=models.PROTECT, to=orm['auth.User'])), + ('created', self.gf('django.db.models.fields.DateTimeField')(db_index=True)), + ('last_modified', self.gf('django.db.models.fields.DateTimeField')()), + ('raw', self.gf('django.db.models.fields.TextField')(blank=True)), + )) + db.send_create_signal('todolists', ['Todolist']) + + db.create_table('todolists_todolistpackage', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('todolist', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['todolists.Todolist'])), + ('pkg', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['main.Package'], null=True, on_delete=models.SET_NULL)), + ('pkgname', self.gf('django.db.models.fields.CharField')(max_length=255)), + ('pkgbase', self.gf('django.db.models.fields.CharField')(max_length=255)), + ('arch', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['main.Arch'])), + ('repo', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['main.Repo'])), + ('created', self.gf('django.db.models.fields.DateTimeField')()), + ('status', self.gf('django.db.models.fields.SmallIntegerField')(default=0)), + ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True, on_delete=models.SET_NULL)), + ('comments', self.gf('django.db.models.fields.TextField')(null=True, blank=True)), + )) + db.send_create_signal('todolists', ['TodolistPackage']) + + db.create_unique('todolists_todolistpackage', ['todolist_id', 'pkgname', 'arch_id']) + + + def backwards(self, orm): + db.delete_unique('todolists_todolistpackage', ['todolist_id', 'pkgname', 'arch_id']) + + db.delete_table('todolists_todolist') + + db.delete_table('todolists_todolistpackage') + + + 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.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', 'blank': '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', 'blank': 'True'}), + '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.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'}) + }, + 'todolists.todolist': { + 'Meta': {'object_name': 'Todolist'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'created_todolists'", 'on_delete': 'models.PROTECT', 'to': "orm['auth.User']"}), + 'description': ('django.db.models.fields.TextField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('django.db.models.fields.DateTimeField', [], {}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'old_id': ('django.db.models.fields.IntegerField', [], {'unique': 'True', 'null': 'True'}), + 'raw': ('django.db.models.fields.TextField', [], {'blank': 'True'}) + }, + 'todolists.todolistpackage': { + 'Meta': {'unique_together': "(('todolist', 'pkgname', 'arch'),)", 'object_name': 'TodolistPackage'}, + 'arch': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Arch']"}), + 'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'pkg': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Package']", 'null': 'True', 'on_delete': 'models.SET_NULL'}), + 'pkgbase': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pkgname': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'repo': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Repo']"}), + 'status': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'todolist': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['todolists.Todolist']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'on_delete': 'models.SET_NULL'}) + } + } + + complete_apps = ['todolists'] diff --git a/todolists/migrations/0003_migrate_todolist_data.py b/todolists/migrations/0003_migrate_todolist_data.py new file mode 100644 index 00000000..8a317a67 --- /dev/null +++ b/todolists/migrations/0003_migrate_todolist_data.py @@ -0,0 +1,184 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import DataMigration +from django.db import models + +class Migration(DataMigration): + + depends_on = ( + ('main', '0045_add_todolist_date_added_index'), + ('main', '0053_auto__add_field_package_pgp_signature'), + ) + + def forwards(self, orm): + list_id_map = {} + list_added = {} + # start by converting the todo lists themselves + for old in orm['main.Todolist'].objects.all().order_by('id'): + new = orm.Todolist.objects.create(name=old.name, old_id=old.id, + description=old.description, created=old.date_added, + last_modified=old.date_added, creator_id=old.creator_id) + # set the 'raw' field to something useful + pkgnames = orm['main.Package'].objects.values_list('pkgname', + flat=True).distinct().order_by('pkgname').filter( + todolistpkg__list_id=old.id) + pkgname_text = '\n'.join(pkgnames) + orm.Todolist.objects.filter(id=new.id).update(raw=pkgname_text) + list_id_map[old.id] = new.id + list_added[old.id] = old.date_added + + # 1 and 0 come from TodolistPackage.COMPLETE, INCOMPLETE + get_status = lambda v: 1 if v is True else 0 + # next, loop each old todolist package, creating a new one + for old in orm['main.TodolistPkg'].objects.all().select_related( + 'pkg').order_by('id'): + pkg = old.pkg + new_list_id = list_id_map[old.list_id] + orm.TodolistPackage.objects.create(todolist_id=new_list_id, + pkg=pkg, pkgname=pkg.pkgname, pkgbase=pkg.pkgbase, + arch_id=pkg.arch_id, repo_id=pkg.repo_id, + status=get_status(old.complete), + created=list_added[old.list_id]) + + def backwards(self, orm): + #orm.Todolist.objects.all().delete() + #orm.TodolistPackage.objects.all().delete() + 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'}) + }, + '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', 'blank': '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', 'blank': 'True'}), + '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.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']"}) + }, + 'todolists.todolist': { + 'Meta': {'object_name': 'Todolist'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'created_todolists'", 'on_delete': 'models.PROTECT', 'to': "orm['auth.User']"}), + 'description': ('django.db.models.fields.TextField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('django.db.models.fields.DateTimeField', [], {}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'old_id': ('django.db.models.fields.IntegerField', [], {'unique': 'True', 'null': 'True'}), + 'raw': ('django.db.models.fields.TextField', [], {'blank': 'True'}) + }, + 'todolists.todolistpackage': { + 'Meta': {'unique_together': "(('todolist', 'pkgname', 'arch'),)", 'object_name': 'TodolistPackage'}, + 'arch': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Arch']"}), + 'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'pkg': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Package']", 'null': 'True', 'on_delete': 'models.SET_NULL'}), + 'pkgbase': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pkgname': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'repo': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Repo']"}), + 'status': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'todolist': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['todolists.Todolist']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'on_delete': 'models.SET_NULL'}) + } + } + + complete_apps = ['main', 'todolists'] + symmetrical = True diff --git a/todolists/migrations/0004_auto__add_field_todolist_slug.py b/todolists/migrations/0004_auto__add_field_todolist_slug.py new file mode 100644 index 00000000..18fd2f9a --- /dev/null +++ b/todolists/migrations/0004_auto__add_field_todolist_slug.py @@ -0,0 +1,123 @@ +# -*- 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.add_column('todolists_todolist', 'slug', + self.gf('django.db.models.fields.SlugField')(max_length=255, unique=True, null=True), + keep_default=False) + + + def backwards(self, orm): + db.delete_column('todolists_todolist', 'slug') + + + 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.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', 'blank': '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', 'blank': 'True'}), + '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.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'}) + }, + 'todolists.todolist': { + 'Meta': {'object_name': 'Todolist'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'created_todolists'", 'on_delete': 'models.PROTECT', 'to': "orm['auth.User']"}), + 'description': ('django.db.models.fields.TextField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('django.db.models.fields.DateTimeField', [], {}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'old_id': ('django.db.models.fields.IntegerField', [], {'unique': 'True', 'null': 'True'}), + 'raw': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'unique': 'True', 'null': 'True'}) + }, + 'todolists.todolistpackage': { + 'Meta': {'unique_together': "(('todolist', 'pkgname', 'arch'),)", 'object_name': 'TodolistPackage'}, + 'arch': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Arch']"}), + 'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'pkg': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Package']", 'null': 'True', 'on_delete': 'models.SET_NULL'}), + 'pkgbase': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pkgname': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'repo': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Repo']"}), + 'status': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'todolist': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['todolists.Todolist']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'on_delete': 'models.SET_NULL'}) + } + } + + complete_apps = ['todolists'] diff --git a/todolists/migrations/0005_add_slugs.py b/todolists/migrations/0005_add_slugs.py new file mode 100644 index 00000000..d7d67793 --- /dev/null +++ b/todolists/migrations/0005_add_slugs.py @@ -0,0 +1,133 @@ +# -*- coding: utf-8 -*- +from south.db import db +from south.v2 import DataMigration +from django.db import models + +from django.template.defaultfilters import slugify + +class Migration(DataMigration): + + def forwards(self, orm): + existing = list(orm.Todolist.objects.values_list( + 'slug', flat=True).distinct()) + for item in orm.Todolist.objects.defer('raw').filter(slug=None): + suffixed = slug = slugify(item.name) + suffix = 1 + while suffixed in existing: + suffix += 1 + suffixed = "%s-%d" % (slug, suffix) + + item.slug = suffixed + existing.append(suffixed) + + item.save() + + def backwards(self, orm): + orm.Todolist.objects.all.update(slug=None) + + 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.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', 'blank': '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', 'blank': 'True'}), + '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.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'}) + }, + 'todolists.todolist': { + 'Meta': {'object_name': 'Todolist'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'created_todolists'", 'on_delete': 'models.PROTECT', 'to': "orm['auth.User']"}), + 'description': ('django.db.models.fields.TextField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('django.db.models.fields.DateTimeField', [], {}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'old_id': ('django.db.models.fields.IntegerField', [], {'unique': 'True', 'null': 'True'}), + 'raw': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'unique': 'True', 'null': 'True'}) + }, + 'todolists.todolistpackage': { + 'Meta': {'unique_together': "(('todolist', 'pkgname', 'arch'),)", 'object_name': 'TodolistPackage'}, + 'arch': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Arch']"}), + 'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'pkg': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Package']", 'null': 'True', 'on_delete': 'models.SET_NULL'}), + 'pkgbase': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pkgname': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'repo': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Repo']"}), + 'status': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'todolist': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['todolists.Todolist']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'on_delete': 'models.SET_NULL'}) + } + } + + complete_apps = ['todolists'] + symmetrical = True diff --git a/todolists/migrations/0006_auto__chg_field_todolist_slug.py b/todolists/migrations/0006_auto__chg_field_todolist_slug.py new file mode 100644 index 00000000..3073120b --- /dev/null +++ b/todolists/migrations/0006_auto__chg_field_todolist_slug.py @@ -0,0 +1,119 @@ +# -*- 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_todolist', 'slug', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=255)) + + def backwards(self, orm): + db.alter_column('todolists_todolist', 'slug', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=255, null=True)) + + 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.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', 'blank': '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', 'blank': 'True'}), + '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.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'}) + }, + 'todolists.todolist': { + 'Meta': {'object_name': 'Todolist'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'created_todolists'", 'on_delete': 'models.PROTECT', 'to': "orm['auth.User']"}), + 'description': ('django.db.models.fields.TextField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('django.db.models.fields.DateTimeField', [], {}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'old_id': ('django.db.models.fields.IntegerField', [], {'unique': 'True', 'null': 'True'}), + 'raw': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}) + }, + 'todolists.todolistpackage': { + 'Meta': {'unique_together': "(('todolist', 'pkgname', 'arch'),)", 'object_name': 'TodolistPackage'}, + 'arch': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Arch']"}), + 'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'pkg': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Package']", 'null': 'True', 'on_delete': 'models.SET_NULL'}), + 'pkgbase': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pkgname': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'repo': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Repo']"}), + 'status': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'todolist': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['todolists.Todolist']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'on_delete': 'models.SET_NULL'}) + } + } + + complete_apps = ['todolists'] diff --git a/todolists/migrations/0007_auto__add_field_todolistpackage_removed.py b/todolists/migrations/0007_auto__add_field_todolistpackage_removed.py new file mode 100644 index 00000000..6d9c4fb2 --- /dev/null +++ b/todolists/migrations/0007_auto__add_field_todolistpackage_removed.py @@ -0,0 +1,124 @@ +# -*- 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.add_column('todolists_todolistpackage', 'removed', + self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True), + keep_default=False) + + + def backwards(self, orm): + db.delete_column('todolists_todolistpackage', 'removed') + + + 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.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', 'blank': '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', 'blank': 'True'}), + '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.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'}) + }, + 'todolists.todolist': { + 'Meta': {'object_name': 'Todolist'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'created_todolists'", 'on_delete': 'models.PROTECT', 'to': "orm['auth.User']"}), + 'description': ('django.db.models.fields.TextField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('django.db.models.fields.DateTimeField', [], {}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'old_id': ('django.db.models.fields.IntegerField', [], {'unique': 'True', 'null': 'True'}), + 'raw': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}) + }, + 'todolists.todolistpackage': { + 'Meta': {'unique_together': "(('todolist', 'pkgname', 'arch'),)", 'object_name': 'TodolistPackage'}, + 'arch': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Arch']"}), + 'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'pkg': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Package']", 'null': 'True', 'on_delete': 'models.SET_NULL'}), + 'pkgbase': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pkgname': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'removed': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'repo': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Repo']"}), + 'status': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'todolist': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['todolists.Todolist']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'on_delete': 'models.SET_NULL'}) + } + } + + complete_apps = ['todolists'] diff --git a/todolists/migrations/0008_auto__add_field_todolistpackage_last_modified.py b/todolists/migrations/0008_auto__add_field_todolistpackage_last_modified.py new file mode 100644 index 00000000..ac3025b4 --- /dev/null +++ b/todolists/migrations/0008_auto__add_field_todolistpackage_last_modified.py @@ -0,0 +1,129 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models +from pytz import utc + + +class Migration(SchemaMigration): + + def forwards(self, orm): + default = datetime.datetime(2000, 1, 1, 0, 0).replace(tzinfo=utc) + db.add_column('todolists_todolistpackage', 'last_modified', + self.gf('django.db.models.fields.DateTimeField')(default=default), + keep_default=False) + + + def backwards(self, orm): + db.delete_column('todolists_todolistpackage', 'last_modified') + + + 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.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', [], {}), + 'created': ('django.db.models.fields.DateTimeField', [], {}), + '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', 'blank': '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', 'blank': 'True'}), + '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.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'}) + }, + 'todolists.todolist': { + 'Meta': {'object_name': 'Todolist'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'created_todolists'", 'on_delete': 'models.PROTECT', 'to': "orm['auth.User']"}), + 'description': ('django.db.models.fields.TextField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('django.db.models.fields.DateTimeField', [], {}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'old_id': ('django.db.models.fields.IntegerField', [], {'unique': 'True', 'null': 'True'}), + 'raw': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}) + }, + 'todolists.todolistpackage': { + 'Meta': {'unique_together': "(('todolist', 'pkgname', 'arch'),)", 'object_name': 'TodolistPackage'}, + 'arch': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Arch']"}), + 'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('django.db.models.fields.DateTimeField', [], {}), + 'pkg': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Package']", 'null': 'True', 'on_delete': 'models.SET_NULL'}), + 'pkgbase': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pkgname': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'removed': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'repo': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Repo']"}), + 'status': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'todolist': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['todolists.Todolist']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'on_delete': 'models.SET_NULL'}) + } + } + + complete_apps = ['todolists'] diff --git a/todolists/migrations/0009_update_last_modified_todolist_package.py b/todolists/migrations/0009_update_last_modified_todolist_package.py new file mode 100644 index 00000000..f7bf30ae --- /dev/null +++ b/todolists/migrations/0009_update_last_modified_todolist_package.py @@ -0,0 +1,122 @@ +# -*- coding: utf-8 -*- +from south.db import db +from south.v2 import DataMigration +from django.db import models + +class Migration(DataMigration): + + def forwards(self, orm): + orm.TodolistPackage.objects.all().update(last_modified=models.F('created')) + + 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'}) + }, + '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.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', [], {}), + 'created': ('django.db.models.fields.DateTimeField', [], {}), + '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', 'blank': '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', 'blank': 'True'}), + '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.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'}) + }, + 'todolists.todolist': { + 'Meta': {'object_name': 'Todolist'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'created_todolists'", 'on_delete': 'models.PROTECT', 'to': "orm['auth.User']"}), + 'description': ('django.db.models.fields.TextField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('django.db.models.fields.DateTimeField', [], {}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'old_id': ('django.db.models.fields.IntegerField', [], {'unique': 'True', 'null': 'True'}), + 'raw': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}) + }, + 'todolists.todolistpackage': { + 'Meta': {'unique_together': "(('todolist', 'pkgname', 'arch'),)", 'object_name': 'TodolistPackage'}, + 'arch': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Arch']"}), + 'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('django.db.models.fields.DateTimeField', [], {}), + 'pkg': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Package']", 'null': 'True', 'on_delete': 'models.SET_NULL'}), + 'pkgbase': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pkgname': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'removed': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'repo': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Repo']"}), + 'status': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'todolist': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['todolists.Todolist']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'on_delete': 'models.SET_NULL'}) + } + } + + complete_apps = ['todolists'] + symmetrical = True diff --git a/todolists/migrations/__init__.py b/todolists/migrations/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/todolists/migrations/__init__.py diff --git a/todolists/models.py b/todolists/models.py new file mode 100644 index 00000000..3ea80f37 --- /dev/null +++ b/todolists/models.py @@ -0,0 +1,94 @@ +from django.contrib.auth.models import User +from django.contrib.sites.models import Site +from django.db import models +from django.db.models import Q +from django.db.models.signals import pre_save + +from main.models import Arch, Repo, Package +from main.utils import set_created_field + + +class TodolistManager(models.Manager): + def incomplete(self): + not_done = ((Q(todolistpackage__status=TodolistPackage.INCOMPLETE) | + Q(todolistpackage__status=TodolistPackage.IN_PROGRESS)) & + Q(todolistpackage__removed__isnull=True)) + return self.order_by().filter(not_done).distinct() + + +class Todolist(models.Model): + slug = models.SlugField(max_length=255, unique=True) + old_id = models.IntegerField(null=True, unique=True) + name = models.CharField(max_length=255) + description = models.TextField() + creator = models.ForeignKey(User, on_delete=models.PROTECT, + related_name="created_todolists") + created = models.DateTimeField(db_index=True) + last_modified = models.DateTimeField(editable=False) + raw = models.TextField(blank=True) + + objects = TodolistManager() + + class Meta: + get_latest_by = 'created' + + def __unicode__(self): + return self.name + + def get_absolute_url(self): + return '/todo/%s/' % self.slug + + def get_full_url(self, proto='https'): + '''get a URL suitable for things like email including the domain''' + domain = Site.objects.get_current().domain + return '%s://%s%s' % (proto, domain, self.get_absolute_url()) + + def packages(self): + if not hasattr(self, '_packages'): + self._packages = self.todolistpackage_set.filter( + removed__isnull=True).select_related( + 'pkg', 'repo', 'arch').order_by('pkgname', 'arch') + return self._packages + + +class TodolistPackage(models.Model): + INCOMPLETE = 0 + COMPLETE = 1 + IN_PROGRESS = 2 + STATUS_CHOICES = ( + (INCOMPLETE, 'Incomplete'), + (COMPLETE, 'Complete'), + (IN_PROGRESS, 'In-progress'), + ) + + todolist = models.ForeignKey(Todolist) + pkg = models.ForeignKey(Package, null=True, on_delete=models.SET_NULL) + pkgname = models.CharField(max_length=255) + pkgbase = models.CharField(max_length=255) + arch = models.ForeignKey(Arch) + repo = models.ForeignKey(Repo) + created = models.DateTimeField(editable=False) + last_modified = models.DateTimeField(editable=False) + removed = models.DateTimeField(null=True, blank=True) + status = models.SmallIntegerField(default=INCOMPLETE, + choices=STATUS_CHOICES) + user = models.ForeignKey(User, null=True, on_delete=models.SET_NULL) + comments = models.TextField(null=True, blank=True) + + class Meta: + unique_together = (('todolist', 'pkgname', 'arch'),) + get_latest_by = 'created' + + def __unicode__(self): + return self.pkgname + + def status_css_class(self): + return self.get_status_display().lower().replace('-', '') + + +pre_save.connect(set_created_field, sender=Todolist, + dispatch_uid="todolists.models") +pre_save.connect(set_created_field, sender=TodolistPackage, + dispatch_uid="todolists.models") + +# vim: set ts=4 sw=4 et: diff --git a/todolists/templatetags/__init__.py b/todolists/templatetags/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/todolists/templatetags/__init__.py diff --git a/todolists/templatetags/todolists.py b/todolists/templatetags/todolists.py new file mode 100644 index 00000000..5f31dc1f --- /dev/null +++ b/todolists/templatetags/todolists.py @@ -0,0 +1,19 @@ +from django import template + +register = template.Library() + + +def pkg_absolute_url(repo, arch, pkgname): + return '/packages/%s/%s/%s/' % (repo.name.lower(), arch.name, pkgname) + + +@register.simple_tag +def todopkg_details_link(todopkg): + pkg = todopkg.pkg + if not pkg: + return todopkg.pkgname + link = '<a href="%s" title="View package details for %s">%s</a>' + url = pkg_absolute_url(todopkg.repo, todopkg.arch, pkg.pkgname) + return link % (url, pkg.pkgname, pkg.pkgname) + +# vim: set ts=4 sw=4 et: diff --git a/todolists/urls.py b/todolists/urls.py index a379468f..6617d7dd 100644 --- a/todolists/urls.py +++ b/todolists/urls.py @@ -1,17 +1,26 @@ from django.conf.urls import patterns from django.contrib.auth.decorators import permission_required -from .views import DeleteTodolist +from .views import (view_redirect, view, todolist_list, add, edit, flag, + list_pkgbases, DeleteTodolist) -urlpatterns = patterns('todolists.views', - (r'^$', 'todolist_list'), - (r'^(?P<list_id>\d+)/$', 'view'), - (r'^(?P<list_id>\d+)/pkgbases/(?P<svn_root>[a-z]+)/$', 'list_pkgbases'), - (r'^add/$', 'add'), - (r'^edit/(?P<list_id>\d+)/$', 'edit'), - (r'^flag/(\d+)/(\d+)/$', 'flag'), - (r'^delete/(?P<pk>\d+)/$', - permission_required('main.delete_todolist')(DeleteTodolist.as_view())), +urlpatterns = patterns('', + (r'^$', todolist_list), + + # old todolists URLs, permanent redirect view so we don't break all links + (r'^(?P<old_id>\d+)/$', view_redirect), + + (r'^add/$', + permission_required('todolists.add_todolist')(add)), + (r'^(?P<slug>[-\w]+)/$', view), + (r'^(?P<slug>[-\w]+)/edit/$', + permission_required('todolists.change_todolist')(edit)), + (r'^(?P<slug>[-\w]+)/delete/$', + permission_required('todolists.delete_todolist')(DeleteTodolist.as_view())), + (r'^(?P<slug>[-\w]+)/flag/(?P<pkg_id>\d+)/$', + permission_required('todolists.change_todolistpackage')(flag)), + (r'^(?P<slug>[-\w]+)/pkgbases/(?P<svn_root>[a-z]+)/$', + list_pkgbases), ) # vim: set ts=4 sw=4 et: diff --git a/todolists/utils.py b/todolists/utils.py index 24101e86..51a75a3c 100644 --- a/todolists/utils.py +++ b/todolists/utils.py @@ -1,23 +1,58 @@ +from django.db import connections, router from django.db.models import Count -from main.models import Todolist +from .models import Todolist, TodolistPackage +from packages.models import Package -def get_annotated_todolists(): - qs = Todolist.objects.all() - lists = qs.select_related('creator').defer( - 'creator__email', 'creator__password', 'creator__is_staff', - 'creator__is_active', 'creator__is_superuser', - 'creator__last_login', 'creator__date_joined').annotate( - pkg_count=Count('todolistpkg')).order_by('-date_added') - incomplete = qs.filter(todolistpkg__complete=False).annotate( - Count('todolistpkg')).values_list('id', 'todolistpkg__count') +def todo_counts(): + sql = """ +SELECT todolist_id, count(*), sum(CASE WHEN status = %s THEN 1 ELSE 0 END) + FROM todolists_todolistpackage + WHERE removed IS NULL + GROUP BY todolist_id + """ + database = router.db_for_write(TodolistPackage) + connection = connections[database] + cursor = connection.cursor() + cursor.execute(sql, [TodolistPackage.COMPLETE]) + results = cursor.fetchall() + return {row[0]: (row[1], row[2]) for row in results} - # tag each list with an incomplete package count - lookup = dict(incomplete) + +def get_annotated_todolists(incomplete_only=False): + lists = Todolist.objects.all().defer('raw').select_related( + 'creator').order_by('-created') + lookup = todo_counts() + + # tag each list with package counts for todolist in lists: - todolist.incomplete_count = lookup.get(todolist.id, 0) + counts = lookup.get(todolist.id, (0, 0)) + todolist.pkg_count = counts[0] + todolist.complete_count = counts[1] + todolist.incomplete_count = counts[0] - counts[1] + + if incomplete_only: + lists = [l for l in lists if l.incomplete_count > 0] return lists + +def attach_staging(packages, list_id): + '''Look for any staging version of the packages provided and attach them + to the 'staging' attribute on each package if found.''' + pkgnames = TodolistPackage.objects.filter( + todolist_id=list_id).values('pkgname') + staging_pkgs = Package.objects.normal().filter(repo__staging=True, + pkgname__in=pkgnames) + # now build a lookup dict to attach to the correct package + lookup = {(p.pkgname, p.arch): p for p in staging_pkgs} + + annotated = [] + for package in packages: + in_staging = lookup.get((package.pkgname, package.arch), None) + package.staging = in_staging + + return annotated + # vim: set ts=4 sw=4 et: diff --git a/todolists/views.py b/todolists/views.py index 379189ab..7de32036 100644 --- a/todolists/views.py +++ b/todolists/views.py @@ -1,81 +1,103 @@ -from django import forms +import json +from django import forms from django.http import HttpResponse from django.conf import settings from django.core.mail import send_mail -from django.shortcuts import get_list_or_404, get_object_or_404, redirect -from django.contrib.auth.decorators import login_required, permission_required +from django.shortcuts import (get_list_or_404, get_object_or_404, + redirect, render) from django.db import transaction from django.views.decorators.cache import never_cache from django.views.generic import DeleteView -from django.views.generic.simple import direct_to_template from django.template import Context, loader -from django.utils import simplejson +from django.template.defaultfilters import slugify +from django.utils.timezone import now -from main.models import Todolist, TodolistPkg, Package, Repo +from main.models import Package, Repo +from main.utils import find_unique_slug from packages.utils import attach_maintainers -from .utils import get_annotated_todolists +from .models import Todolist, TodolistPackage +from .utils import get_annotated_todolists, attach_staging + class TodoListForm(forms.ModelForm): - packages = forms.CharField(required=False, + raw = forms.CharField(label='Packages', required=False, help_text='(one per line)', widget=forms.Textarea(attrs={'rows': '20', 'cols': '60'})) - def clean_packages(self): - package_names = [s.strip() for s in - self.cleaned_data['packages'].split("\n")] - package_names = set(package_names) - packages = Package.objects.filter(pkgname__in=package_names).filter( - repo__testing=False, repo__staging=False).select_related( - 'arch', 'repo').order_by('arch') - return packages + def package_names(self): + return {s.strip() for s in self.cleaned_data['raw'].split("\n")} + + def packages(self): + return Package.objects.normal().filter( + pkgname__in=self.package_names(), + repo__testing=False, repo__staging=False).order_by('arch') class Meta: model = Todolist - fields = ('name', 'description') + fields = ('name', 'description', 'raw') + -@permission_required('main.change_todolistpkg') @never_cache -def flag(request, list_id, pkg_id): - todolist = get_object_or_404(Todolist, id=list_id) - pkg = get_object_or_404(TodolistPkg, id=pkg_id) - pkg.complete = not pkg.complete - pkg.save() +def flag(request, slug, pkg_id): + todolist = get_object_or_404(Todolist, slug=slug) + tlpkg = get_object_or_404(TodolistPackage, id=pkg_id, removed__isnull=True) + # TODO: none of this; require absolute value on submit + if tlpkg.status == TodolistPackage.INCOMPLETE: + tlpkg.status = TodolistPackage.COMPLETE + else: + tlpkg.status = TodolistPackage.INCOMPLETE + tlpkg.user = request.user + tlpkg.save(update_fields=('status', 'user', 'last_modified')) if request.is_ajax(): - return HttpResponse( - simplejson.dumps({'complete': pkg.complete}), - mimetype='application/json') + data = { + 'status': tlpkg.get_status_display(), + 'css_class': tlpkg.status_css_class(), + } + return HttpResponse(json.dumps(data), content_type='application/json') return redirect(todolist) -@login_required -def view(request, list_id): - todolist = get_object_or_404(Todolist, id=list_id) - svn_roots = Repo.objects.order_by().values_list( - 'svn_root', flat=True).distinct() + +def view_redirect(request, old_id): + todolist = get_object_or_404(Todolist, old_id=old_id) + return redirect(todolist, permanent=True) + + +def view(request, slug): + todolist = get_object_or_404(Todolist, slug=slug) + svn_roots = Repo.objects.values_list( + 'svn_root', flat=True).order_by().distinct() # we don't hold onto the result, but the objects are the same here, # so accessing maintainers in the template is now cheap - attach_maintainers(tp.pkg for tp in todolist.packages) - return direct_to_template(request, 'todolists/view.html', { + attach_maintainers(todolist.packages()) + attach_staging(todolist.packages(), todolist.pk) + arches = {tp.arch for tp in todolist.packages()} + repos = {tp.repo for tp in todolist.packages()} + return render(request, 'todolists/view.html', { 'list': todolist, 'svn_roots': svn_roots, + 'arches': sorted(arches), + 'repos': sorted(repos), }) -# really no need for login_required on this one... -def list_pkgbases(request, list_id, svn_root): + +def list_pkgbases(request, slug, svn_root): '''Used to make bulk moves of packages a lot easier.''' - todolist = get_object_or_404(Todolist, id=list_id) + todolist = get_object_or_404(Todolist, slug=slug) repos = get_list_or_404(Repo, svn_root=svn_root) - pkgbases = set(tp.pkg.pkgbase for tp in todolist.packages - if tp.pkg.repo in repos) - return HttpResponse('\n'.join(sorted(pkgbases)), - mimetype='text/plain') + pkgbases = TodolistPackage.objects.values_list( + 'pkgbase', flat=True).filter( + todolist=todolist, repo__in=repos, removed__isnull=True).order_by( + 'pkgbase').distinct() + return HttpResponse('\n'.join(pkgbases), content_type='text/plain') + -@login_required def todolist_list(request): - lists = get_annotated_todolists() - return direct_to_template(request, 'todolists/list.html', {'lists': lists}) + incomplete_only = request.user.is_anonymous() + lists = get_annotated_todolists(incomplete_only) + return render(request, 'todolists/list.html', {'lists': lists}) + -@permission_required('main.add_todolist') @never_cache def add(request): if request.POST: @@ -89,16 +111,17 @@ def add(request): page_dict = { 'title': 'Add Todo List', + 'description': '', 'form': form, 'submit_text': 'Create List' } - return direct_to_template(request, 'general_form.html', page_dict) + return render(request, 'general_form.html', page_dict) + # TODO: this calls for transaction management and async emailing -@permission_required('main.change_todolist') @never_cache -def edit(request, list_id): - todo_list = get_object_or_404(Todolist, id=list_id) +def edit(request, slug): + todo_list = get_object_or_404(Todolist, slug=slug) if request.POST: form = TodoListForm(request.POST, instance=todo_list) if form.is_valid(): @@ -107,14 +130,16 @@ def edit(request, list_id): return redirect(todo_list) else: form = TodoListForm(instance=todo_list, - initial={ 'packages': '\n'.join(todo_list.package_names) }) + initial={'packages': todo_list.raw}) page_dict = { 'title': 'Edit Todo List: %s' % todo_list.name, + 'description': '', 'form': form, 'submit_text': 'Save List' } - return direct_to_template(request, 'general_form.html', page_dict) + return render(request, 'general_form.html', page_dict) + class DeleteTodolist(DeleteView): model = Todolist @@ -122,36 +147,64 @@ class DeleteTodolist(DeleteView): template_name = 'todolists/todolist_confirm_delete.html' success_url = '/todo/' + @transaction.commit_on_success def create_todolist_packages(form, creator=None): - packages = form.cleaned_data['packages'] + package_names = form.package_names() + packages = form.packages() + timestamp = now() if creator: - # todo list is new + # todo list is new, populate creator and slug fields todolist = form.save(commit=False) todolist.creator = creator + todolist.slug = find_unique_slug(Todolist, todolist.name) todolist.save() - - old_packages = [] else: # todo list already existed form.save() todolist = form.instance - # first delete any packages not in the new list - for todo_pkg in todolist.packages: - if todo_pkg.pkg not in packages: - todo_pkg.delete() - # save the old package list so we know what to add - old_packages = [p.pkg for p in todolist.packages] + # first mark removed any packages not in the new list + to_remove = set() + for todo_pkg in todolist.packages(): + if todo_pkg.pkg and todo_pkg.pkg not in packages: + to_remove.add(todo_pkg.pk) + elif todo_pkg.pkgname not in package_names: + to_remove.add(todo_pkg.pk) + + TodolistPackage.objects.filter( + pk__in=to_remove).update(removed=timestamp) + # Add (or mark unremoved) any packages in the new packages list todo_pkgs = [] for package in packages: - if package not in old_packages: - todo_pkg = TodolistPkg.objects.create(list=todolist, pkg=package) + # ensure get_or_create uses the fields in our unique constraint + defaults = { + 'pkg': package, + 'pkgbase': package.pkgbase, + 'repo': package.repo, + } + todo_pkg, created = TodolistPackage.objects.get_or_create( + todolist=todolist, + pkgname=package.pkgname, + arch=package.arch, + defaults=defaults) + if created: todo_pkgs.append(todo_pkg) + else: + save = False + if todo_pkg.removed is not None: + todo_pkg.removed = None + save = True + if todo_pkg.pkg != package: + todo_pkg.pkg = package + save = True + if save: + todo_pkg.save() return todo_pkgs + def send_todolist_emails(todo_list, new_packages): '''Sends emails to package maintainers notifying them that packages have been added to a todo list.''' @@ -179,12 +232,4 @@ def send_todolist_emails(todo_list, new_packages): [maint], fail_silently=True) -def public_list(request): - todo_lists = Todolist.objects.incomplete() - # total hackjob, but it makes this a lot less query-intensive. - all_pkgs = [tp for tl in todo_lists for tp in tl.packages] - attach_maintainers([tp.pkg for tp in all_pkgs]) - return direct_to_template(request, "todolists/public_list.html", - {"todo_lists": todo_lists}) - # vim: set ts=4 sw=4 et: |