This is a series of 50 migrations that changes the Document and DocAlias

primary keys from character strings to integers, and makes corresponding code
changes.

This was prompted by database limitations discovered when trying to make
DocAlias use a m2m document field; with 255 long strings as primary keys for
Document and DocAlias this violated the MySQL database limitations.

Changing the primary keys to integers should also improve efficiency.  

Due to the data migrations which create the new integer primary keys and adds
corresponding integer foreign keys matching the previous string foreign keys
in all tables having foreign keys to Document and DocAlias, some of these
migrations take a long time.  The total set of migrations are expected to have
a runtime on the order of 2 hours.
 - Legacy-Id: 16237
This commit is contained in:
Henrik Levkowetz 2019-06-10 11:32:46 +00:00
parent 1f949d758c
commit 815602351f
88 changed files with 4657 additions and 127 deletions

View file

@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-21 14:23
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
import ietf.utils.models
class Migration(migrations.Migration):
dependencies = [
('community', '0002_auto_20180220_1052'),
]
operations = [
migrations.CreateModel(
name='CommunityListDocs',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('communitylist', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='community.CommunityList')),
('document', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id')),
],
),
migrations.AddField(
model_name='communitylist',
name='added_docs2',
field=models.ManyToManyField(related_name='communitylists', through='community.CommunityListDocs', to='doc.Document'),
),
migrations.CreateModel(
name='SearchRuleDocs',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('document', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id')),
('searchrule', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='community.SearchRule')),
],
),
migrations.AddField(
model_name='searchrule',
name='name_contains_index2',
field=models.ManyToManyField(related_name='searchrules', through='community.SearchRuleDocs', to='doc.Document'),
),
]

View file

@ -0,0 +1,55 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-21 14:27
from __future__ import unicode_literals
import sys
from tqdm import tqdm
from django.db import migrations
def forward(apps, schema_editor):
Document = apps.get_model('doc','Document')
CommunityList = apps.get_model('community', 'CommunityList')
CommunityListDocs = apps.get_model('community', 'CommunityListDocs')
SearchRule = apps.get_model('community', 'SearchRule')
SearchRuleDocs = apps.get_model('community', 'SearchRuleDocs')
# Document id fixup ------------------------------------------------------------
objs = Document.objects.in_bulk()
nameid = { o.name: o.id for id, o in objs.iteritems() }
sys.stderr.write('\n')
sys.stderr.write(' %s.%s:\n' % (CommunityList.__name__, 'added_docs'))
count = 0
for l in tqdm(CommunityList.objects.all()):
for d in l.added_docs.all():
count += 1
CommunityListDocs.objects.get_or_create(communitylist=l, document_id=nameid[d.name])
sys.stderr.write(' %s CommunityListDocs objects created\n' % (count, ))
sys.stderr.write(' %s.%s:\n' % (SearchRule.__name__, 'name_contains_index'))
count = 0
for r in tqdm(SearchRule.objects.all()):
for d in r.name_contains_index.all():
count += 1
SearchRuleDocs.objects.get_or_create(searchrule=r, document_id=nameid[d.name])
sys.stderr.write(' %s SearchRuleDocs objects created\n' % (count, ))
def reverse(apps, schema_editor):
pass
class Migration(migrations.Migration):
dependencies = [
('community', '0003_add_communitylist_docs2_m2m'),
('doc', '0014_set_document_docalias_id'),
]
operations = [
migrations.RunPython(forward, reverse),
]

View file

@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-22 08:15
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('community', '0004_set_document_m2m_keys'),
]
# The implementation of AlterField in Django 1.11 applies
# 'ALTER TABLE <table> MODIFY <field> ...;' in order to fix foregn keys
# to the altered field, but as it seems does _not_ fix up m2m
# intermediary tables in an equivalent manner, so here we remove and
# then recreate the m2m tables so they will have the appropriate field
# types.
operations = [
# Remove fields
migrations.RemoveField(
model_name='communitylist',
name='added_docs',
),
migrations.RemoveField(
model_name='searchrule',
name='name_contains_index',
),
]

View file

@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-22 08:15
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('community', '0005_1_del_docs_m2m_table'),
]
# The implementation of AlterField in Django 1.11 applies
# 'ALTER TABLE <table> MODIFY <field> ...;' in order to fix foregn keys
# to the altered field, but as it seems does _not_ fix up m2m
# intermediary tables in an equivalent manner, so here we remove and
# then recreate the m2m tables so they will have the appropriate field
# types.
operations = [
# Add fields back (will create the m2m tables with the right field types)
migrations.AddField(
model_name='communitylist',
name='added_docs',
field=models.ManyToManyField(to='doc.Document'),
),
migrations.AddField(
model_name='searchrule',
name='name_contains_index',
field=models.ManyToManyField(to='doc.Document'),
),
]

View file

@ -0,0 +1,56 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-27 05:56
from __future__ import unicode_literals
from django.db import migrations
import sys, time
from tqdm import tqdm
def forward(apps, schema_editor):
CommunityList = apps.get_model('community', 'CommunityList')
CommunityListDocs = apps.get_model('community', 'CommunityListDocs')
SearchRule = apps.get_model('community', 'SearchRule')
SearchRuleDocs = apps.get_model('community', 'SearchRuleDocs')
# Document id fixup ------------------------------------------------------------
sys.stderr.write('\n')
sys.stderr.write(' %s.%s:\n' % (CommunityList.__name__, 'added_docs'))
for l in tqdm(CommunityList.objects.all()):
l.added_docs.set([ d.document for d in CommunityListDocs.objects.filter(communitylist=l) ])
sys.stderr.write(' %s.%s:\n' % (SearchRule.__name__, 'name_contains_index'))
for r in tqdm(SearchRule.objects.all()):
r.name_contains_index.set([ d.document for d in SearchRuleDocs.objects.filter(searchrule=r) ])
def reverse(apps, schema_editor):
pass
def timestamp(apps, schema_editor):
sys.stderr.write('\n %s' % time.strftime('%Y-%m-%d %H:%M:%S'))
class Migration(migrations.Migration):
dependencies = [
('community', '0005_2_add_docs_m2m_table'),
]
operations = [
#migrations.RunPython(forward, reverse),
# Alternative:
migrations.RunPython(timestamp, timestamp),
migrations.RunSQL(
"INSERT INTO community_communitylist_added_docs SELECT * FROM community_communitylistdocs;",
""),
migrations.RunPython(timestamp, timestamp),
migrations.RunSQL(
"INSERT INTO community_searchrule_name_contains_index SELECT * FROM community_searchruledocs;",
""),
migrations.RunPython(timestamp, timestamp),
]

View file

@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-30 03:06
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('community', '0006_copy_docs_m2m_table'),
]
operations = [
migrations.RemoveField(
model_name='communitylistdocs',
name='communitylist',
),
migrations.RemoveField(
model_name='communitylistdocs',
name='document',
),
migrations.RemoveField(
model_name='searchruledocs',
name='document',
),
migrations.RemoveField(
model_name='searchruledocs',
name='searchrule',
),
migrations.RemoveField(
model_name='communitylist',
name='added_docs2',
),
migrations.RemoveField(
model_name='searchrule',
name='name_contains_index2',
),
migrations.DeleteModel(
name='CommunityListDocs',
),
migrations.DeleteModel(
name='SearchRuleDocs',
),
]

View file

@ -107,7 +107,7 @@ class CommunityListTests(TestCase):
self.assertEqual(r.status_code, 200)
# add document
r = self.client.post(url, { "action": "add_documents", "documents": draft.pk })
r = self.client.post(url, { "action": "add_documents", "documents": draft.name })
self.assertEqual(r.status_code, 302)
clist = CommunityList.objects.get(user__username="plain")
self.assertTrue(clist.added_docs.filter(pk=draft.pk))
@ -118,7 +118,7 @@ class CommunityListTests(TestCase):
self.assertTrue(draft.name in unicontent(r))
# remove document
r = self.client.post(url, { "action": "remove_document", "document": draft.pk })
r = self.client.post(url, { "action": "remove_document", "document": draft.name })
self.assertEqual(r.status_code, 302)
clist = CommunityList.objects.get(user__username="plain")
self.assertTrue(not clist.added_docs.filter(pk=draft.pk))

View file

@ -61,7 +61,7 @@ def augment_docs_with_tracking_info(docs, user):
if user and user.is_authenticated:
clist = CommunityList.objects.filter(user=user).first()
if clist:
tracked.update(docs_tracked_by_community_list(clist).filter(pk__in=docs).values_list("pk", flat=True))
tracked.update(docs_tracked_by_community_list(clist).filter(pk__in=[ d.pk for d in docs ]).values_list("pk", flat=True))
for d in docs:
d.tracked_in_personal_community_list = d.pk in tracked

View file

@ -57,9 +57,9 @@ def manage_list(request, username=None, acronym=None, group_type=None):
add_doc_form = AddDocumentsForm()
if request.method == 'POST' and action == 'remove_document':
document_pk = request.POST.get('document')
if clist.pk is not None and document_pk:
document = get_object_or_404(clist.added_docs, pk=document_pk)
document_name = request.POST.get('document')
if clist.pk is not None and document_name:
document = get_object_or_404(clist.added_docs, name=document_name)
clist.added_docs.remove(document)
return HttpResponseRedirect("")
@ -209,7 +209,7 @@ def feed(request, username=None, acronym=None, group_type=None):
since = datetime.datetime.now() - datetime.timedelta(days=14)
events = DocEvent.objects.filter(
doc__in=documents,
doc__id__in=documents,
time__gte=since,
).distinct().order_by('-time', '-id').select_related("doc")

View file

@ -2,6 +2,7 @@ import json
from django.utils.html import escape
from django import forms
from django.db.models import Q
from django.urls import reverse as urlreverse
import debug # pyflakes:ignore
@ -52,8 +53,10 @@ class SearchableDocumentsField(forms.CharField):
if isinstance(value, (int, long)):
value = str(value)
if isinstance(value, basestring):
pks = self.parse_select2_value(value)
value = self.model.objects.filter(pk__in=pks)
items = self.parse_select2_value(value)
names = [ i for i in items if not i.isdigit() ]
ids = [ i for i in items if i.isdigit() ]
value = self.model.objects.filter(Q(name__in=names)|Q(id__in=ids))
filter_args = {}
if self.model == DocAlias:
filter_args["document__type"] = self.doc_type
@ -76,17 +79,17 @@ class SearchableDocumentsField(forms.CharField):
def clean(self, value):
value = super(SearchableDocumentsField, self).clean(value)
pks = self.parse_select2_value(value)
names = self.parse_select2_value(value)
objs = self.model.objects.filter(pk__in=pks)
objs = self.model.objects.filter(name__in=names)
found_pks = [str(o.pk) for o in objs]
failed_pks = [x for x in pks if x not in found_pks]
if failed_pks:
raise forms.ValidationError(u"Could not recognize the following documents: {pks}. You can only input documents already registered in the Datatracker.".format(pks=", ".join(failed_pks)))
found_names = [str(o.name) for o in objs]
failed_names = [x for x in names if x not in found_names]
if failed_names:
raise forms.ValidationError(u"Could not recognize the following documents: {names}. You can only input documents already registered in the Datatracker.".format(names=", ".join(failed_names)))
if self.max_entries != None and len(objs) > self.max_entries:
raise forms.ValidationError(u"You can select at most %s entries only." % self.max_entries)
raise forms.ValidationError(u"You can select at most %s entries." % self.max_entries)
return objs

View file

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-08 08:41
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('doc', '0012_add_event_type_closed_review_assignment'),
]
operations = [
migrations.AddField(
model_name='docalias',
name='id',
field=models.IntegerField(default=0),
),
migrations.AddField(
model_name='document',
name='id',
field=models.IntegerField(default=0),
),
]

View file

@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-08 08:42
from __future__ import unicode_literals
import sys
from tqdm import tqdm
from django.db import migrations
def forward(apps, schema_editor):
Document = apps.get_model('doc','Document')
sys.stderr.write('\n')
for i, d in enumerate(tqdm(Document.objects.all()), start=1):
d.id = i
d.save()
DocAlias = apps.get_model('doc','DocAlias')
for i, d in enumerate(tqdm(DocAlias.objects.all()), start=1):
d.id = i
d.save()
def reverse(apps, schema_editor):
pass
class Migration(migrations.Migration):
dependencies = [
('doc', '0013_add_document_docalias_id'),
]
operations = [
migrations.RunPython(forward, reverse),
]

View file

@ -0,0 +1,121 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-08 10:29
from __future__ import unicode_literals
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
import ietf.utils.models
class Migration(migrations.Migration):
dependencies = [
('doc', '0014_set_document_docalias_id'),
]
operations = [
# Fix name and id fields first
migrations.AlterField(
model_name='docalias',
name='name',
field=models.CharField(max_length=255, unique=True),
),
migrations.AlterField(
model_name='docalias',
name='id',
field=models.IntegerField(primary_key=True, serialize=False),
),
migrations.AlterField(
model_name='document',
name='name',
field=models.CharField(max_length=255, unique=True, validators=[django.core.validators.RegexValidator(b'^[-a-z0-9]+$', b'Provide a valid document name consisting of lowercase letters, numbers and hyphens.', b'invalid')]),
),
migrations.AlterField(
model_name='document',
name='id',
field=models.IntegerField(primary_key=True, serialize=False),
),
# Then remaining fields
migrations.AddField(
model_name='docalias',
name='document2',
field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id'),
),
migrations.AddField(
model_name='dochistory',
name='doc2',
field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='history_set', to='doc.Document', to_field=b'id'),
),
migrations.AddField(
model_name='documentauthor',
name='document2',
field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id'),
),
migrations.AddField(
model_name='documenturl',
name='doc2',
field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id'),
),
migrations.AddField(
model_name='relateddochistory',
name='target2',
field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='reversely_related_document_history_set', to='doc.DocAlias', to_field=b'id'),
),
migrations.AddField(
model_name='relateddocument',
name='source2',
field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id'),
),
migrations.AddField(
model_name='relateddocument',
name='target2',
field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.DocAlias', to_field=b'id'),
),
migrations.AddField(
model_name='docevent',
name='doc2',
field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field='id'),
),
migrations.AlterField(
model_name='docalias',
name='document',
field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_docalias', to='doc.Document', to_field=b'name'),
),
migrations.AlterField(
model_name='dochistory',
name='doc',
field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_hist', to='doc.Document', to_field=b'name'),
),
migrations.AlterField(
model_name='documentauthor',
name='document',
field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_doc_auth', to='doc.Document', to_field=b'name'),
),
migrations.AlterField(
model_name='documenturl',
name='doc',
field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_doc_url', to='doc.Document', to_field=b'name'),
),
migrations.AlterField(
model_name='relateddochistory',
name='target',
field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_hist_target', to='doc.DocAlias', to_field=b'name'),
),
migrations.AlterField(
model_name='relateddocument',
name='source',
field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_rel_source', to='doc.Document', to_field=b'name'),
),
migrations.AlterField(
model_name='relateddocument',
name='target',
field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_rel_target', to='doc.DocAlias', to_field=b'name'),
),
migrations.AlterField(
model_name='docevent',
name='doc',
field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_docevent', to='doc.Document', to_field=b'name'),
),
]

View file

@ -0,0 +1,93 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-28 12:42
from __future__ import unicode_literals
import sys, time
from django.db import migrations, models
import django.db.models.deletion
import ietf.utils.models
def timestamp(apps, schema_editor):
sys.stderr.write('\n %s' % time.strftime('%Y-%m-%d %H:%M:%S'))
class Migration(migrations.Migration):
dependencies = [
('name', '0006_adjust_statenames'),
('doc', '0015_1_add_fk_to_document_id'),
]
operations = [
migrations.CreateModel(
name='DocumentLanguages',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('document', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field='name', related_name='doclanguages')),
('formallanguagename', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='name.FormalLanguageName')),
],
),
migrations.CreateModel(
name='DocumentStates',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('document', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field='name', related_name='docstates')),
('state', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.State')),
],
),
migrations.CreateModel(
name='DocumentTags',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('document', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field='name', related_name='doctags')),
('doctagname', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='name.DocTagName')),
],
),
migrations.AddField(
model_name='document',
name='formal_languages2',
field=models.ManyToManyField(blank=True, related_name='languagedocs', through='doc.DocumentLanguages', to='name.FormalLanguageName'),
),
migrations.AddField(
model_name='document',
name='states2',
field=models.ManyToManyField(blank=True, related_name='statedocs', through='doc.DocumentStates', to='doc.State'),
),
migrations.AddField(
model_name='document',
name='tags2',
field=models.ManyToManyField(blank=True, related_name='tagdocs', through='doc.DocumentTags', to='name.DocTagName'),
),
# Here we copy the content of the existing implicit m2m tables for
# the Document m2m fields into the explicit through tabeles, in order
# to be able to later set the correct id from name
migrations.RunPython(timestamp, timestamp),
migrations.RunSQL(
"INSERT INTO doc_documentlanguages SELECT * FROM doc_document_formal_languages;",
""),
migrations.RunPython(timestamp, timestamp),
migrations.RunSQL(
"INSERT INTO doc_documentstates SELECT * FROM doc_document_states;",
""),
migrations.RunPython(timestamp, timestamp),
migrations.RunSQL(
"INSERT INTO doc_documenttags SELECT * FROM doc_document_tags;",
""),
migrations.RunPython(timestamp, timestamp),
migrations.AddField(
model_name='documentlanguages',
name='document2',
field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field='id', null=True, default=None),
),
migrations.AddField(
model_name='documentstates',
name='document2',
field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field='id', null=True, default=None), ),
migrations.AddField(
model_name='documenttags',
name='document2',
field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field='id', null=True, default=None),
),
]

View file

@ -0,0 +1,112 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-08 14:04
from __future__ import unicode_literals
import sys
from tqdm import tqdm
from django.db import migrations
def forward(apps, schema_editor):
def add_id_fk(o, a, nameid):
n = getattr(o, a+'_id')
if n:
i = nameid[n]
if not isinstance(i, (int, long)):
raise ValueError("Inappropriate value: %s: nameid[%s]: %s" % (o.__class__.__name__, n, i))
if getattr(o, a+'2_id') != i:
setattr(o, a+'2_id', i)
o.save()
DocAlias = apps.get_model('doc','DocAlias')
DocEvent = apps.get_model('doc', 'DocEvent')
DocHistory = apps.get_model('doc', 'DocHistory')
Document = apps.get_model('doc', 'Document')
DocumentAuthor = apps.get_model('doc', 'DocumentAuthor')
DocumentLanguages = apps.get_model('doc', 'DocumentLanguages')
DocumentStates = apps.get_model('doc', 'DocumentStates')
DocumentTags = apps.get_model('doc', 'DocumentTags')
DocumentURL = apps.get_model('doc', 'DocumentURL')
Group = apps.get_model('group', 'Group')
IprDocRel = apps.get_model('ipr', 'IprDocRel')
LiaisonStatementAttachment = apps.get_model('liaisons', 'LiaisonStatementAttachment')
RelatedDocHistory = apps.get_model('doc', 'RelatedDocHistory')
RelatedDocument = apps.get_model('doc', 'RelatedDocument')
ReviewAssignment = apps.get_model('review', 'ReviewAssignment')
ReviewRequest = apps.get_model('review', 'ReviewRequest')
ReviewWish = apps.get_model('review', 'ReviewWish')
SessionPresentation = apps.get_model('meeting', 'SessionPresentation')
Submission = apps.get_model('submit', 'Submission')
# Document id fixup ------------------------------------------------------------
objs = Document.objects.in_bulk()
nameid = { o.name: o.id for id, o in objs.iteritems() }
sys.stderr.write('\n')
sys.stderr.write('Setting Document FKs:\n')
for C, a in [
( DocAlias , 'document'),
( DocEvent , 'doc'),
( DocHistory , 'doc'),
( DocumentAuthor , 'document'),
( DocumentLanguages , 'document'),
( DocumentStates , 'document'),
( DocumentTags , 'document'),
( DocumentURL , 'doc'),
( Group , 'charter'),
( LiaisonStatementAttachment , 'document'),
( RelatedDocument , 'source'),
( ReviewAssignment , 'review'),
( ReviewRequest , 'doc'),
( ReviewRequest , 'unused_review'),
( ReviewWish , 'doc'),
( SessionPresentation , 'document'),
( Submission , 'draft'),
]:
sys.stderr.write(' %s.%s:\n' % (C.__name__, a))
for o in tqdm(C.objects.all()):
add_id_fk(o, a, nameid)
# DocAlias id fixup ------------------------------------------------------------
sys.stderr.write('\n')
objs = DocAlias.objects.in_bulk()
nameid = { o.name: o.id for id, o in objs.iteritems() }
sys.stderr.write('Setting DocAlias FKs:\n')
for C, a in [
( IprDocRel , 'document'),
( RelatedDocument , 'target'),
( RelatedDocHistory , 'target'),
]:
sys.stderr.write(' %s.%s:\n' % (C.__name__, a))
for o in tqdm(C.objects.all()):
add_id_fk(o, a, nameid)
def reverse(apps, schema_editor):
pass
class Migration(migrations.Migration):
dependencies = [
('community', '0004_set_document_m2m_keys'),
('doc', '0015_2_add_doc_document_m2m_fields'),
('group', '0014_set_document_m2m_keys'),
('ipr', '0003_add_ipdocrel_document2_fk'),
('liaisons', '0003_liaison_document2_fk'),
('meeting', '0015_sessionpresentation_document2_fk'),
('message', '0003_set_document_m2m_keys'),
('review', '0011_review_document2_fk'),
('submit', '0002_submission_document2_fk'),
]
operations = [
migrations.RunPython(forward, reverse),
]

View file

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-09 05:46
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('doc', '0016_set_document_docalias_fk'),
]
operations = [
migrations.AlterField(
model_name='docalias',
name='id',
field=models.AutoField(primary_key=True, serialize=False),
),
migrations.AlterField(
model_name='document',
name='id',
field=models.AutoField(primary_key=True, serialize=False),
),
]

View file

@ -0,0 +1,124 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-20 09:53
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
import ietf.utils.models
class Migration(migrations.Migration):
dependencies = [
('doc', '0017_make_document_id_primary_key'),
]
operations = [
migrations.AlterModelOptions(
name='documentauthor',
options={'ordering': ['document2', 'order']},
),
migrations.RemoveIndex(
model_name='docevent',
name='doc_doceven_type_43e53e_idx',
),
migrations.RemoveField(
model_name='docalias',
name='document',
),
migrations.RemoveField(
model_name='docevent',
name='doc',
),
migrations.RemoveField(
model_name='dochistory',
name='doc',
),
migrations.RemoveField(
model_name='documentauthor',
name='document',
),
migrations.RemoveField(
model_name='documenturl',
name='doc',
),
migrations.RemoveField(
model_name='relateddochistory',
name='target',
),
migrations.RemoveField(
model_name='relateddocument',
name='source',
),
migrations.RemoveField(
model_name='relateddocument',
name='target',
),
migrations.AddIndex(
model_name='docevent',
index=models.Index(fields=[b'type', b'doc2'], name='doc_doceven_type_ac7748_idx'),
),
# The following 9 migrations are related to the m2m fields on Document
# Remove the intermediary model field pointing to Document.name
migrations.RemoveField(
model_name='documentlanguages',
name='document',
),
migrations.RemoveField(
model_name='documentstates',
name='document',
),
migrations.RemoveField(
model_name='documenttags',
name='document',
),
# Rename the intermediary model field pointing to Document.id, to
# match the implicit m2m table
migrations.RenameField(
model_name='documentlanguages',
old_name='document2',
new_name='document',
),
migrations.RenameField(
model_name='documentstates',
old_name='document2',
new_name='document',
),
migrations.RenameField(
model_name='documenttags',
old_name='document2',
new_name='document',
),
# Alter the fields to point to Document.pk instead of Document.name
migrations.AlterField(
model_name='documentlanguages',
name='document',
field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document'),
),
migrations.AlterField(
model_name='documentstates',
name='document',
field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document'),
),
migrations.AlterField(
model_name='documenttags',
name='document',
field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document'),
),
# Remove the implicit m2m tables which point to Document.name
migrations.RemoveField(
model_name='document',
name='formal_languages',
),
migrations.RemoveField(
model_name='document',
name='states',
),
migrations.RemoveField(
model_name='document',
name='tags',
),
# Next (in a separate migration, in order to commit the above before
# we proceed) we'll create the implicit m2m tables again, this time
# pointing to Document.id since that's now the primary key.
]

View file

@ -0,0 +1,83 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-21 05:31
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('doc', '0018_remove_old_document_field'),
]
operations = [
migrations.AlterModelOptions(
name='documentauthor',
options={'ordering': ['document', 'order']},
),
migrations.RemoveIndex(
model_name='docevent',
name='doc_doceven_type_ac7748_idx',
),
migrations.RenameField(
model_name='docalias',
old_name='document2',
new_name='document',
),
migrations.RenameField(
model_name='docevent',
old_name='doc2',
new_name='doc',
),
migrations.RenameField(
model_name='dochistory',
old_name='doc2',
new_name='doc',
),
migrations.RenameField(
model_name='documentauthor',
old_name='document2',
new_name='document',
),
migrations.RenameField(
model_name='documenturl',
old_name='doc2',
new_name='doc',
),
migrations.RenameField(
model_name='relateddochistory',
old_name='target2',
new_name='target',
),
migrations.RenameField(
model_name='relateddocument',
old_name='source2',
new_name='source',
),
migrations.RenameField(
model_name='relateddocument',
old_name='target2',
new_name='target',
),
migrations.AddIndex(
model_name='docevent',
index=models.Index(fields=[b'type', b'doc'], name='doc_doceven_type_43e53e_idx'),
),
# Add back the m2m field we removed in 0018_...
migrations.AddField(
model_name='document',
name='formal_languages',
field=models.ManyToManyField(blank=True, help_text=b'Formal languages used in document', to='name.FormalLanguageName'),
),
migrations.AddField(
model_name='document',
name='states',
field=models.ManyToManyField(blank=True, to='doc.State'),
),
migrations.AddField(
model_name='document',
name='tags',
field=models.ManyToManyField(blank=True, to='name.DocTagName'),
),
]

View file

@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-21 05:31
from __future__ import unicode_literals
import sys, time
from django.db import migrations
def timestamp(apps, schema_editor):
sys.stderr.write('\n %s' % time.strftime('%Y-%m-%d %H:%M:%S'))
class Migration(migrations.Migration):
dependencies = [
('doc', '0019_rename_field_document2'),
]
operations = [
# Copy the doc IDs from the explicit m2m table to the implicit table
migrations.RunPython(timestamp, timestamp),
migrations.RunSQL(
"INSERT INTO doc_document_formal_languages SELECT id,document_id,formallanguagename_id FROM doc_documentlanguages;",
""),
migrations.RunPython(timestamp, timestamp),
migrations.RunSQL(
"INSERT INTO doc_document_states SELECT id,document_id,state_id FROM doc_documentstates;",
""),
migrations.RunPython(timestamp, timestamp),
migrations.RunSQL(
"INSERT INTO doc_document_tags SELECT id,document_id,doctagname_id FROM doc_documenttags;",
""),
migrations.RunPython(timestamp, timestamp),
]

View file

@ -0,0 +1,62 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-30 03:36
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('doc', '0020_copy_docs_m2m_table'),
]
operations = [
# Get rid of the explicit m2m tables which we needed only to be
# able to convert from Document.name to Document.id
migrations.RemoveField(
model_name='documentlanguages',
name='document',
),
migrations.RemoveField(
model_name='documentlanguages',
name='formallanguagename',
),
migrations.RemoveField(
model_name='documentstates',
name='document',
),
migrations.RemoveField(
model_name='documentstates',
name='state',
),
migrations.RemoveField(
model_name='documenttags',
name='doctagname',
),
migrations.RemoveField(
model_name='documenttags',
name='document',
),
migrations.RemoveField(
model_name='document',
name='formal_languages2',
),
migrations.RemoveField(
model_name='document',
name='states2',
),
migrations.RemoveField(
model_name='document',
name='tags2',
),
migrations.DeleteModel(
name='DocumentLanguages',
),
migrations.DeleteModel(
name='DocumentStates',
),
migrations.DeleteModel(
name='DocumentTags',
),
]

View file

@ -0,0 +1,67 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-06-10 03:47
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
import ietf.utils.models
class Migration(migrations.Migration):
dependencies = [
('doc', '0021_remove_docs2_m2m'),
]
operations = [
migrations.AlterField(
model_name='docalias',
name='document',
field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document'),
),
migrations.AlterField(
model_name='docalias',
name='id',
field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='docevent',
name='doc',
field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document'),
),
migrations.AlterField(
model_name='dochistory',
name='doc',
field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='history_set', to='doc.Document'),
),
migrations.AlterField(
model_name='document',
name='id',
field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='documentauthor',
name='document',
field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document'),
),
migrations.AlterField(
model_name='documenturl',
name='doc',
field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document'),
),
migrations.AlterField(
model_name='relateddochistory',
name='target',
field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reversely_related_document_history_set', to='doc.DocAlias'),
),
migrations.AlterField(
model_name='relateddocument',
name='source',
field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document'),
),
migrations.AlterField(
model_name='relateddocument',
name='target',
field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.DocAlias'),
),
]

View file

@ -609,7 +609,7 @@ validate_docname = RegexValidator(
)
class Document(DocumentInfo):
name = models.CharField(max_length=255, primary_key=True, validators=[validate_docname,]) # immutable
name = models.CharField(max_length=255, validators=[validate_docname,], unique=True) # immutable
def __unicode__(self):
return self.name
@ -908,8 +908,10 @@ class DocAlias(models.Model):
same immutable Document.name, in the tables, but will be referred
to by RFC number, primarily, after achieving RFC status.
"""
name = models.CharField(max_length=255, primary_key=True)
name = models.CharField(max_length=255, unique=True)
document = ForeignKey(Document)
# docs = models.ManyToManyField(Document, related_name='aliases')
def __unicode__(self):
return "%s-->%s" % (self.name, self.document.name)
document_link = admin_link("document")
@ -1005,7 +1007,7 @@ class DocEvent(models.Model):
time = models.DateTimeField(default=datetime.datetime.now, help_text="When the event happened", db_index=True)
type = models.CharField(max_length=50, choices=EVENT_TYPES)
by = ForeignKey(Person)
doc = ForeignKey('doc.Document')
doc = ForeignKey(Document)
rev = models.CharField(verbose_name="revision", max_length=16, null=True, blank=True)
desc = models.TextField()

View file

@ -685,8 +685,8 @@ def extract_complete_replaces_ancestor_mapping_for_docs(names):
break
relations = RelatedDocument.objects.filter(
source__in=front, relationship="replaces"
).select_related("target").values_list("source", "target__document")
source__name__in=front, relationship="replaces"
).select_related("target").values_list("source__name", "target__document__name")
if not relations:
break

View file

@ -20,7 +20,7 @@ def fill_in_telechat_date(docs, doc_dict=None, doc_ids=None):
doc_ids = doc_dict.keys()
seen = set()
for e in TelechatDocEvent.objects.filter(doc__in=doc_ids, type="scheduled_for_telechat").order_by('-time'):
for e in TelechatDocEvent.objects.filter(doc__id__in=doc_ids, type="scheduled_for_telechat").order_by('-time'):
if e.doc_id not in seen:
d = doc_dict[e.doc_id]
d.telechat_date = wrap_value(d.telechat_date(e))
@ -49,7 +49,7 @@ def fill_in_document_table_attributes(docs, have_telechat_date=False):
doc_dict = dict((d.pk, d) for d in docs)
doc_ids = doc_dict.keys()
rfc_aliases = dict(DocAlias.objects.filter(name__startswith="rfc", document__in=doc_ids).values_list("document", "name"))
rfc_aliases = dict(DocAlias.objects.filter(name__startswith="rfc", document__id__in=doc_ids).values_list("document__id", "name"))
# latest event cache
event_types = ("published_rfc",
@ -61,11 +61,11 @@ def fill_in_document_table_attributes(docs, have_telechat_date=False):
for e in event_types:
d.latest_event_cache[e] = None
for e in DocEvent.objects.filter(doc__in=doc_ids, type__in=event_types).order_by('time'):
for e in DocEvent.objects.filter(doc__id__in=doc_ids, type__in=event_types).order_by('time'):
doc_dict[e.doc_id].latest_event_cache[e.type] = e
seen = set()
for e in BallotDocEvent.objects.filter(doc__in=doc_ids, type__in=('created_ballot', 'closed_ballot')).order_by('-time','-id'):
for e in BallotDocEvent.objects.filter(doc__id__in=doc_ids, type__in=('created_ballot', 'closed_ballot')).order_by('-time','-id'):
if not e.doc_id in seen:
doc_dict[e.doc_id].ballot = e if e.type == 'created_ballot' else None
seen.add(e.doc_id)

View file

@ -382,7 +382,7 @@ def document_main(request, name, rev=None):
published = doc.latest_event(type="published_rfc")
started_iesg_process = doc.latest_event(type="started_iesg_process")
review_assignments = review_assignments_to_list_for_docs([doc]).get(doc.pk, [])
review_assignments = review_assignments_to_list_for_docs([doc]).get(doc.name, [])
no_review_from_teams = no_review_from_teams_on_doc(doc, rev or doc.rev)
return render(request, "doc/document_draft.html",
@ -598,11 +598,11 @@ def document_main(request, name, rev=None):
# If we want to go back to using markup_txt.markup_unicode, call it explicitly here like this:
# content = markup_txt.markup_unicode(content, split=False, width=80)
review_assignment = ReviewAssignment.objects.filter(review=doc.name).first()
review_assignment = ReviewAssignment.objects.filter(review__name=doc.name).first()
other_reviews = []
if review_assignment:
other_reviews = [r for r in review_assignments_to_list_for_docs([review_assignment.review_request.doc]).get(doc.pk, []) if r != review_assignment]
other_reviews = [r for r in review_assignments_to_list_for_docs([review_assignment.review_request.doc]).get(doc.name, []) if r != review_assignment]
return render(request, "doc/document_review.html",
dict(doc=doc,

View file

@ -478,7 +478,7 @@ def index_all_drafts(request):
else:
heading = "%s Internet-Drafts" % state.name
draft_names = DocAlias.objects.filter(document__states=state).values_list("name", "document")
draft_names = DocAlias.objects.filter(document__states=state).values_list("name", "document__name")
names = []
names_to_skip = set()

View file

@ -38,7 +38,7 @@ class GroupChangesFeed(Feed):
def item_link(self, obj):
if isinstance(obj, DocEvent):
return urlreverse("ietf.doc.views_doc.document_main", kwargs={'name': obj.doc_id })
return urlreverse("ietf.doc.views_doc.document_main", kwargs={'name': obj.doc.name })
elif isinstance(obj, GroupEvent):
return obj.group.about_url()

View file

@ -227,7 +227,7 @@ class ManageReviewRequestForm(forms.Form):
def __init__(self, review_req, *args, **kwargs):
if not "prefix" in kwargs:
if review_req.pk is None:
kwargs["prefix"] = "r{}-{}".format(review_req.type_id, review_req.doc_id)
kwargs["prefix"] = "r{}-{}".format(review_req.type_id, review_req.doc.name)
else:
kwargs["prefix"] = "r{}".format(review_req.pk)

View file

@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-02-25 13:02
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
import ietf.utils.models
class Migration(migrations.Migration):
dependencies = [
('group', '0012_add_old_nomcom_announcements'),
]
operations = [
migrations.CreateModel(
name='GroupMilestoneDocs',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('document', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id')),
('groupmilestone', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='group.GroupMilestone')),
],
),
migrations.CreateModel(
name='GroupMilestoneHistoryDocs',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('document', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id')),
('groupmilestonehistory', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='group.GroupMilestoneHistory')),
],
),
migrations.AddField(
model_name='group',
name='charter2',
field=ietf.utils.models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='chartered_group', to='doc.Document', to_field=b'id'),
),
migrations.AlterField(
model_name='group',
name='charter',
field=ietf.utils.models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='old_group', to='doc.Document', to_field=b'name'),
),
migrations.AddField(
model_name='groupmilestone',
name='docs2',
field=models.ManyToManyField(blank=True, related_name='groupmilestones', through='group.GroupMilestoneDocs', to='doc.Document'),
),
migrations.AddField(
model_name='groupmilestonehistory',
name='docs2',
field=models.ManyToManyField(blank=True, related_name='groupmilestoneshistory', through='group.GroupMilestoneHistoryDocs', to='doc.Document'),
),
]

View file

@ -0,0 +1,56 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-10 06:48
from __future__ import unicode_literals
import sys
from tqdm import tqdm
from django.db import migrations
def forward(apps, schema_editor):
Document = apps.get_model('doc','Document')
GroupMilestone = apps.get_model('group', 'GroupMilestone')
GroupMilestoneDocs = apps.get_model('group', 'GroupMilestoneDocs')
GroupMilestoneHistory = apps.get_model('group', 'GroupMilestoneHistory')
GroupMilestoneHistoryDocs = apps.get_model('group', 'GroupMilestoneHistoryDocs')
# Document id fixup ------------------------------------------------------------
objs = Document.objects.in_bulk()
nameid = { o.name: o.id for id, o in objs.iteritems() }
sys.stderr.write('\n')
sys.stderr.write(' %s.%s:\n' % (GroupMilestone.__name__, 'docs'))
count = 0
for m in tqdm(GroupMilestone.objects.all()):
for d in m.docs.all():
count += 1
GroupMilestoneDocs.objects.get_or_create(groupmilestone=m, document_id=nameid[d.name])
sys.stderr.write(' %s GroupMilestoneDocs objects created\n' % (count, ))
sys.stderr.write(' %s.%s:\n' % (GroupMilestoneHistory.__name__, 'docs'))
count = 0
for m in tqdm(GroupMilestoneHistory.objects.all()):
for d in m.docs.all():
count += 1
GroupMilestoneHistoryDocs.objects.get_or_create(GroupMilestoneHistory=m, document_id=nameid[d.name])
sys.stderr.write(' %s GroupMilestoneHistoryDocs objects created\n' % (count, ))
def reverse(apps, schema_editor):
pass
class Migration(migrations.Migration):
dependencies = [
('group', '0013_add_groupmilestone_docs2_m2m'),
('doc', '0014_set_document_docalias_id'),
]
operations = [
migrations.RunPython(forward, reverse),
]

View file

@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-22 08:00
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('group', '0014_set_document_m2m_keys'),
]
# The implementation of AlterField in Django 1.11 applies
# 'ALTER TABLE <table> MODIFY <field> ...;' in order to fix foregn keys
# to the altered field, but as it seems does _not_ fix up m2m
# intermediary tables in an equivalent manner, so here we remove and
# then recreate the m2m tables so they will have the appropriate field
# types.
operations = [
migrations.RemoveField(
model_name='groupmilestone',
name='docs',
),
migrations.RemoveField(
model_name='groupmilestonehistory',
name='docs',
),
migrations.AddField(
model_name='groupmilestone',
name='docs',
field=models.ManyToManyField(to='doc.Document'),
),
migrations.AddField(
model_name='groupmilestonehistory',
name='docs',
field=models.ManyToManyField(to='doc.Document'),
),
]

View file

@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-22 08:00
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('group', '0015_1_del_docs_m2m_table'),
]
# The implementation of AlterField in Django 1.11 applies
# 'ALTER TABLE <table> MODIFY <field> ...;' in order to fix foregn keys
# to the altered field, but as it seems does _not_ fix up m2m
# intermediary tables in an equivalent manner, so here we remove and
# then recreate the m2m tables so they will have the appropriate field
# types.
operations = [
migrations.RemoveField(
model_name='groupmilestone',
name='docs',
),
migrations.RemoveField(
model_name='groupmilestonehistory',
name='docs',
),
migrations.AddField(
model_name='groupmilestone',
name='docs',
field=models.ManyToManyField(blank=True, to='doc.Document'),
),
migrations.AddField(
model_name='groupmilestonehistory',
name='docs',
field=models.ManyToManyField(blank=True, to='doc.Document'),
),
]

View file

@ -0,0 +1,57 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-27 05:57
from __future__ import unicode_literals
import sys, time
from tqdm import tqdm
from django.db import migrations
def forward(apps, schema_editor):
GroupMilestone = apps.get_model('group', 'GroupMilestone')
GroupMilestoneDocs = apps.get_model('group', 'GroupMilestoneDocs')
GroupMilestoneHistory = apps.get_model('group', 'GroupMilestoneHistory')
GroupMilestoneHistoryDocs = apps.get_model('group', 'GroupMilestoneHistoryDocs')
# Document id fixup ------------------------------------------------------------
sys.stderr.write('\n')
sys.stderr.write(' %s.%s:\n' % (GroupMilestone.__name__, 'docs'))
for m in tqdm(GroupMilestone.objects.all()):
m.docs.set([ d.document for d in GroupMilestoneDocs.objects.filter(groupmilestone=m) ])
sys.stderr.write(' %s.%s:\n' % (GroupMilestoneHistory.__name__, 'docs'))
for m in tqdm(GroupMilestoneHistory.objects.all()):
m.docs.set([ d.document for d in GroupMilestoneHistoryDocs.objects.filter(groupmilestonehistory=m) ])
def reverse(apps, schema_editor):
pass
def timestamp(apps, schema_editor):
sys.stderr.write('\n %s' % time.strftime('%Y-%m-%d %H:%M:%S'))
class Migration(migrations.Migration):
dependencies = [
('group', '0015_2_add_docs_m2m_table'),
]
operations = [
#migrations.RunPython(forward, reverse),
migrations.RunPython(timestamp, timestamp),
migrations.RunSQL(
"INSERT INTO group_groupmilestone_docs SELECT * FROM group_groupmilestonedocs;",
""
),
migrations.RunPython(timestamp, timestamp),
migrations.RunSQL(
"INSERT INTO group_groupmilestonehistory_docs SELECT * FROM group_groupmilestonehistorydocs;",
""
),
migrations.RunPython(timestamp, timestamp),
]

View file

@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-30 03:23
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('group', '0016_copy_docs_m2m_table'),
]
operations = [
migrations.RemoveField(
model_name='groupmilestonedocs',
name='document',
),
migrations.RemoveField(
model_name='groupmilestonedocs',
name='groupmilestone',
),
migrations.RemoveField(
model_name='groupmilestonehistorydocs',
name='document',
),
migrations.RemoveField(
model_name='groupmilestonehistorydocs',
name='groupmilestonehistory',
),
migrations.RemoveField(
model_name='groupmilestone',
name='docs2',
),
migrations.RemoveField(
model_name='groupmilestonehistory',
name='docs2',
),
migrations.DeleteModel(
name='GroupMilestoneDocs',
),
migrations.DeleteModel(
name='GroupMilestoneHistoryDocs',
),
]

View file

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-25 06:51
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('group', '0017_remove_docs2_m2m'),
]
operations = [
migrations.RemoveField(
model_name='group',
name='charter',
),
]

View file

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-25 06:52
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('doc', '0019_rename_field_document2'),
('group', '0018_remove_old_document_field'),
]
operations = [
migrations.RenameField(
model_name='group',
old_name='charter2',
new_name='charter',
),
]

View file

@ -237,7 +237,7 @@ class ReviewTests(TestCase):
content = """
{% autoescape off %}
Reviewer Deadline Draft
{% for r in review_assignments %}{{ r.reviewer.person.plain_name|ljust:"22" }} {{ r.review_request.deadline|date:"Y-m-d" }} {{ r.review_request.doc_id }}-{% if r.review_request.requested_rev %}{{ r.review_request.requested_rev }}{% else %}{{ r.review_request.doc.rev }}{% endif %}
{% for r in review_assignments %}{{ r.reviewer.person.plain_name|ljust:"22" }} {{ r.review_request.deadline|date:"Y-m-d" }} {{ r.review_request.doc.name }}-{% if r.review_request.requested_rev %}{{ r.review_request.requested_rev }}{% else %}{{ r.review_request.doc.rev }}{% endif %}
{% endfor %}
{% if rotation_list %}Next in the reviewer rotation:
@ -480,13 +480,13 @@ class ReviewTests(TestCase):
empty_outbox()
email_reviewer_reminder(review_req)
self.assertEqual(len(outbox), 1)
self.assertTrue(review_req.doc_id in outbox[0].get_payload(decode=True).decode("utf-8"))
self.assertTrue(review_req.doc.name in outbox[0].get_payload(decode=True).decode("utf-8"))
# email secretary
empty_outbox()
email_secretary_reminder(review_req, secretary_role)
self.assertEqual(len(outbox), 1)
self.assertTrue(review_req.doc_id in outbox[0].get_payload(decode=True).decode("utf-8"))
self.assertTrue(review_req.doc.name in outbox[0].get_payload(decode=True).decode("utf-8"))

View file

@ -1372,7 +1372,7 @@ def reviewer_overview(request, acronym, group_type=None):
latest_reqs = []
for d in req_data:
if d.state in ["assigned", "accepted"] or len(latest_reqs) < MAX_CLOSED_REQS + open_reqs:
latest_reqs.append((d.assignment_pk, d.doc, d.reviewed_rev, d.assigned_time, d.deadline,
latest_reqs.append((d.assignment_pk, d.doc_name, d.reviewed_rev, d.assigned_time, d.deadline,
assignment_state_by_slug.get(d.state),
int(math.ceil(d.assignment_to_closure_days)) if d.assignment_to_closure_days is not None else None))
if d.state in ["completed", "completed_in_time", "completed_late"]:
@ -1405,7 +1405,7 @@ def manage_review_requests(request, acronym, group_type=None, assignment_status=
document_requests = extract_revision_ordered_review_requests_for_documents_and_replaced(
ReviewRequest.objects.filter(state__in=("part-completed", "completed"), team=group).prefetch_related("result"),
set(r.doc_id for r in review_requests),
set(r.doc.name for r in review_requests),
)
# we need a mutable query dict for resetting upon saving with
@ -1417,7 +1417,7 @@ def manage_review_requests(request, acronym, group_type=None, assignment_status=
# add previous requests
l = []
for r in document_requests.get(req.doc_id, []):
for r in document_requests.get(req.doc.name, []):
# take all on the latest reviewed rev
if l and l[0].reviewed_rev:
if r.doc_id == l[0].doc_id and r.reviewed_rev:
@ -1703,7 +1703,7 @@ def change_reviewer_settings(request, acronym, reviewer_email, group_type=None):
msg += "{} is currently assigned to review:".format(reviewer_role.person)
for r in review_assignments:
msg += "\n\n"
msg += "{} (deadline: {})".format(r.review_request.doc_id, r.review_request.deadline.isoformat())
msg += "{} (deadline: {})".format(r.review_request.doc.name, r.review_request.deadline.isoformat())
else:
msg += "{} does not have any assignments currently.".format(reviewer_role.person)

View file

@ -22,17 +22,17 @@ def all_id_txt():
# this returns a lot of data so try to be efficient
# precalculations
revision_time = dict(NewRevisionDocEvent.objects.filter(type="new_revision", doc__name__startswith="draft-").order_by('time').values_list("doc_id", "time"))
revision_time = dict(NewRevisionDocEvent.objects.filter(type="new_revision", doc__name__startswith="draft-").order_by('time').values_list("doc__name", "time"))
def formatted_rev_date(name):
t = revision_time.get(name)
return t.strftime("%Y-%m-%d") if t else ""
rfc_aliases = dict(DocAlias.objects.filter(name__startswith="rfc",
document__states=State.objects.get(type="draft", slug="rfc")).values_list("document_id", "name"))
document__states=State.objects.get(type="draft", slug="rfc")).values_list("document__name", "name"))
replacements = dict(RelatedDocument.objects.filter(target__document__states=State.objects.get(type="draft", slug="repl"),
relationship="replaces").values_list("target__document_id", "source"))
relationship="replaces").values_list("target__name", "source__name"))
# we need a distinct to prevent the queries below from multiplying the result
@ -66,7 +66,7 @@ def all_id_txt():
# handle the rest
not_in_process = all_ids.exclude(pk__in=[d.name for d in in_iesg_process])
not_in_process = all_ids.exclude(pk__in=[d.pk for d in in_iesg_process])
for s in State.objects.filter(type="draft").order_by("order"):
for name, rev in not_in_process.filter(states=s).values_list("name", "rev"):
@ -110,21 +110,21 @@ def all_id2_txt():
drafts = drafts.prefetch_related("states")
rfc_aliases = dict(DocAlias.objects.filter(name__startswith="rfc",
document__states=State.objects.get(type="draft", slug="rfc")).values_list("document_id", "name"))
document__states=State.objects.get(type="draft", slug="rfc")).values_list("document__name", "name"))
replacements = dict(RelatedDocument.objects.filter(target__document__states=State.objects.get(type="draft", slug="repl"),
relationship="replaces").values_list("target__document_id", "source"))
relationship="replaces").values_list("target__name", "source__name"))
revision_time = dict(DocEvent.objects.filter(type="new_revision", doc__name__startswith="draft-").order_by('time').values_list("doc_id", "time"))
revision_time = dict(DocEvent.objects.filter(type="new_revision", doc__name__startswith="draft-").order_by('time').values_list("doc__name", "time"))
file_types = file_types_for_drafts()
authors = {}
for a in DocumentAuthor.objects.filter(document__name__startswith="draft-").order_by("order").select_related("email", "person").iterator():
if a.document_id not in authors:
l = authors[a.document_id] = []
if a.document.name not in authors:
l = authors[a.document.name] = []
else:
l = authors[a.document_id]
l = authors[a.document.name]
if a.email:
l.append(u'%s <%s>' % (a.person.plain_name().replace("@", ""), a.email.address.replace(",", "")))
else:
@ -239,8 +239,8 @@ def active_drafts_index_by_group(extra_values=()):
docs_dict[d.name]['group_id'] = individual.id
# add initial and latest revision time
for time, doc_id in NewRevisionDocEvent.objects.filter(type="new_revision", doc__states=active_state).order_by('-time').values_list("time", "doc_id"):
d = docs_dict.get(doc_id)
for time, doc_name in NewRevisionDocEvent.objects.filter(type="new_revision", doc__states=active_state).order_by('-time').values_list("time", "doc__name"):
d = docs_dict.get(doc_name)
if d:
if "rev_time" not in d:
d["rev_time"] = time
@ -248,7 +248,7 @@ def active_drafts_index_by_group(extra_values=()):
# add authors
for a in DocumentAuthor.objects.filter(document__states=active_state).order_by("order").select_related("person"):
d = docs_dict.get(a.document_id)
d = docs_dict.get(a.document.name)
if d:
if "authors" not in d:
d["authors"] = []

View file

@ -182,7 +182,7 @@ def fill_in_agenda_docs(date, sections, docs=None):
if e and (e.consensus != None):
doc.consensus = "Yes" if e.consensus else "No"
doc.review_assignments = review_assignments_for_docs.get(doc.pk, [])
doc.review_assignments = review_assignments_for_docs.get(doc.name, [])
elif doc.type_id == "conflrev":
doc.conflictdoc = doc.relateddocument_set.get(relationship__slug='conflrev').target.document
elif doc.type_id == "charter":

View file

@ -493,7 +493,7 @@ class RescheduleOnAgendaTests(TestCase):
e.returning_item = True
e.save()
form_id = draft.pk
form_id = draft.name
url = urlreverse('ietf.iesg.views.agenda_documents')

View file

@ -384,7 +384,7 @@ class IetfAuthTests(TestCase):
# wish to review
r = self.client.post(url, {
"action": "add_wish",
'doc': doc.pk,
'doc': doc.name,
"team": review_req.team_id,
})
self.assertEqual(r.status_code, 302)

View file

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-08 11:58
from __future__ import unicode_literals
from django.db import migrations
import django.db.models.deletion
import ietf.utils.models
class Migration(migrations.Migration):
dependencies = [
('doc', '0015_1_add_fk_to_document_id'),
('ipr', '0002_auto_20180225_1207'),
]
operations = [
migrations.AddField(
model_name='iprdocrel',
name='document2',
field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.DocAlias', to_field=b'id'),
),
migrations.AlterField(
model_name='iprdocrel',
name='document',
field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_ipr', to='doc.DocAlias', to_field=b'name'),
),
]

View file

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-20 09:53
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('ipr', '0003_add_ipdocrel_document2_fk'),
]
operations = [
migrations.RemoveField(
model_name='iprdocrel',
name='document',
),
]

View file

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-21 05:31
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('doc', '0019_rename_field_document2'),
('ipr', '0004_remove_iprdocrel_document'),
]
operations = [
migrations.RenameField(
model_name='iprdocrel',
old_name='document2',
new_name='document',
),
]

View file

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-06-10 03:42
from __future__ import unicode_literals
from django.db import migrations
import django.db.models.deletion
import ietf.utils.models
class Migration(migrations.Migration):
dependencies = [
('ipr', '0005_rename_field_document2'),
]
operations = [
migrations.AlterField(
model_name='iprdocrel',
name='document',
field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.DocAlias'),
),
]

View file

@ -260,9 +260,9 @@ class IprTests(TestCase):
"ietfer_contact_info": "555-555-0101",
"iprdocrel_set-TOTAL_FORMS": 2,
"iprdocrel_set-INITIAL_FORMS": 0,
"iprdocrel_set-0-document": "%s" % draft.docalias_set.first().pk,
"iprdocrel_set-0-document": "%s" % draft.docalias_set.first().name,
"iprdocrel_set-0-revisions": '00',
"iprdocrel_set-1-document": DocAlias.objects.filter(name__startswith="rfc").first().pk,
"iprdocrel_set-1-document": DocAlias.objects.filter(name__startswith="rfc").first().name,
"patent_number": "SE12345678901",
"patent_inventor": "A. Nonymous",
"patent_title": "A method of transfering bits",
@ -303,9 +303,9 @@ class IprTests(TestCase):
"ietfer_contact_info": "555-555-0101",
"iprdocrel_set-TOTAL_FORMS": 2,
"iprdocrel_set-INITIAL_FORMS": 0,
"iprdocrel_set-0-document": "%s" % draft.docalias_set.first().pk,
"iprdocrel_set-0-document": "%s" % draft.docalias_set.first().name,
"iprdocrel_set-0-revisions": '00',
"iprdocrel_set-1-document": DocAlias.objects.filter(name__startswith="rfc").first().pk,
"iprdocrel_set-1-document": DocAlias.objects.filter(name__startswith="rfc").first().name,
"patent_number": "SE12345678901",
"patent_inventor": "A. Nonymous",
"patent_title": "A method of transfering bits",
@ -351,7 +351,7 @@ class IprTests(TestCase):
"holder_legal_name": "Test Legal",
"ietfer_contact_info": "555-555-0101",
"ietfer_name": "Test Participant",
"iprdocrel_set-0-document": "%s" % draft.docalias_set.first().pk,
"iprdocrel_set-0-document": "%s" % draft.docalias_set.first().name,
"iprdocrel_set-0-revisions": '00',
"iprdocrel_set-INITIAL_FORMS": 0,
"iprdocrel_set-TOTAL_FORMS": 1,
@ -400,9 +400,9 @@ class IprTests(TestCase):
"ietfer_contact_info": "555-555-0101",
"iprdocrel_set-TOTAL_FORMS": 2,
"iprdocrel_set-INITIAL_FORMS": 0,
"iprdocrel_set-0-document": "%s" % draft.docalias_set.first().pk,
"iprdocrel_set-0-document": "%s" % draft.docalias_set.first().name,
"iprdocrel_set-0-revisions": '00',
"iprdocrel_set-1-document": DocAlias.objects.filter(name__startswith="rfc").first().pk,
"iprdocrel_set-1-document": DocAlias.objects.filter(name__startswith="rfc").first().name,
"patent_number": "SE12345678901",
"patent_inventor": "A. Nonymous",
"patent_title": "A method of transfering bits",
@ -438,7 +438,7 @@ class IprTests(TestCase):
"holder_contact_email": "test@holder.com",
"iprdocrel_set-TOTAL_FORMS": 1,
"iprdocrel_set-INITIAL_FORMS": 0,
"iprdocrel_set-0-document": "%s" % draft.docalias_set.first().pk,
"iprdocrel_set-0-document": "%s" % draft.docalias_set.first().name,
"iprdocrel_set-0-revisions": '00',
"patent_number": "SE12345678901",
"patent_inventor": "A. Nonymous",
@ -627,7 +627,7 @@ Subject: test
'iprdocrel_set-TOTAL_FORMS' : 1,
'iprdocrel_set-INITIAL_FORMS' : 1,
'iprdocrel_set-0-id': disclosure.pk,
"iprdocrel_set-0-document": disclosure.docs.first().pk,
"iprdocrel_set-0-document": disclosure.docs.first().name,
"iprdocrel_set-0-revisions": disclosure.docs.first().document.rev,
'holder_legal_name': disclosure.holder_legal_name,
'patent_number': patent_dict['Number'],

View file

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-08 11:58
from __future__ import unicode_literals
from django.db import migrations
import django.db.models.deletion
import ietf.utils.models
class Migration(migrations.Migration):
dependencies = [
('doc', '0015_1_add_fk_to_document_id'),
('liaisons', '0002_auto_20180225_1207'),
]
operations = [
migrations.AddField(
model_name='liaisonstatementattachment',
name='document2',
field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id'),
),
migrations.AlterField(
model_name='liaisonstatementattachment',
name='document',
field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_liaison', to='doc.Document', to_field=b'name'),
),
]

View file

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-20 09:53
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('liaisons', '0003_liaison_document2_fk'),
]
operations = [
migrations.RemoveField(
model_name='liaisonstatementattachment',
name='document',
),
]

View file

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-21 05:31
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('doc', '0019_rename_field_document2'),
('liaisons', '0004_remove_liaisonstatementattachment_document'),
]
operations = [
migrations.RenameField(
model_name='liaisonstatementattachment',
old_name='document2',
new_name='document',
),
]

View file

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-06-10 03:47
from __future__ import unicode_literals
from django.db import migrations
import django.db.models.deletion
import ietf.utils.models
class Migration(migrations.Migration):
dependencies = [
('liaisons', '0005_rename_field_document2'),
]
operations = [
migrations.AlterField(
model_name='liaisonstatementattachment',
name='document',
field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document'),
),
]

View file

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-08 11:58
from __future__ import unicode_literals
from django.db import migrations
import django.db.models.deletion
import ietf.utils.models
class Migration(migrations.Migration):
dependencies = [
('doc', '0015_1_add_fk_to_document_id'),
('meeting', '0014_auto_20190426_0305'),
]
operations = [
migrations.AddField(
model_name='sessionpresentation',
name='document2',
field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id'),
),
migrations.AlterField(
model_name='sessionpresentation',
name='document',
field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_sesspres', to='doc.Document', to_field=b'name'),
),
]

View file

@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-21 03:57
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('doc', '0018_remove_old_document_field'),
('meeting', '0015_sessionpresentation_document2_fk'),
]
operations = [
# We need to get rid of the current through table uniqueness
# constraint before we can remove the document column: The table
# has "UNIQUE KEY `session_id` (`session_id`,`document_id`)"
migrations.RunSQL(
"ALTER TABLE `meeting_session_materials` DROP INDEX `session_id`;",
"CREATE UNIQUE INDEX `session_id` ON `meeting_session_materials` (`session_id`, `document_id`);"
),
## This doesn't work:
# migrations.RemoveIndex(
# model_name='sessionpresentation',
# name='session_id'
# ),
migrations.RemoveField(
model_name='sessionpresentation',
name='document',
),
]

View file

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-21 05:31
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('doc', '0019_rename_field_document2'),
('meeting', '0016_remove_sessionpresentation_document'),
]
operations = [
migrations.RenameField(
model_name='sessionpresentation',
old_name='document2',
new_name='document',
),
migrations.AlterUniqueTogether(
name='sessionpresentation',
unique_together=set([('session', 'document')]),
),
]

View file

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-06-10 03:47
from __future__ import unicode_literals
from django.db import migrations
import django.db.models.deletion
import ietf.utils.models
class Migration(migrations.Migration):
dependencies = [
('meeting', '0017_rename_field_document2'),
]
operations = [
migrations.AlterField(
model_name='sessionpresentation',
name='document',
field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document'),
),
]

View file

@ -863,6 +863,7 @@ class SessionPresentation(models.Model):
class Meta:
db_table = 'meeting_session_materials'
ordering = ('order',)
unique_together = (('session', 'document'),)
def __unicode__(self):
return u"%s -> %s-%s" % (self.session, self.document.name, self.rev)

View file

@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-21 14:23
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
import ietf.utils.models
class Migration(migrations.Migration):
dependencies = [
('message', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='MessageDocs',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('message', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='message.Message')),
('document', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id')),
],
),
migrations.AddField(
model_name='message',
name='related_docs2',
field=models.ManyToManyField(blank=True, related_name='messages', through='message.MessageDocs', to='doc.Document'),
),
]

View file

@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-21 14:27
from __future__ import unicode_literals
import sys
from tqdm import tqdm
from django.db import migrations
def forward(apps, schema_editor):
Document = apps.get_model('doc','Document')
Message = apps.get_model('message', 'Message')
MessageDocs = apps.get_model('message', 'MessageDocs')
# Document id fixup ------------------------------------------------------------
objs = Document.objects.in_bulk()
nameid = { o.name: o.id for id, o in objs.iteritems() }
sys.stderr.write('\n')
sys.stderr.write(' %s.%s:\n' % (Message.__name__, 'related_docs'))
count = 0
for m in tqdm(Message.objects.all()):
for d in m.related_docs.all():
count += 1;
MessageDocs.objects.get_or_create(message=m, document_id=nameid[d.name])
sys.stderr.write(' %s MessageDocs objects created\n' % (count, ))
def reverse(apps, schema_editor):
pass
class Migration(migrations.Migration):
dependencies = [
('message', '0002_add_message_docs2_m2m'),
('doc', '0014_set_document_docalias_id'),
]
operations = [
migrations.RunPython(forward, reverse),
]

View file

@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-22 08:01
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('message', '0003_set_document_m2m_keys'),
]
# The implementation of AlterField in Django 1.11 applies
# 'ALTER TABLE <table> MODIFY <field> ...;' in order to fix foregn keys
# to the altered field, but as it seems does _not_ fix up m2m
# intermediary tables in an equivalent manner, so here we remove and
# then recreate the m2m tables so they will have the appropriate field
# types.
operations = [
migrations.RemoveField(
model_name='message',
name='related_docs',
),
migrations.AddField(
model_name='message',
name='related_docs',
field=models.ManyToManyField(to='doc.Document'),
),
]

View file

@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-22 08:01
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('message', '0004_1_del_docs_m2m_table'),
]
# The implementation of AlterField in Django 1.11 applies
# 'ALTER TABLE <table> MODIFY <field> ...;' in order to fix foregn keys
# to the altered field, but as it seems does _not_ fix up m2m
# intermediary tables in an equivalent manner, so here we remove and
# then recreate the m2m tables so they will have the appropriate field
# types.
operations = [
migrations.RemoveField(
model_name='message',
name='related_docs',
),
migrations.AddField(
model_name='message',
name='related_docs',
field=models.ManyToManyField(blank=True, to='doc.Document'),
),
]

View file

@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-27 05:56
from __future__ import unicode_literals
import sys, time
from django.db import migrations
def timestamp(apps, schema_editor):
sys.stderr.write('\n %s' % time.strftime('%Y-%m-%d %H:%M:%S'))
class Migration(migrations.Migration):
dependencies = [
('message', '0004_2_add_docs_m2m_table'),
]
operations = [
#migrations.RunPython(forward, reverse),
migrations.RunPython(timestamp, timestamp),
migrations.RunSQL(
"INSERT INTO message_message_related_docs SELECT * FROM message_messagedocs;",
""
),
migrations.RunPython(timestamp, timestamp),
]

View file

@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-30 03:32
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('message', '0005_copy_docs_m2m_table'),
]
operations = [
migrations.RemoveField(
model_name='messagedocs',
name='document',
),
migrations.RemoveField(
model_name='messagedocs',
name='message',
),
migrations.RemoveField(
model_name='message',
name='related_docs2',
),
migrations.DeleteModel(
name='MessageDocs',
),
]

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,58 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-08 11:58
from __future__ import unicode_literals
from django.db import migrations
import django.db.models.deletion
import ietf.utils.models
class Migration(migrations.Migration):
dependencies = [
('doc', '0015_1_add_fk_to_document_id'),
('review', '0010_populate_review_assignments'),
]
operations = [
migrations.AddField(
model_name='reviewrequest',
name='doc2',
field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='reviewrequest_set', to='doc.Document', to_field=b'id'),
),
migrations.AddField(
model_name='reviewwish',
name='doc2',
field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id'),
),
migrations.AddField(
model_name='reviewrequest',
name='unused_review2',
field=ietf.utils.models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field='id'),
),
migrations.AddField(
model_name='reviewassignment',
name='review2',
field=ietf.utils.models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field='id'),
),
migrations.AlterField(
model_name='reviewrequest',
name='doc',
field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_revreq', to='doc.Document', to_field=b'name'),
),
migrations.AlterField(
model_name='reviewwish',
name='doc',
field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_revwish', to='doc.Document', to_field=b'name'),
),
migrations.AlterField(
model_name='reviewrequest',
name='unused_review',
field=ietf.utils.models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='old_unused_review', to='doc.Document', to_field=b'name'),
),
migrations.AlterField(
model_name='reviewassignment',
name='review',
field=ietf.utils.models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='old_reviewassignment', to='doc.Document', to_field=b'name'),
),
]

View file

@ -0,0 +1,47 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-20 09:53
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('review', '0011_review_document2_fk'),
]
operations = [
migrations.RemoveField(
model_name='reviewrequest',
name='doc',
),
migrations.RemoveField(
model_name='reviewrequest',
name='unused_reviewer',
),
migrations.RemoveField(
model_name='reviewrequest',
name='unused_review',
),
migrations.RemoveField(
model_name='reviewrequest',
name='unused_review2',
),
migrations.RemoveField(
model_name='reviewrequest',
name='unused_reviewed_rev',
),
migrations.RemoveField(
model_name='reviewrequest',
name='unused_result',
),
migrations.RemoveField(
model_name='reviewwish',
name='doc',
),
migrations.RemoveField(
model_name='reviewassignment',
name='review',
),
]

View file

@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-21 05:31
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('doc', '0019_rename_field_document2'),
('review', '0012_remove_old_document_field'),
]
operations = [
migrations.RenameField(
model_name='reviewrequest',
old_name='doc2',
new_name='doc',
),
migrations.RenameField(
model_name='reviewwish',
old_name='doc2',
new_name='doc',
),
migrations.RenameField(
model_name='reviewassignment',
old_name='review2',
new_name='review',
),
]

View file

@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-06-10 03:47
from __future__ import unicode_literals
from django.db import migrations
import django.db.models.deletion
import ietf.utils.models
class Migration(migrations.Migration):
dependencies = [
('review', '0013_rename_field_document2'),
]
operations = [
migrations.AlterField(
model_name='reviewrequest',
name='doc',
field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reviewrequest_set', to='doc.Document'),
),
migrations.AlterField(
model_name='reviewwish',
name='doc',
field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document'),
),
]

View file

@ -119,14 +119,6 @@ class ReviewRequest(models.Model):
requested_rev = models.CharField(verbose_name="requested revision", max_length=16, blank=True, help_text="Fill in if a specific revision is to be reviewed, e.g. 02")
comment = models.TextField(verbose_name="Requester's comments and instructions", max_length=2048, blank=True, help_text="Provide any additional information to show to the review team secretary and reviewer", default='')
# Moved to class ReviewAssignment:
# These exist only to facilitate data migrations. They will be removed in the next release.
unused_reviewer = ForeignKey(Email, blank=True, null=True)
unused_review = OneToOneField(Document, blank=True, null=True)
unused_reviewed_rev = models.CharField(verbose_name="reviewed revision", max_length=16, blank=True)
unused_result = ForeignKey(ReviewResultName, blank=True, null=True)
def __unicode__(self):
return u"%s review on %s by %s %s" % (self.type, self.doc, self.team, self.state)

View file

@ -167,7 +167,7 @@ def days_needed_to_fulfill_min_interval_for_reviewers(team):
return res
ReviewAssignmentData = namedtuple("ReviewAssignmentData", [
"assignment_pk", "doc", "doc_pages", "req_time", "state", "assigned_time", "deadline", "reviewed_rev", "result", "team", "reviewer",
"assignment_pk", "doc_name", "doc_pages", "req_time", "state", "assigned_time", "deadline", "reviewed_rev", "result", "team", "reviewer",
"late_days",
"request_to_assignment_days", "assignment_to_closure_days", "request_to_closure_days"])
@ -194,7 +194,7 @@ def extract_review_assignment_data(teams=None, reviewers=None, time_from=None, t
event_qs = ReviewAssignment.objects.filter(filters)
event_qs = event_qs.values_list(
"pk", "review_request__doc", "review_request__doc__pages", "review_request__time", "state", "review_request__deadline", "reviewed_rev", "result", "review_request__team",
"pk", "review_request__doc__name", "review_request__doc__pages", "review_request__time", "state", "review_request__deadline", "reviewed_rev", "result", "review_request__team",
"reviewer__person", "assigned_on", "completed_on"
)
@ -215,7 +215,7 @@ def extract_review_assignment_data(teams=None, reviewers=None, time_from=None, t
for assignment in event_qs:
assignment_pk, doc, doc_pages, req_time, state, deadline, reviewed_rev, result, team, reviewer, assigned_on, completed_on = assignment
assignment_pk, doc_name, doc_pages, req_time, state, deadline, reviewed_rev, result, team, reviewer, assigned_on, completed_on = assignment
requested_time = req_time
assigned_time = assigned_on
@ -226,7 +226,7 @@ def extract_review_assignment_data(teams=None, reviewers=None, time_from=None, t
assignment_to_closure_days = positive_days(assigned_time, closed_time)
request_to_closure_days = positive_days(requested_time, closed_time)
d = ReviewAssignmentData(assignment_pk, doc, doc_pages, req_time, state, assigned_time, deadline, reviewed_rev, result, team, reviewer,
d = ReviewAssignmentData(assignment_pk, doc_name, doc_pages, req_time, state, assigned_time, deadline, reviewed_rev, result, team, reviewer,
late_days, request_to_assignment_days, assignment_to_closure_days,
request_to_closure_days)
@ -659,7 +659,7 @@ def suggested_review_requests_for_team(team):
# cancelled/moved
telechat_events = TelechatDocEvent.objects.filter(
# turn into list so we don't get a complex and slow join sent down to the DB
doc__in=list(telechat_docs.values_list("pk", flat=True)),
doc__id__in=list(telechat_docs.values_list("pk", flat=True)),
).values_list(
"doc", "pk", "time", "telechat_date"
).order_by("doc", "-time", "-id").distinct()
@ -688,7 +688,7 @@ def suggested_review_requests_for_team(team):
# filter those with existing explicit requests
existing_requests = defaultdict(list)
for r in ReviewRequest.objects.filter(doc__in=requests.iterkeys(), team=team):
for r in ReviewRequest.objects.filter(doc__id__in=requests.iterkeys(), team=team):
existing_requests[r.doc_id].append(r)
def blocks(existing, request):
@ -719,8 +719,10 @@ def extract_revision_ordered_review_assignments_for_documents_and_replaced(revie
replaces = extract_complete_replaces_ancestor_mapping_for_docs(names)
assignments_for_each_doc = defaultdict(list)
for r in review_assignment_queryset.filter(review_request__doc__in=set(e for l in replaces.itervalues() for e in l) | names).order_by("-reviewed_rev","-assigned_on", "-id").iterator():
assignments_for_each_doc[r.review_request.doc_id].append(r)
replacement_name_set = set(e for l in replaces.itervalues() for e in l) | names
for r in ( review_assignment_queryset.filter(review_request__doc__name__in=replacement_name_set)
.order_by("-reviewed_rev","-assigned_on", "-id").iterator()):
assignments_for_each_doc[r.review_request.doc.name].append(r)
# now collect in breadth-first order to keep the revision order intact
res = defaultdict(list)
@ -765,8 +767,8 @@ def extract_revision_ordered_review_requests_for_documents_and_replaced(review_r
replaces = extract_complete_replaces_ancestor_mapping_for_docs(names)
requests_for_each_doc = defaultdict(list)
for r in review_request_queryset.filter(doc__in=set(e for l in replaces.itervalues() for e in l) | names).order_by("-time", "-id").iterator():
requests_for_each_doc[r.doc_id].append(r)
for r in review_request_queryset.filter(doc__name__in=set(e for l in replaces.itervalues() for e in l) | names).order_by("-time", "-id").iterator():
requests_for_each_doc[r.doc.name].append(r)
# now collect in breadth-first order to keep the revision order intact
res = defaultdict(list)
@ -990,12 +992,12 @@ def email_reviewer_reminder(review_request):
deadline_days = (review_request.deadline - datetime.date.today()).days
subject = "Reminder: deadline for review of {} in {} is {}".format(review_request.doc_id, team.acronym, review_request.deadline.isoformat())
subject = "Reminder: deadline for review of {} in {} is {}".format(review_request.doc.name, team.acronym, review_request.deadline.isoformat())
import ietf.ietfauth.views
overview_url = urlreverse(ietf.ietfauth.views.review_overview)
import ietf.doc.views_review
request_url = urlreverse(ietf.doc.views_review.review_request, kwargs={ "name": review_request.doc_id, "request_id": review_request.pk })
request_url = urlreverse(ietf.doc.views_review.review_request, kwargs={ "name": review_request.doc.name, "request_id": review_request.pk })
domain = Site.objects.get_current().domain
@ -1034,12 +1036,12 @@ def email_secretary_reminder(review_request, secretary_role):
deadline_days = (review_request.deadline - datetime.date.today()).days
subject = "Reminder: deadline for review of {} in {} is {}".format(review_request.doc_id, team.acronym, review_request.deadline.isoformat())
subject = "Reminder: deadline for review of {} in {} is {}".format(review_request.doc.name, team.acronym, review_request.deadline.isoformat())
import ietf.group.views
settings_url = urlreverse(ietf.group.views.change_review_secretary_settings, kwargs={ "acronym": team.acronym, "group_type": team.type_id })
import ietf.doc.views_review
request_url = urlreverse(ietf.doc.views_review.review_request, kwargs={ "name": review_request.doc_id, "request_id": review_request.pk })
request_url = urlreverse(ietf.doc.views_review.review_request, kwargs={ "name": review_request.doc.name, "request_id": review_request.pk })
domain = Site.objects.get_current().domain

View file

@ -207,10 +207,10 @@ def get_progress_stats(sdate,edate):
new_draft_events = events.filter(newrevisiondocevent__rev='00')
new_drafts = list(set([ e.doc_id for e in new_draft_events ]))
data['new_drafts_count'] = len(new_drafts)
data['new_drafts_updated_count'] = events.filter(doc__in=new_drafts,newrevisiondocevent__rev='01').count()
data['new_drafts_updated_more_count'] = events.filter(doc__in=new_drafts,newrevisiondocevent__rev='02').count()
data['new_drafts_updated_count'] = events.filter(doc__id__in=new_drafts,newrevisiondocevent__rev='01').count()
data['new_drafts_updated_more_count'] = events.filter(doc__id__in=new_drafts,newrevisiondocevent__rev='02').count()
update_events = events.filter(type='new_revision').exclude(doc__in=new_drafts)
update_events = events.filter(type='new_revision').exclude(doc__id__in=new_drafts)
data['updated_drafts_count'] = len(set([ e.doc_id for e in update_events ]))
# Calculate Final Four Weeks stats (ffw)
@ -224,7 +224,7 @@ def get_progress_stats(sdate,edate):
data['ffw_new_count'] = ffw_new_count
data['ffw_new_percent'] = ffw_new_percent
ffw_update_events = events.filter(time__gte=ffwdate,type='new_revision').exclude(doc__in=new_drafts)
ffw_update_events = events.filter(time__gte=ffwdate,type='new_revision').exclude(doc__id__in=new_drafts)
ffw_update_count = len(set([ e.doc_id for e in ffw_update_events ]))
try:
ffw_update_percent = format(ffw_update_count / float(data['updated_drafts_count']),'.0%')

View file

@ -21,6 +21,7 @@ warnings.filterwarnings("ignore", message="Deprecated allow_tags attribute used
warnings.filterwarnings("ignore", message="You passed a bytestring as `filenames`. This will not work on Python 3.")
warnings.filterwarnings("ignore", message="django.forms.extras is deprecated.", module="bootstrap3")
warnings.filterwarnings("ignore", message="defusedxml.lxml is no longer supported and will be removed in a future release.", module="tastypie")
warnings.filterwarnings("ignore", message="Duplicate index '.*' defined on the table")
try:

View file

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-08 11:58
from __future__ import unicode_literals
from django.db import migrations
import django.db.models.deletion
import ietf.utils.models
class Migration(migrations.Migration):
dependencies = [
('doc', '0015_1_add_fk_to_document_id'),
('submit', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='submission',
name='draft2',
field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id'),
),
migrations.AlterField(
model_name='submission',
name='draft',
field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='old_submission', to='doc.Document', to_field=b'name'),
),
]

View file

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-25 06:44
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('submit', '0002_submission_document2_fk'),
]
operations = [
migrations.RemoveField(
model_name='submission',
name='draft',
),
]

View file

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-25 06:46
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('doc', '0019_rename_field_document2'),
('submit', '0003_remove_old_document_field'),
]
operations = [
migrations.RenameField(
model_name='submission',
old_name='draft2',
new_name='draft',
),
]

View file

@ -181,7 +181,7 @@ class SubmitTests(TestCase):
if r.status_code == 302:
submission = Submission.objects.get(name=name)
self.assertEqual(submission.submitter, email.utils.formataddr((submitter_name, submitter_email)))
self.assertEqual(submission.replaces, ",".join(d.name for d in DocAlias.objects.filter(pk__in=replaces.split(",") if replaces else [])))
self.assertEqual(submission.replaces, ",".join(d.name for d in DocAlias.objects.filter(name__in=replaces.split(",") if replaces else [])))
return r
@ -237,7 +237,7 @@ class SubmitTests(TestCase):
mailbox_before = len(outbox)
replaced_alias = draft.docalias_set.first()
r = self.supply_extra_metadata(name, status_url, author.ascii, author.email().address.lower(),
replaces=str(replaced_alias.pk) + "," + str(sug_replaced_alias.pk))
replaces=str(replaced_alias.name) + "," + str(sug_replaced_alias.name))
self.assertEqual(r.status_code, 302)
status_url = r["Location"]
@ -594,16 +594,16 @@ class SubmitTests(TestCase):
status_url, author = self.do_submission(name,rev)
mailbox_before = len(outbox)
replaced_alias = draft.docalias_set.first()
r = self.supply_extra_metadata(name, status_url, "Submitter Name", "author@example.com", replaces=str(replaced_alias.pk))
r = self.supply_extra_metadata(name, status_url, "Submitter Name", "author@example.com", replaces=str(replaced_alias.name))
self.assertEqual(r.status_code, 200)
self.assertTrue('cannot replace itself' in unicontent(r))
replaced_alias = DocAlias.objects.get(name='draft-ietf-random-thing')
r = self.supply_extra_metadata(name, status_url, "Submitter Name", "author@example.com", replaces=str(replaced_alias.pk))
r = self.supply_extra_metadata(name, status_url, "Submitter Name", "author@example.com", replaces=str(replaced_alias.name))
self.assertEqual(r.status_code, 200)
self.assertTrue('cannot replace an RFC' in unicontent(r))
replaced_alias.document.set_state(State.objects.get(type='draft-iesg',slug='approved'))
replaced_alias.document.set_state(State.objects.get(type='draft',slug='active'))
r = self.supply_extra_metadata(name, status_url, "Submitter Name", "author@example.com", replaces=str(replaced_alias.pk))
r = self.supply_extra_metadata(name, status_url, "Submitter Name", "author@example.com", replaces=str(replaced_alias.name))
self.assertEqual(r.status_code, 200)
self.assertTrue('approved by the IESG and cannot' in unicontent(r))
r = self.supply_extra_metadata(name, status_url, "Submitter Name", "author@example.com", replaces='')
@ -737,7 +737,7 @@ class SubmitTests(TestCase):
"edit-pages": "123",
"submitter-name": "Some Random Test Person",
"submitter-email": "random@example.com",
"replaces": str(draft.docalias_set.all().first().pk),
"replaces": str(draft.docalias_set.all().first().name),
"edit-note": "no comments",
"authors-0-name": "Person 1",
"authors-0-email": "person1@example.com",

View file

@ -478,7 +478,7 @@ class RFCEditorUndoTests(TestCase):
# get
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
self.assertTrue(e2.doc_id in unicontent(r))
self.assertTrue(e2.doc.name in unicontent(r))
# delete e2
deleted_before = DeletedEvent.objects.count()

View file

@ -4,7 +4,7 @@ Hello,
This is a notification from the {{ clist.long_name }}.
Document: {{ event.doc }},
https://datatracker.ietf.org/doc/{{ event.doc_id }}/
https://datatracker.ietf.org/doc/{{ event.doc.name }}/
Change by {{ event.by }} on {{ event.time }}:

View file

@ -44,7 +44,7 @@
<td class="edit"></td>
<td>
{% for review_assignment in other_reviews %}
{% include "doc/review_assignment_summary.html" with current_doc_name=review_assignemnt.review_request.doc_id current_rev=review_assignment.reviewed_rev %}
{% include "doc/review_assignment_summary.html" with current_doc_name=review_assignemnt.review_request.doc.name current_rev=review_assignment.reviewed_rev %}
{% endfor %}
</td>
</tr>

View file

@ -1,12 +1,12 @@
<div class="review-assignment-summary">
{% if review_assignment.state_id == "completed" or review_assignment.state_id == "part-completed" %}
<a href="{% if review_assignment.review %}{% url "ietf.doc.views_doc.document_main" review_assignment.review.name %}{% else %}{% url "ietf.doc.views_review.review_request" review_assignment.review_request.doc_id review_assignment.review_request.pk %}{% endif %}">
{{ review_assignment.review_request.team.acronym|upper }} {{ review_assignment.review_request.type.name }} Review{% if review_assignment.reviewed_rev and review_assignment.reviewed_rev != current_rev or review_assignment.review_request.doc_id != current_doc_name %} (of {% if review_assignment.review_request.doc_id != current_doc_name %}{{ review_assignment.review_request.doc_id }}{% endif %}-{{ review_assignment.reviewed_rev }}){% endif %}{% if review_assignment.result %}:
<a href="{% if review_assignment.review %}{% url "ietf.doc.views_doc.document_main" review_assignment.review.name %}{% else %}{% url "ietf.doc.views_review.review_request" review_assignment.review_request.doc.name review_assignment.review_request.pk %}{% endif %}">
{{ review_assignment.review_request.team.acronym|upper }} {{ review_assignment.review_request.type.name }} Review{% if review_assignment.reviewed_rev and review_assignment.reviewed_rev != current_rev or review_assignment.review_request.doc.name != current_doc_name %} (of {% if review_assignment.review_request.doc.name != current_doc_name %}{{ review_assignment.review_request.doc.name }}{% endif %}-{{ review_assignment.reviewed_rev }}){% endif %}{% if review_assignment.result %}:
{{ review_assignment.result.name }}{% endif %} {% if review_assignment.state_id == "part-completed" %}(partially completed){% endif %}
</a>
{% else %}
<i>
<a href="{% url "ietf.doc.views_review.review_request" review_assignment.review_request.doc_id review_assignment.review_request.pk %}">{{ review_assignment.review_request.team.acronym|upper }} {{ review_assignment.review_request.type.name }} Review
<a href="{% url "ietf.doc.views_review.review_request" review_assignment.review_request.doc.name review_assignment.review_request.pk %}">{{ review_assignment.review_request.team.acronym|upper }} {{ review_assignment.review_request.type.name }} Review
- due: {{ review_assignment.review_request.deadline|date:"Y-m-d" }}</a></i>
{% endif %}
</div>

View file

@ -61,13 +61,13 @@
{% for rlatest in r.latest_reqs %}
<div>
{% if rlatest.reviewed_rev %}
Previous review of <a href="{% url "ietf.doc.views_doc.document_main" name=rlatest.doc_id rev=rlatest.reviewed_rev %}?include_text=1">{% if rlatest.doc_id != r.doc_id %}{{ rlatest.doc_id }}{% endif %}-{{ rlatest.reviewed_rev }}</a>
Previous review of <a href="{% url "ietf.doc.views_doc.document_main" name=rlatest.doc.name rev=rlatest.reviewed_rev %}?include_text=1">{% if rlatest.doc_id != r.doc_id %}{{ rlatest.doc.name }}{% endif %}-{{ rlatest.reviewed_rev }}</a>
(<a href="{{ rfcdiff_base_url }}?url1={{ rlatest.doc.name }}-{{ rlatest.reviewed_rev }}&url2={{ r.doc.name }}-{{ r.doc.rev }}">diff</a>):
<a href="{{ rlatest.review.get_absolute_url }}">{% if rlatest.result %}{{ rlatest.result.name }}{% else %}result unavail.{% endif %}</a>
by {{ rlatest.reviewer.person }}{% if rlatest.closed_review_request_event %} {{ rlatest.closed_review_request_event.time.date|date }}{% endif %}
{% else %}
Previous review of <a href="{% url "ietf.doc.views_doc.document_main" name=rlatest.doc_id %}?include_text=1">{% if rlatest.doc_id != r.doc_id %}{{ rlatest.doc_id }}{% else %}this document{% endif %}</a>:
<a href="{% url "ietf.doc.views_review.review_request" name=rlatest.doc_id request_id=rlatest.pk %}">{% if rlatest.result %}{{ rlatest.result.name }}{% else %}result unavail.{% endif %}</a>
Previous review of <a href="{% url "ietf.doc.views_doc.document_main" name=rlatest.doc.name %}?include_text=1">{% if rlatest.doc_id != r.doc_id %}{{ rlatest.doc.name }}{% else %}this document{% endif %}</a>:
<a href="{% url "ietf.doc.views_review.review_request" name=rlatest.doc.name request_id=rlatest.pk %}">{% if rlatest.result %}{{ rlatest.result.name }}{% else %}result unavail.{% endif %}</a>
by {{ rlatest.reviewer.person }}{% if rlatest.closed_review_request_event %} {{ rlatest.closed_review_request_event.time.date|date }}{% endif %}
{% endif %}
</div>

View file

@ -6,6 +6,6 @@
IANA Review: {{ doc.iana_review_state }}{% endif %}{% if doc.consensus %}
Consensus: {{ doc.consensus }}{% endif %}{% if doc.lastcall_expires %}
Last call expires: {{ doc.lastcall_expires|date:"Y-m-d" }}{% endif %}{% if doc.review_assignments %}
Reviews: {% for assignment in doc.review_assignments %}{% with current_doc_name=doc.name current_rev=doc.rev %}{% if not forloop.first %} {% endif %}{{ assignment.review_request.team.acronym|upper }} {{ assignment.review_request.type.name }} Review{% if assignment.state_id == "completed" or assignment.state_id == "part-completed" %}{% if assignment.reviewed_rev and assignment.reviewed_rev != current_rev or assignment.review_request.doc_id != current_doc_name %} (of {% if assignment.review_request.doc_id != current_doc_name %}{{ assignment.review_request.doc_id }}{% endif %}-{{ assignment.reviewed_rev }}){% endif %}{% if assignment.result %}: {{ assignment.result.name }}{% endif %} {% if assignment.state_id == "part-completed" %}(partially completed){% endif %}{% else %} - due: {{ assignment.review_request.deadline|date:"Y-m-d" }}{% endif %}{% endwith %}
Reviews: {% for assignment in doc.review_assignments %}{% with current_doc_name=doc.name current_rev=doc.rev %}{% if not forloop.first %} {% endif %}{{ assignment.review_request.team.acronym|upper }} {{ assignment.review_request.type.name }} Review{% if assignment.state_id == "completed" or assignment.state_id == "part-completed" %}{% if assignment.reviewed_rev and assignment.reviewed_rev != current_rev or assignment.review_request.doc.name != current_doc_name %} (of {% if assignment.review_request.doc.name != current_doc_name %}{{ assignment.review_request.doc.name }}{% endif %}-{{ assignment.reviewed_rev }}){% endif %}{% if assignment.result %}: {{ assignment.result.name }}{% endif %} {% if assignment.state_id == "part-completed" %}(partially completed){% endif %}{% else %} - due: {{ assignment.review_request.deadline|date:"Y-m-d" }}{% endif %}{% endwith %}
{% endfor %}{% endif %}
{% with doc.active_defer_event as defer %}{% if defer %} Was deferred by {{defer.by}} on {{defer.time|date:"Y-m-d"}}{% endif %}{% endwith %}

View file

@ -95,7 +95,7 @@
<table class="table">
{% for w in review_wishes %}
<tr>
<td><a href="{% url "ietf.doc.views_doc.document_main" w.doc_id %}">{{ w.doc_id }}</a></td>
<td><a href="{% url "ietf.doc.views_doc.document_main" w.doc.name %}">{{ w.doc_id }}</a></td>
<td>{{ w.team.acronym }}</td>
<td>
<form method="post">

View file

@ -1,4 +1,4 @@
{% load ietf_filters %}{% autoescape off %}{% filter wordwrap:78 %}This is just a friendly reminder that the deadline for the review of {{ review_request.doc_id }} is in {{ deadline_days }} day{{ deadline_days|pluralize }}:
{% load ietf_filters %}{% autoescape off %}{% filter wordwrap:78 %}This is just a friendly reminder that the deadline for the review of {{ review_request.doc.name }} is in {{ deadline_days }} day{{ deadline_days|pluralize }}:
{{ review_request_url }}

View file

@ -1,4 +1,4 @@
{% load ietf_filters %}{% autoescape off %}{% filter wordwrap:78 %}This is just a friendly reminder that the deadline for the review of {{ review_request.doc_id }} is in {{ deadline_days }} day{{ deadline_days|pluralize }}:
{% load ietf_filters %}{% autoescape off %}{% filter wordwrap:78 %}This is just a friendly reminder that the deadline for the review of {{ review_request.doc.name }} is in {{ deadline_days }} day{{ deadline_days|pluralize }}:
{{ review_request_url }}

View file

@ -22,7 +22,7 @@
{% for e in events %}
<tr>
<td>{{ e.time|date:"Y-m-d H:i:s"}}</td>
<td><a href="{% url 'ietf.doc.views_doc.document_history' e.doc_id %}">{{ e.doc_id }}</a></td>
<td><a href="{% url 'ietf.doc.views_doc.document_history' e.doc.name %}">{{ e.doc.name }}</a></td>
<td>{{ e.desc|safe }}</td>
<td>
<form method="post">

View file

@ -1,3 +1,8 @@
# Copyright The IETF Trust 2011-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import debug # pyflakes:ignore
def find_history_active_at(obj, time):
"""Assumes obj has a corresponding history model (e.g. obj could
be Document with a corresponding DocHistory model), then either

View file

@ -64,6 +64,7 @@ from django.template import TemplateDoesNotExist
from django.template.loaders.base import Loader as BaseLoader
from django.test.runner import DiscoverRunner
from django.core.management import call_command
from django.urls import RegexURLResolver
import debug # pyflakes:ignore
@ -72,7 +73,9 @@ debug.debug = True
import ietf
import ietf.utils.mail
from ietf.checks import maybe_create_svn_symlinks
from ietf.utils.management.commands import pyflakes
from ietf.utils.test_smtpserver import SMTPTestServerDriver
from ietf.utils.test_utils import TestCase
loaded_templates = set()
@ -121,6 +124,19 @@ def safe_destroy_test_db(*args, **kwargs):
settings.DATABASES["default"]["NAME"] = test_database_name
return old_destroy(*args, **kwargs)
class PyFlakesTestCase(TestCase):
def __init__(self, test_runner=None, **kwargs):
self.runner = test_runner
super(PyFlakesTestCase, self).__init__(**kwargs)
def pyflakes_test(self):
self.maxDiff = None
path = os.path.join(settings.BASE_DIR)
warnings = []
warnings = pyflakes.checkPaths([path], verbosity=0)
self.assertEqual([], [str(w) for w in warnings])
class TemplateCoverageLoader(BaseLoader):
is_usable = True
@ -375,6 +391,8 @@ class CoverageTest(unittest.TestCase):
self.skipTest("Coverage switched off with --skip-coverage")
def interleaved_migrations_test(self):
if self.runner.permit_mixed_migrations:
return
# from django.apps import apps
# unreleased = {}
# for appconf in apps.get_app_configs():
@ -474,12 +492,16 @@ class IetfTestRunner(DiscoverRunner):
parser.add_argument('--html-report',
action='store_true', default=False,
help='Generate a html code coverage report in %s' % settings.TEST_CODE_COVERAGE_REPORT_DIR)
parser.add_argument('--permit-mixed-migrations',
action='store_true', default=False,
help='Permit interleaved unreleased migrations')
def __init__(self, skip_coverage=False, save_version_coverage=None, html_report=None, **kwargs):
def __init__(self, skip_coverage=False, save_version_coverage=None, html_report=None, permit_mixed_migrations=None, **kwargs):
#
self.check_coverage = not skip_coverage
self.save_version_coverage = save_version_coverage
self.html_report = html_report
self.permit_mixed_migrations = permit_mixed_migrations
#
self.root_dir = os.path.dirname(settings.BASE_DIR)
self.coverage_file = os.path.join(self.root_dir, settings.TEST_COVERAGE_MASTER_FILE)
@ -668,6 +690,7 @@ class IetfTestRunner(DiscoverRunner):
code_coverage_collection = True
url_coverage_collection = True
extra_tests += [
PyFlakesTestCase(test_runner=self, methodName='pyflakes_test'),
CoverageTest(test_runner=self, methodName='interleaved_migrations_test'),
CoverageTest(test_runner=self, methodName='url_coverage_test'),
CoverageTest(test_runner=self, methodName='template_coverage_test'),
@ -679,7 +702,7 @@ class IetfTestRunner(DiscoverRunner):
# parent classes to later subclasses, the parent classes will
# determine the ordering, so use the most specific classes
# necessary to get the right ordering:
self.reorder_by += (StaticLiveServerTestCase, TemplateTagTest, CoverageTest, )
self.reorder_by = (PyFlakesTestCase, ) + self.reorder_by + (StaticLiveServerTestCase, TemplateTagTest, CoverageTest, )
failures = super(IetfTestRunner, self).run_tests(test_labels, extra_tests=extra_tests, **kwargs)

View file

@ -37,7 +37,6 @@ from ietf.utils.bower_storage import BowerStorageFinder
from ietf.utils.draft import Draft, getmeta
from ietf.utils.log import unreachable, assertion
from ietf.utils.mail import send_mail_preformatted, send_mail_text, send_mail_mime, outbox
from ietf.utils.management.commands import pyflakes
from ietf.utils.test_runner import get_template_paths, set_coverage_checking
from ietf.utils.test_utils import TestCase
@ -51,15 +50,6 @@ except ImportError as e:
skip_message = "Skipping trac tests: %s" % e
sys.stderr.write(" "+skip_message+'\n')
class PyFlakesTestCase(TestCase):
def test_pyflakes(self):
self.maxDiff = None
path = os.path.join(settings.BASE_DIR)
warnings = []
warnings = pyflakes.checkPaths([path], verbosity=0)
self.assertEqual([], [str(w) for w in warnings])
class SendingMail(TestCase):
def test_send_mail_preformatted(self):