Merged in the Document and DocAlias primary key change and m2m work in ^/personal/henrik/6.96.1-docalias.

- Legacy-Id: 16261
This commit is contained in:
Henrik Levkowetz 2019-06-15 12:00:48 +00:00
commit 426870b766
126 changed files with 5058 additions and 338 deletions

1
.gitignore vendored
View file

@ -22,6 +22,7 @@
/.settings
/.tmp
/.factoryboy_random_state
/attic
/bin
/etc
/ghostdriver.log

View file

@ -1,4 +1,5 @@
#!/usr/bin/env python
# Copyright The IETF Trust 2017-2019, All Rights Reserved
import datetime
import os
@ -79,7 +80,7 @@ for name in sorted(names):
words=draft.get_wordcount(),
expires=time+datetime.timedelta(settings.INTERNET_DRAFT_DAYS_TO_EXPIRE),
)
doc.docalias_set.create(name=doc.name)
DocAlias.objects.create(name=doc.name).docs.add(doc)
doc.states.add(expired)
# update authors
authors = []

View file

@ -0,0 +1,44 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,56 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,32 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,34 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,57 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,46 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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

@ -1,3 +1,6 @@
# Copyright The IETF Trust 2016-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import json
from pyquery import PyQuery
@ -107,7 +110,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 +121,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

@ -1,3 +1,6 @@
# Copyright The IETF Trust 2016-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import re
from django.db.models import Q
@ -61,7 +64,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

@ -1,3 +1,6 @@
# Copyright The IETF Trust 2012-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import csv
import uuid
import datetime
@ -57,9 +60,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 +212,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

@ -1,3 +1,6 @@
# Copyright The IETF Trust 2010-2019, All Rights Reserved
# -*- coding: utf-8 -*-
from django.contrib import admin
from django import forms
@ -19,9 +22,9 @@ class StateAdmin(admin.ModelAdmin):
filter_horizontal = ["next_states"]
admin.site.register(State, StateAdmin)
class DocAliasInline(admin.TabularInline):
model = DocAlias
extra = 1
# class DocAliasInline(admin.TabularInline):
# model = DocAlias
# extra = 1
class DocAuthorInline(admin.TabularInline):
model = DocumentAuthor
@ -58,7 +61,7 @@ class DocumentAdmin(admin.ModelAdmin):
search_fields = ['name']
list_filter = ['type']
raw_id_fields = ['group', 'shepherd', 'ad']
inlines = [DocAliasInline, DocAuthorInline, RelatedDocumentInline, ]
inlines = [DocAuthorInline, RelatedDocumentInline, ]
form = DocumentForm
def save_model(self, request, obj, form, change):
@ -88,9 +91,9 @@ class DocHistoryAdmin(admin.ModelAdmin):
admin.site.register(DocHistory, DocHistoryAdmin)
class DocAliasAdmin(admin.ModelAdmin):
list_display = ['name', 'document_link']
search_fields = ['name', 'document__name']
raw_id_fields = ['document']
# list_display = ['name', 'document_link']
# search_fields = ['name', 'document__name']
raw_id_fields = ['docs']
admin.site.register(DocAlias, DocAliasAdmin)
class DocReminderAdmin(admin.ModelAdmin):
@ -102,7 +105,7 @@ admin.site.register(DocReminder, DocReminderAdmin)
class RelatedDocumentAdmin(admin.ModelAdmin):
list_display = ['source', 'target', 'relationship', ]
list_filter = ['relationship', ]
search_fields = ['source__name', 'target__name', 'target__document__name', ]
search_fields = ['source__name', 'target__name', 'target__docs__name', ]
raw_id_fields = ['source', 'target', ]
admin.site.register(RelatedDocument, RelatedDocumentAdmin)

View file

@ -1,3 +1,6 @@
# Copyright The IETF Trust 2016-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import debug # pyflakes:ignore
import factory
import datetime
@ -33,13 +36,14 @@ class BaseDocumentFactory(factory.DjangoModelFactory):
newrevisiondocevent = factory.RelatedFactory('ietf.doc.factories.NewRevisionDocEventFactory','doc')
alias = factory.RelatedFactory('ietf.doc.factories.DocAliasFactory','document')
@factory.post_generation
def other_aliases(obj, create, extracted, **kwargs): # pylint: disable=no-self-argument
alias = DocAliasFactory(name=obj.name)
alias.docs.add(obj)
if create and extracted:
for alias in extracted:
obj.docalias_set.create(name=alias)
for name in extracted:
alias = DocAliasFactory(name=name)
alias.docs.add(obj)
@factory.post_generation
def states(obj, create, extracted, **kwargs): # pylint: disable=no-self-argument
@ -61,10 +65,14 @@ class BaseDocumentFactory(factory.DjangoModelFactory):
@factory.post_generation
def relations(obj, create, extracted, **kwargs): # pylint: disable=no-self-argument
if create and extracted:
for (rel_id,docalias) in extracted:
if isinstance(docalias,Document):
docalias = docalias.docalias_set.first()
obj.relateddocument_set.create(relationship_id=rel_id,target=docalias)
for (rel_id, doc) in extracted:
if isinstance(doc, Document):
docalias = doc.docalias.first()
elif isinstance(doc, DocAlias):
docalias = doc
else:
continue
obj.relateddocument_set.create(relationship_id=rel_id, target=docalias)
@classmethod
def _after_postgeneration(cls, obj, create, results=None):
@ -195,9 +203,9 @@ class ConflictReviewFactory(BaseDocumentFactory):
if not create:
return
if extracted:
obj.relateddocument_set.create(relationship_id='conflrev',target=extracted.docalias_set.first())
obj.relateddocument_set.create(relationship_id='conflrev',target=extracted.docalias.first())
else:
obj.relateddocument_set.create(relationship_id='conflrev',target=DocumentFactory(type_id='draft',group=Group.objects.get(type_id='individ')).docalias_set.first())
obj.relateddocument_set.create(relationship_id='conflrev',target=DocumentFactory(type_id='draft',group=Group.objects.get(type_id='individ')).docalias.first())
@factory.post_generation
def states(obj, create, extracted, **kwargs):
@ -219,12 +227,18 @@ class DocAliasFactory(factory.DjangoModelFactory):
class Meta:
model = DocAlias
document = factory.SubFactory('ietf.doc.factories.DocumentFactory')
@factory.post_generation
def document(self, create, extracted, **kwargs):
if create and extracted:
self.docs.add(extracted)
@factory.post_generation
def docs(self, create, extracted, **kwargs):
if create and extracted:
for doc in extracted:
if not doc in self.docs.all():
self.docs.add(doc)
@factory.lazy_attribute
def name(self):
return self.document.name
class DocEventFactory(factory.DjangoModelFactory):
class Meta:

View file

@ -1,7 +1,11 @@
# Copyright The IETF Trust 2014-2019, All Rights Reserved
# -*- coding: utf-8 -*-
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,11 +56,13 @@ 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
filter_args["docs__type"] = self.doc_type
else:
filter_args["type"] = self.doc_type
value = value.filter(**filter_args)
@ -76,17 +82,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,26 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,36 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,122 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,94 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,113 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,26 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,125 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,84 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,34 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,63 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,68 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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

@ -1,4 +1,5 @@
# Copyright The IETF Trust 2007, All Rights Reserved
# Copyright The IETF Trust 2007-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import datetime
import logging
@ -323,7 +324,7 @@ class DocumentInfo(models.Model):
elif state.slug == "repl":
rs = self.related_that("replaces")
if rs:
return mark_safe("Replaced by " + ", ".join("<a href=\"%s\">%s</a>" % (urlreverse('ietf.doc.views_doc.document_main', kwargs=dict(name=alias.document)), alias.document) for alias in rs))
return mark_safe("Replaced by " + ", ".join("<a href=\"%s\">%s</a>" % (urlreverse('ietf.doc.views_doc.document_main', kwargs=dict(name=alias.document.name)), alias.document) for alias in rs))
else:
return "Replaced"
elif state.slug == "active":
@ -411,9 +412,9 @@ class DocumentInfo(models.Model):
if not isinstance(relationship, tuple):
raise TypeError("Expected a string or tuple, received %s" % type(relationship))
if isinstance(self, Document):
return RelatedDocument.objects.filter(target__document=self, relationship__in=relationship).select_related('source')
return RelatedDocument.objects.filter(target__docs=self, relationship__in=relationship).select_related('source')
elif isinstance(self, DocHistory):
return RelatedDocHistory.objects.filter(target__document=self.doc, relationship__in=relationship).select_related('source')
return RelatedDocHistory.objects.filter(target__docs=self.doc, relationship__in=relationship).select_related('source')
else:
raise TypeError("Expected method called on Document or DocHistory")
@ -434,9 +435,9 @@ class DocumentInfo(models.Model):
if not isinstance(relationship, tuple):
raise TypeError("Expected a string or tuple, received %s" % type(relationship))
if isinstance(self, Document):
return RelatedDocument.objects.filter(source=self, relationship__in=relationship).select_related('target__document')
return RelatedDocument.objects.filter(source=self, relationship__in=relationship).select_related('target')
elif isinstance(self, DocHistory):
return RelatedDocHistory.objects.filter(source=self, relationship__in=relationship).select_related('target__document')
return RelatedDocHistory.objects.filter(source=self, relationship__in=relationship).select_related('target')
else:
raise TypeError("Expected method called on Document or DocHistory")
@ -447,14 +448,15 @@ class DocumentInfo(models.Model):
for r in rels:
if not r in related:
related += ( r, )
related = r.target.document.all_relations_that_doc(relationship, related)
for doc in r.target.docs.all():
related = doc.all_relations_that_doc(relationship, related)
return related
def related_that(self, relationship):
return list(set([x.source.docalias_set.get(name=x.source.name) for x in self.relations_that(relationship)]))
return list(set([x.source.docalias.get(name=x.source.name) for x in self.relations_that(relationship)]))
def all_related_that(self, relationship, related=None):
return list(set([x.source.docalias_set.get(name=x.source.name) for x in self.all_relations_that(relationship)]))
return list(set([x.source.docalias.get(name=x.source.name) for x in self.all_relations_that(relationship)]))
def related_that_doc(self, relationship):
return list(set([x.target for x in self.relations_that_doc(relationship)]))
@ -463,7 +465,7 @@ class DocumentInfo(models.Model):
return list(set([x.target for x in self.all_relations_that_doc(relationship)]))
def replaces(self):
return set([ r.document for r in self.related_that_doc("replaces")])
return set([ d for r in self.related_that_doc("replaces") for d in r.docs.all() ])
def replaces_canonical_name(self):
s = set([ r.document for r in self.related_that_doc("replaces")])
@ -609,7 +611,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
@ -657,7 +659,7 @@ class Document(DocumentInfo):
if not hasattr(self, '_canonical_name'):
name = self.name
if self.type_id == "draft" and self.get_state_slug() == "rfc":
a = self.docalias_set.filter(name__startswith="rfc").order_by('-name').first()
a = self.docalias.filter(name__startswith="rfc").order_by('-name').first()
if a:
name = a.name
elif self.type_id == "charter":
@ -671,7 +673,7 @@ class Document(DocumentInfo):
def canonical_docalias(self):
return self.docalias_set.get(name=self.name)
return self.docalias.get(name=self.name)
def display_name(self):
name = self.canonical_name()
@ -766,14 +768,14 @@ class Document(DocumentInfo):
def ipr(self,states=('posted','removed')):
"""Returns the IPR disclosures against this document (as a queryset over IprDocRel)."""
from ietf.ipr.models import IprDocRel
return IprDocRel.objects.filter(document__document=self,disclosure__state__in=states)
return IprDocRel.objects.filter(document__docs=self, disclosure__state__in=states)
def related_ipr(self):
"""Returns the IPR disclosures against this document and those documents this
document directly or indirectly obsoletes or replaces
"""
from ietf.ipr.models import IprDocRel
iprs = IprDocRel.objects.filter(document__in=list(self.docalias_set.all())+self.all_related_that_doc(('obs','replaces'))).filter(disclosure__state__in=('posted','removed')).values_list('disclosure', flat=True).distinct()
iprs = IprDocRel.objects.filter(document__in=list(self.docalias.all())+self.all_related_that_doc(('obs','replaces'))).filter(disclosure__state__in=('posted','removed')).values_list('disclosure', flat=True).distinct()
return iprs
def future_presentations(self):
@ -889,8 +891,9 @@ class DocHistory(DocumentInfo):
return self.doc.groupmilestone_set
@property
def docalias_set(self):
return self.doc.docalias_set
def docalias(self):
log.unreachable('2019-06-11')
return self.doc.docalias
def is_dochistory(self):
return True
@ -908,10 +911,15 @@ 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)
document = ForeignKey(Document)
name = models.CharField(max_length=255, unique=True)
docs = models.ManyToManyField(Document, related_name='docalias')
@property
def document(self):
return self.docs.first()
def __unicode__(self):
return "%s-->%s" % (self.name, self.document.name)
return "%s-->%s" % (self.name, ','.join([unicode(d.name) for d in self.docs.all() if isinstance(d, Document) ]))
document_link = admin_link("document")
class Meta:
verbose_name = "document alias"
@ -1005,7 +1013,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

@ -1,3 +1,6 @@
# Copyright The IETF Trust 2012-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import os
import shutil
import datetime
@ -216,7 +219,7 @@ class SearchTests(TestCase):
draft.set_state(State.objects.get(type='draft-iesg', slug='lc'))
rfc = IndividualDraftFactory(ad=ad)
rfc.set_state(State.objects.get(type='draft', slug='rfc'))
rfc.docalias_set.create(name='rfc6666')
DocAlias.objects.create(name='rfc6666').docs.add(rfc)
conflrev = DocumentFactory(type_id='conflrev',ad=ad)
conflrev.set_state(State.objects.get(type='conflrev', slug='iesgeval'))
statchg = DocumentFactory(type_id='statchg',ad=ad)
@ -278,7 +281,7 @@ class SearchTests(TestCase):
self.assertEqual(data[0]["id"], draft.pk)
# DocAlias
doc_alias = draft.docalias_set.get()
doc_alias = draft.docalias.first()
url = urlreverse('ietf.doc.views_search.ajax_select2_search_docs', kwargs={
"model_name": "docalias",
@ -499,7 +502,7 @@ Man Expires September 22, 2015 [Page 3]
draft = WgDraftFactory(name='draft-ietf-mars-test',rev='01')
HolderIprDisclosureFactory(docs=[draft])
replaced = IndividualDraftFactory()
draft.relateddocument_set.create(relationship_id='replaces',source=draft,target=replaced.docalias_set.first())
draft.relateddocument_set.create(relationship_id='replaces',source=draft,target=replaced.docalias.first())
# these tests aren't testing all attributes yet, feel free to
# expand them
@ -580,7 +583,7 @@ Man Expires September 22, 2015 [Page 3]
shepherd_id=draft.shepherd_id, ad_id=draft.ad_id, expires=draft.expires,
notify=draft.notify, note=draft.note)
rel = RelatedDocument.objects.create(source=replacement,
target=draft.docalias_set.get(name__startswith="draft"),
target=draft.docalias.get(name__startswith="draft"),
relationship_id="replaces")
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name)))
@ -595,8 +598,10 @@ Man Expires September 22, 2015 [Page 3]
draft.save_with_history([DocEvent.objects.create(doc=draft, rev=draft.rev, type="published_rfc", by=Person.objects.get(name="(System)"))])
rfc_alias = DocAlias.objects.create(name="rfc123456", document=draft)
bcp_alias = DocAlias.objects.create(name="bcp123456", document=draft)
rfc_alias = DocAlias.objects.create(name="rfc123456")
rfc_alias.docs.add(draft)
bcp_alias = DocAlias.objects.create(name="bcp123456")
bcp_alias.docs.add(draft)
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name)))
self.assertEqual(r.status_code, 302)
@ -759,8 +764,8 @@ class DocTestCase(TestCase):
self.assertFalse('more YES or NO' in unicontent(r))
# status change
IndividualDraftFactory().docalias_set.create(name='rfc9998')
IndividualDraftFactory().docalias_set.create(name='rfc9999')
DocAlias.objects.create(name='rfc9998').docs.add(IndividualDraftFactory())
DocAlias.objects.create(name='rfc9999').docs.add(IndividualDraftFactory())
doc = DocumentFactory(type_id='statchg',name='status-change-imaginary-mid-review')
iesgeval_pk = str(State.objects.get(slug='iesgeval',type__slug='statchg').pk)
self.client.login(username='ad', password='ad+password')
@ -1003,7 +1008,7 @@ class ReferencesTest(TestCase):
def test_references(self):
doc1 = WgDraftFactory(name='draft-ietf-mars-test')
doc2 = IndividualDraftFactory(name='draft-imaginary-independent-submission').docalias_set.first()
doc2 = IndividualDraftFactory(name='draft-imaginary-independent-submission').docalias.first()
RelatedDocument.objects.get_or_create(source=doc1,target=doc2,relationship=DocRelationshipName.objects.get(slug='refnorm'))
url = urlreverse('ietf.doc.views_doc.document_references', kwargs=dict(name=doc1.name))
r = self.client.get(url)

View file

@ -1,4 +1,6 @@
# Copyright The IETF Trust 2013-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import datetime
from pyquery import PyQuery
@ -741,7 +743,7 @@ class ApproveBallotTests(TestCase):
self.assertTrue("No downward references for" in r.content)
# Add a downref, the page should ask if it should be added to the registry
rel = draft.relateddocument_set.create(target=rfc.docalias_set.get(name='rfc6666'),relationship_id='refnorm')
rel = draft.relateddocument_set.create(target=rfc.docalias.get(name='rfc6666'),relationship_id='refnorm')
d = [rdoc for rdoc in draft.relateddocument_set.all() if rel.is_approved_downref()]
original_len = len(d)
r = self.client.get(url)
@ -970,7 +972,7 @@ class RegenerateLastCallTestCase(TestCase):
std_level_id='inf',
)
draft.relateddocument_set.create(target=rfc.docalias_set.get(name='rfc6666'),relationship_id='refnorm')
draft.relateddocument_set.create(target=rfc.docalias.get(name='rfc6666'),relationship_id='refnorm')
r = self.client.post(url, dict(regenerate_last_call_text="1"))
self.assertEqual(r.status_code, 200)
@ -980,7 +982,7 @@ class RegenerateLastCallTestCase(TestCase):
self.assertTrue("rfc6666" in lc_text)
self.assertTrue("Independent Submission Editor stream" in lc_text)
draft.relateddocument_set.create(target=rfc.docalias_set.get(name='rfc6666'),relationship_id='downref-approval')
draft.relateddocument_set.create(target=rfc.docalias.get(name='rfc6666'),relationship_id='downref-approval')
r = self.client.post(url, dict(regenerate_last_call_text="1"))
self.assertEqual(r.status_code, 200)

View file

@ -1,4 +1,4 @@
# Copyright The IETF Trust 2017, All Rights Reserved
# Copyright The IETF Trust 2017-2019, All Rights Reserved
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
@ -21,7 +21,7 @@ class Downref(TestCase):
WgDraftFactory(name='draft-ietf-mars-test')
doc = WgDraftFactory(name='draft-ietf-mars-approved-document',states=[('draft-iesg','rfcqueue')])
rfc = WgRfcFactory(alias2__name='rfc9998')
RelatedDocument.objects.create(source=doc, target=rfc.docalias_set.get(name='rfc9998'),relationship_id='downref-approval')
RelatedDocument.objects.create(source=doc, target=rfc.docalias.get(name='rfc9998'),relationship_id='downref-approval')
def test_downref_registry(self):
url = urlreverse('ietf.doc.views_downref.downref_registry')
@ -118,7 +118,7 @@ class Downref(TestCase):
draft = WgDraftFactory(name='draft-ietf-mars-ready-for-lc-document',intended_std_level_id='ps',states=[('draft-iesg','iesg-eva')])
WgDraftFactory(name='draft-ietf-mars-another-approved-document',states=[('draft-iesg','rfcqueue')])
rfc9999 = WgRfcFactory(alias2__name='rfc9999', std_level_id=None)
RelatedDocument.objects.create(source=draft, target=rfc9999.docalias_set.get(name='rfc9999'), relationship_id='refnorm')
RelatedDocument.objects.create(source=draft, target=rfc9999.docalias.get(name='rfc9999'), relationship_id='refnorm')
url = urlreverse('ietf.doc.views_ballot.lastcalltext', kwargs=dict(name=draft.name))
login_testing_unauthorized(self, "secretary", url)
@ -130,7 +130,7 @@ class Downref(TestCase):
self.assertIn('The document contains these normative downward references', text)
# now, the announcement text about the downref to RFC 9999 should be gone
RelatedDocument.objects.create(source=draft, target=rfc9999.docalias_set.get(name='rfc9999'),relationship_id='downref-approval')
RelatedDocument.objects.create(source=draft, target=rfc9999.docalias.get(name='rfc9999'),relationship_id='downref-approval')
r = self.client.post(url, dict(regenerate_last_call_text="1"))
self.assertEqual(r.status_code, 200)
q = PyQuery(r.content)

View file

@ -1,4 +1,6 @@
# Copyright The IETF Trust 2011-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import os
import shutil
import datetime
@ -1569,7 +1571,7 @@ class ChangeReplacesTests(TestCase):
# Post that says replacea replaces base a
empty_outbox()
RelatedDocument.objects.create(source=self.replacea, target=self.basea.docalias_set.first(),
RelatedDocument.objects.create(source=self.replacea, target=self.basea.docalias.first(),
relationship=DocRelationshipName.objects.get(slug="possibly-replaces"))
self.assertEqual(self.basea.get_state().slug,'active')
r = self.client.post(url, dict(replaces=self.basea.name))
@ -1617,7 +1619,7 @@ class ChangeReplacesTests(TestCase):
def test_review_possibly_replaces(self):
replaced = self.basea.docalias_set.first()
replaced = self.basea.docalias.first()
RelatedDocument.objects.create(source=self.replacea, target=replaced,
relationship=DocRelationshipName.objects.get(slug="possibly-replaces"))

View file

@ -1,4 +1,5 @@
# Copyright The IETF Trust 2011, All Rights Reserved
# Copyright The IETF Trust 2011-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import os
import shutil
@ -52,7 +53,7 @@ class GroupMaterialTests(TestCase):
doc = Document.objects.create(name="slides-testteam-test-file", rev="01", type_id="slides", group=group)
doc.set_state(State.objects.get(type="slides", slug="active"))
doc.set_state(State.objects.get(type="reuse_policy", slug="multiple"))
DocAlias.objects.create(name=doc.name, document=doc)
DocAlias.objects.create(name=doc.name).docs.add(doc)
NewRevisionDocEvent.objects.create(doc=doc,by=Person.objects.get(name="(System)"),rev='00',type='new_revision',desc='New revision available')
NewRevisionDocEvent.objects.create(doc=doc,by=Person.objects.get(name="(System)"),rev='01',type='new_revision',desc='New revision available')

View file

@ -1,3 +1,4 @@
# Copyright The IETF Trust 2016-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import datetime, os, shutil, json
@ -144,8 +145,8 @@ class ReviewTests(TestCase):
# check we can fish it out
old_doc = WgDraftFactory(name="draft-foo-mars-test")
older_doc = WgDraftFactory(name="draft-older")
RelatedDocument.objects.create(source=old_doc, target=older_doc.docalias_set.first(), relationship_id='replaces')
RelatedDocument.objects.create(source=doc, target=old_doc.docalias_set.first(), relationship_id='replaces')
RelatedDocument.objects.create(source=old_doc, target=older_doc.docalias.first(), relationship_id='replaces')
RelatedDocument.objects.create(source=doc, target=old_doc.docalias.first(), relationship_id='replaces')
review_req.doc = older_doc
review_req.save()

View file

@ -1,4 +1,6 @@
# Copyright The IETF Trust 2013-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import os
import shutil
@ -74,7 +76,7 @@ class StatusChangeTests(TestCase):
self.assertEqual(status_change.rev,u'00')
self.assertEqual(status_change.ad.name,u'Areað Irector')
self.assertEqual(status_change.notify,u'ipu@ietf.org')
self.assertTrue(status_change.relateddocument_set.filter(relationship__slug='tois',target__document__name='draft-ietf-random-thing'))
self.assertTrue(status_change.relateddocument_set.filter(relationship__slug='tois',target__docs__name='draft-ietf-random-thing'))
def test_change_state(self):

View file

@ -1,3 +1,6 @@
# Copyright The IETF Trust 2011-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import os
import re
import urllib
@ -684,10 +687,8 @@ def extract_complete_replaces_ancestor_mapping_for_docs(names):
if not front:
break
relations = RelatedDocument.objects.filter(
source__in=front, relationship="replaces"
).select_related("target").values_list("source", "target__document")
relations = ( RelatedDocument.objects.filter(source__name__in=front, relationship="replaces")
.select_related("target").values_list("source__name", "target__docs__name") )
if not relations:
break

View file

@ -1,4 +1,5 @@
# Copyright The IETF Trust 2016, All Rights Reserved
# Copyright The IETF Trust 2016-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import datetime
import debug # pyflakes:ignore
@ -20,7 +21,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 +50,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([ (a.document.id, a.name) for a in DocAlias.objects.filter(name__startswith="rfc", docs__id__in=doc_ids) ])
# latest event cache
event_types = ("published_rfc",
@ -61,11 +62,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)
@ -122,11 +123,10 @@ def fill_in_document_table_attributes(docs, have_telechat_date=False):
d.updated_by_list = []
xed_by = RelatedDocument.objects.filter(target__name__in=rfc_aliases.values(),
relationship__in=("obs", "updates")).select_related('target__document')
rel_rfc_aliases = dict(DocAlias.objects.filter(name__startswith="rfc",
document__in=[rel.source_id for rel in xed_by]).values_list('document', 'name'))
relationship__in=("obs", "updates")).select_related('target')
rel_rfc_aliases = dict([ (a.document.id, a.name) for a in DocAlias.objects.filter(name__startswith="rfc", docs__id__in=[rel.source_id for rel in xed_by]) ])
for rel in xed_by:
d = doc_dict[rel.target.document_id]
d = doc_dict[rel.target.document.id]
if rel.relationship_id == "obs":
l = d.obsoleted_by_list
elif rel.relationship_id == "updates":
@ -146,7 +146,7 @@ def prepare_document_table(request, docs, query=None, max_results=200):
# the number of queries
docs = docs.select_related("ad", "std_level", "intended_std_level", "group", "stream", "shepherd", )
docs = docs.prefetch_related("states__type", "tags", "groupmilestone_set__group", "reviewrequest_set__team",
"submission_set__checks", "ad__email_set", "docalias_set__iprdocrel_set")
"submission_set__checks", "ad__email_set", "docalias__iprdocrel_set")
if docs.count() > max_results:
docs = docs[:max_results]

View file

@ -1,3 +1,6 @@
# Copyright The IETF Trust 2011-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import os, datetime, textwrap, json
from django.http import HttpResponseRedirect, HttpResponseNotFound, HttpResponseForbidden, Http404
@ -392,7 +395,7 @@ def submit(request, name, option=None):
abstract=group.name,
rev=next_rev,
)
DocAlias.objects.create(name=charter.name, document=charter)
DocAlias.objects.create(name=charter.name).docs.add(charter)
charter.set_state(State.objects.get(used=True, type="charter", slug="notrev"))

View file

@ -1,3 +1,6 @@
# Copyright The IETF Trust 2012-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import datetime, os
from django import forms
@ -388,7 +391,7 @@ def start_review_sanity_check(request, name):
raise Http404
# sanity check that there's not already a conflict review document for this document
if [ rel.source for alias in doc_to_review.docalias_set.all() for rel in alias.relateddocument_set.filter(relationship='conflrev') ]:
if [ rel.source for alias in doc_to_review.docalias.all() for rel in alias.relateddocument_set.filter(relationship='conflrev') ]:
raise Http404
return doc_to_review
@ -421,7 +424,8 @@ def build_conflict_review_document(login, doc_to_review, ad, notify, create_in_s
)
conflict_review.set_state(create_in_state)
DocAlias.objects.create( name=review_name , document=conflict_review )
DocAlias.objects.create( name=review_name).docs.add( conflict_review )
conflict_review.relateddocument_set.create(target=DocAlias.objects.get(name=doc_to_review.name),relationship_id='conflrev')

View file

@ -103,7 +103,7 @@ def document_main(request, name, rev=None):
doc = get_object_or_404(Document.objects.select_related(), docalias__name=name)
# take care of possible redirections
aliases = DocAlias.objects.filter(document=doc).values_list("name", flat=True)
aliases = DocAlias.objects.filter(docs=doc).values_list("name", flat=True)
if rev==None and doc.type_id == "draft" and not name.startswith("rfc"):
for a in aliases:
if a.startswith("rfc"):
@ -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,12 +598,12 @@ 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)
assignments = ReviewAssignment.objects.filter(review=doc.name)
assignments = ReviewAssignment.objects.filter(review__name=doc.name)
review_assignment = assignments.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,
@ -716,7 +716,7 @@ def document_history(request, name):
if doc.get_state_slug() == "rfc":
e = doc.latest_event(type="published_rfc")
aliases = doc.docalias_set.filter(name__startswith="rfc")
aliases = doc.docalias.filter(name__startswith="rfc")
if aliases:
name = aliases[0].name
diff_revisions.append((name, "", e.time if e else doc.time, name))
@ -1011,7 +1011,7 @@ def document_json(request, name, rev=None):
data["expires"] = doc.expires.strftime("%Y-%m-%d %H:%M:%S") if doc.expires else None
data["title"] = doc.title
data["abstract"] = doc.abstract
data["aliases"] = list(doc.docalias_set.values_list("name", flat=True))
data["aliases"] = list(doc.docalias.values_list("name", flat=True))
data["state"] = extract_name(doc.get_state())
data["intended_std_level"] = extract_name(doc.intended_std_level)
data["std_level"] = extract_name(doc.std_level)

View file

@ -1,3 +1,6 @@
# Copyright The IETF Trust 2014-2019, All Rights Reserved
# -*- coding: utf-8 -*-
# views for managing group materials (slides, ...)
import os
import re
@ -142,7 +145,8 @@ def edit_material(request, name=None, acronym=None, action=None, doc_type=None):
dest.write(chunk)
if action == "new":
DocAlias.objects.get_or_create(name=doc.name, document=doc)
alias, __ = DocAlias.objects.get_or_create(name=doc.name)
alias.docs.add(doc)
if prev_rev != doc.rev:
e = NewRevisionDocEvent(type="new_revision", doc=doc, rev=doc.rev)

View file

@ -1,5 +1,5 @@
# Copyright The IETF Trust 2016-2019, All Rights Reserved
# -*- coding: utf-8 -*-
# Copyright The IETF Trust 2011, All Rights Reserved
from __future__ import unicode_literals, print_function
import os
@ -593,7 +593,7 @@ def complete_review(request, name, assignment_id):
name = "-".join(c for c in name_components if c).lower()
if not Document.objects.filter(name=name).exists():
review = Document.objects.create(name=name)
DocAlias.objects.create(document=review, name=review.name)
DocAlias.objects.create(name=review.name).docs.add(review)
break
review.type = DocTypeName.objects.get(slug="review")

View file

@ -1,4 +1,7 @@
# Copyright (C) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
# Copyright The IETF Trust 2009-2019, All Rights Reserved
# -*- coding: utf-8 -*-
# Some parts Copyright (C) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
# All rights reserved. Contact: Pasi Eronen <pasi.eronen@nokia.com>
#
# Redistribution and use in source and binary forms, with or without
@ -478,7 +481,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(docs__states=state).values_list("name", "docs__name")
names = []
names_to_skip = set()
@ -528,7 +531,7 @@ def ajax_select2_search_docs(request, model_name, doc_type):
if model == Document:
qs = qs.filter(type=doc_type)
elif model == DocAlias:
qs = qs.filter(document__type=doc_type)
qs = qs.filter(docs__type=doc_type)
for t in q:
qs = qs.filter(name__icontains=t)

View file

@ -1,3 +1,6 @@
# Copyright The IETF Trust 2012-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import datetime, os, re
from django import forms
@ -527,7 +530,7 @@ def start_rfc_status_change(request,name):
)
status_change.set_state(form.cleaned_data['create_in_state'])
DocAlias.objects.create( name= 'status-change-'+form.cleaned_data['document_name'], document=status_change )
DocAlias.objects.create( name= 'status-change-'+form.cleaned_data['document_name']).docs.add(status_change)
for key in form.cleaned_data['relations']:
status_change.relateddocument_set.create(target=DocAlias.objects.get(name=key),

View file

@ -1,4 +1,4 @@
# Copyright The IETF Trust 2007, All Rights Reserved
# Copyright The IETF Trust 2007-2019, All Rights Reserved
# -*- check-flake8 -*-
from __future__ import unicode_literals, print_function
@ -100,7 +100,7 @@ def get_node_styles(node, group):
def make_dot(group):
references = Q(source__group=group, source__type='draft', relationship__slug__startswith='ref')
both_rfcs = Q(source__states__slug='rfc', target__document__states__slug='rfc')
both_rfcs = Q(source__states__slug='rfc', target__docs__states__slug='rfc')
inactive = Q(source__states__slug__in=['expired', 'repl'])
attractor = Q(target__name__in=['rfc5000', 'rfc5741'])
removed = Q(source__states__slug__in=['auth-rm', 'ietf-rm'])
@ -114,7 +114,7 @@ def make_dot(group):
edges.add(Edge(x))
replacements = RelatedDocument.objects.filter(relationship__slug='replaces',
target__document__in=[x.relateddocument.target.document for x in edges])
target__docs__in=[x.relateddocument.target.document for x in edges])
for x in replacements:
edges.add(Edge(x))

View file

@ -1,4 +1,5 @@
# Copyright The IETF Trust 2011, All Rights Reserved
# Copyright The IETF Trust 2011-2019, All Rights Reserved
# -*- coding: utf-8 -*-
from django.contrib.syndication.views import Feed, FeedDoesNotExist
from django.utils.feedgenerator import Atom1Feed
@ -38,7 +39,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

@ -1,4 +1,5 @@
# Copyright The IETF Trust 2007, All Rights Reserved
# Copyright The IETF Trust 2007-2019, All Rights Reserved
# -*- coding: utf-8 -*-
from __future__ import unicode_literals, print_function
# Stdlib imports
@ -227,7 +228,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,53 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,57 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,41 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,41 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,58 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,46 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,20 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,22 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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

@ -1,3 +1,6 @@
# Copyright The IETF Trust 2013-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import os
from unittest import skipIf
@ -71,7 +74,7 @@ class GroupDocDependencyGraphTests(TestCase):
set_coverage_checking(False)
a = WgDraftFactory()
b = WgDraftFactory()
RelatedDocument.objects.create(source=a,target=b.docalias_set.first(),relationship_id='normref')
RelatedDocument.objects.create(source=a,target=b.docalias.first(),relationship_id='normref')
def tearDown(self):
set_coverage_checking(True)

View file

@ -1,3 +1,4 @@
# Copyright The IETF Trust 2009-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import os
@ -325,7 +326,7 @@ class GroupPagesTests(TestCase):
type_id="slides",
)
doc.set_state(State.objects.get(type="slides", slug="active"))
DocAlias.objects.create(name=doc.name, document=doc)
DocAlias.objects.create(name=doc.name).docs.add(doc)
for url in group_urlreverse_list(group, 'ietf.group.views.materials'):
r = self.client.get(url)

View file

@ -1,3 +1,6 @@
# Copyright The IETF Trust 2016-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import datetime
import debug # pyflakes:ignore
@ -237,7 +240,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 +483,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

@ -188,7 +188,7 @@ def fill_in_wg_roles(group):
group.secretaries = get_roles("secr", [])
def fill_in_wg_drafts(group):
aliases = DocAlias.objects.filter(document__type="draft", document__group=group).select_related('document').order_by("name")
aliases = DocAlias.objects.filter(docs__type="draft", docs__group=group).prefetch_related('docs').order_by("name")
group.drafts = []
group.rfcs = []
for a in aliases:
@ -804,7 +804,7 @@ def group_photos(request, group_type=None, acronym=None):
# charter.set_state(State.objects.get(used=True, type="charter", slug="notrev"))
#
# # Create an alias as well
# DocAlias.objects.create(name=charter.name, document=charter)
# DocAlias.objects.create(name=charter.name).docs.add(charter)
#
# return charter
#
@ -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", "assigned"), team=group).prefetch_related("reviewassignment_set__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
@ -1418,7 +1418,7 @@ def manage_review_requests(request, acronym, group_type=None, assignment_status=
# add previous requests
l = []
rev = None
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
for a in r.reviewassignment_set.all():
if l and rev:
@ -1706,7 +1706,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

@ -1,3 +1,6 @@
# Copyright The IETF Trust 2013-2019, All Rights Reserved
# -*- coding: utf-8 -*-
# code to generate plain-text index files that are placed on
# www.ietf.org in the same directory as the I-Ds
@ -22,17 +25,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"))
docs__states=State.objects.get(type="draft", slug="rfc")).values_list("docs__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"))
replacements = dict(RelatedDocument.objects.filter(target__docs__states=State.objects.get(type="draft", slug="repl"),
relationship="replaces").values_list("target__name", "source__name"))
# we need a distinct to prevent the queries below from multiplying the result
@ -66,7 +69,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 +113,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"))
docs__states=State.objects.get(type="draft", slug="rfc")).values_list("docs__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"))
replacements = dict(RelatedDocument.objects.filter(target__docs__states=State.objects.get(type="draft", slug="repl"),
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 +242,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 +251,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

@ -1,3 +1,4 @@
# Copyright The IETF Trust 2009-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import os
@ -47,7 +48,7 @@ class IndexTests(TestCase):
# published
draft.set_state(State.objects.get(type="draft", slug="rfc"))
DocAlias.objects.create(name="rfc1234", document=draft)
DocAlias.objects.create(name="rfc1234").docs.add(draft)
txt = all_id_txt()
self.assertTrue(draft.name + "-" + draft.rev in txt)
@ -59,7 +60,7 @@ class IndexTests(TestCase):
RelatedDocument.objects.create(
relationship=DocRelationshipName.objects.get(slug="replaces"),
source=Document.objects.create(type_id="draft", rev="00", name="draft-test-replacement"),
target=draft.docalias_set.get(name__startswith="draft"))
target=draft.docalias.get(name__startswith="draft"))
txt = all_id_txt()
self.assertTrue(draft.name + "-" + draft.rev in txt)
@ -109,7 +110,7 @@ class IndexTests(TestCase):
# test RFC
draft.set_state(State.objects.get(type="draft", slug="rfc"))
DocAlias.objects.create(name="rfc1234", document=draft)
DocAlias.objects.create(name="rfc1234").docs.add(draft)
t = get_fields(all_id2_txt())
self.assertEqual(t[4], "1234")
@ -118,7 +119,7 @@ class IndexTests(TestCase):
RelatedDocument.objects.create(
relationship=DocRelationshipName.objects.get(slug="replaces"),
source=Document.objects.create(type_id="draft", rev="00", name="draft-test-replacement"),
target=draft.docalias_set.get(name__startswith="draft"))
target=draft.docalias.get(name__startswith="draft"))
t = get_fields(all_id2_txt())
self.assertEqual(t[5], "draft-test-replacement")

View file

@ -1,3 +1,6 @@
# Copyright The IETF Trust 2013-2019, All Rights Reserved
# -*- coding: utf-8 -*-
# utilities for constructing agendas for IESG telechats
import codecs
@ -182,7 +185,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

@ -1,4 +1,6 @@
# Copyright The IETF Trust 2009-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import os
import shutil
import json
@ -92,7 +94,7 @@ class IESGAgendaTests(TestCase):
mars = GroupFactory(acronym='mars',parent=Group.objects.get(acronym='farfut'))
wgdraft = WgDraftFactory(name='draft-ietf-mars-test', group=mars, intended_std_level_id='ps')
rfc = IndividualRfcFactory.create(stream_id='irtf', other_aliases=['rfc6666',], states=[('draft','rfc'),('draft-iesg','pub')], std_level_id='inf', )
wgdraft.relateddocument_set.create(target=rfc.docalias_set.get(name='rfc6666'), relationship_id='refnorm')
wgdraft.relateddocument_set.create(target=rfc.docalias.get(name='rfc6666'), relationship_id='refnorm')
ise_draft = IndividualDraftFactory(name='draft-imaginary-independent-submission')
ise_draft.stream = StreamName.objects.get(slug="ise")
ise_draft.save_with_history([DocEvent(doc=ise_draft, rev=ise_draft.rev, type="changed_stream", by=Person.objects.get(user__username="secretary"), desc="Test")])
@ -216,7 +218,7 @@ class IESGAgendaTests(TestCase):
relation = RelatedDocument.objects.create(
source=statchg,
target=DocAlias.objects.filter(name__startswith='rfc', document__std_level="ps")[0],
target=DocAlias.objects.filter(name__startswith='rfc', docs__std_level="ps")[0],
relationship_id="tohist")
statchg.group = Group.objects.get(acronym="mars")
@ -234,7 +236,7 @@ class IESGAgendaTests(TestCase):
self.assertTrue(statchg in agenda_data(date_str)["sections"]["2.3.3"]["docs"])
# 3.3 document status changes
relation.target = DocAlias.objects.filter(name__startswith='rfc', document__std_level="inf")[0]
relation.target = DocAlias.objects.filter(name__startswith='rfc', docs__std_level="inf")[0]
relation.save()
statchg.group = Group.objects.get(acronym="mars")
@ -493,7 +495,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

@ -1,4 +1,4 @@
# Copyright The IETF Trust 2017, All Rights Reserved
# Copyright The IETF Trust 2017-2019, All Rights Reserved
# -*- coding: utf-8 -*-
from __future__ import unicode_literals, print_function
@ -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

@ -1,4 +1,6 @@
#coding: utf-8
# Copyright The IETF Trust 2010-2019, All Rights Reserved
# -*- coding: utf-8 -*-
from django import forms
from django.contrib import admin
from ietf.name.models import DocRelationshipName
@ -91,7 +93,7 @@ admin.site.register(IprDocRel, IprDocRelAdmin)
class RelatedIprAdmin(admin.ModelAdmin):
list_display = ['source', 'target', 'relationship', ]
search_fields = ['source__name', 'target__name', 'target__document__name', ]
search_fields = ['source__name', 'target__name', 'target__docs__name', ]
raw_id_fields = ['source', 'target', ]
admin.site.register(RelatedIpr, RelatedIprAdmin)

View file

@ -1,3 +1,6 @@
# Copyright The IETF Trust 2018-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import datetime
import factory
@ -34,7 +37,7 @@ class IprDisclosureBaseFactory(factory.DjangoModelFactory):
return
if extracted:
for doc in extracted:
IprDocRel.objects.create(disclosure=self,document=doc.docalias_set.first())
IprDocRel.objects.create(disclosure=self,document=doc.docalias.first())
@factory.post_generation
def updates(self, create, extracted, **kwargs):

View file

@ -0,0 +1,29 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,20 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,22 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,23 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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

@ -1,3 +1,6 @@
# Copyright The IETF Trust 2009-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import datetime
import urllib
@ -157,7 +160,7 @@ class IprTests(TestCase):
self.assertTrue(draft.name in unicontent(r))
self.assertTrue(ipr.title not in unicontent(r))
DocAlias.objects.create(name="rfc321", document=draft)
DocAlias.objects.create(name="rfc321").docs.add(draft)
# find RFC
r = self.client.get(url + "?submit=rfc&rfc=321")
@ -260,9 +263,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.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 +306,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.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 +354,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.first().name,
"iprdocrel_set-0-revisions": '00',
"iprdocrel_set-INITIAL_FORMS": 0,
"iprdocrel_set-TOTAL_FORMS": 1,
@ -400,9 +403,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.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 +441,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.first().name,
"iprdocrel_set-0-revisions": '00',
"patent_number": "SE12345678901",
"patent_inventor": "A. Nonymous",
@ -627,7 +630,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

@ -1,3 +1,8 @@
# Copyright The IETF Trust 2014-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import debug # pyflakes:ignore
def get_genitive(name):
"""Return the genitive form of name"""
return name + "'" if name.endswith('s') else name + "'s"
@ -29,23 +34,30 @@ def iprs_from_docs(aliases,**kwargs):
"""Returns a list of IPRs related to doc aliases"""
iprdocrels = []
for alias in aliases:
if alias.document.ipr(**kwargs):
iprdocrels += alias.document.ipr(**kwargs)
for document in alias.docs.all():
if document.ipr(**kwargs):
iprdocrels += document.ipr(**kwargs)
return list(set([i.disclosure for i in iprdocrels]))
def related_docs(alias, relationship=('replaces', 'obs')):
"""Returns list of related documents"""
results = list(alias.document.docalias_set.all())
results = []
for doc in alias.docs.all():
results += list(doc.docalias.all())
rels = alias.document.all_relations_that_doc(relationship)
rels = []
for doc in alias.docs.all():
rels += list(doc.all_relations_that_doc(relationship))
for rel in rels:
rel_aliases = list(rel.target.document.docalias_set.all())
rel_aliases = list(rel.target.document.docalias.all())
for x in rel_aliases:
x.related = rel
x.relation = rel.relationship.revname
results += rel_aliases
return list(set(results))

View file

@ -1,4 +1,5 @@
# Copyright The IETF Trust 2007, All Rights Reserved
# Copyright The IETF Trust 2007-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import datetime
import itertools
@ -460,16 +461,16 @@ def by_draft_recursive_txt(request):
for o in IprDocRel.objects.filter(disclosure__state='posted').select_related('document'):
alias = o.document
document = alias.document
name = alias.name
related = set(document.docalias_set.all()) | set(document.all_related_that_doc(('obs', 'replaces')))
for alias in related:
name = alias.name
if name.startswith("rfc"):
name = name.upper()
if not name in docipr:
docipr[name] = []
docipr[name].append(o.disclosure_id)
for document in alias.docs.all():
related = set(document.docalias.all()) | set(document.all_related_that_doc(('obs', 'replaces')))
for alias in related:
name = alias.name
if name.startswith("rfc"):
name = name.upper()
if not name in docipr:
docipr[name] = []
docipr[name].append(o.disclosure_id)
lines = [ u"# Machine-readable list of IPR disclosures by draft name" ]
for name, iprs in docipr.iteritems():
@ -700,7 +701,7 @@ def search(request):
# Search by wg acronym
# Document list with IPRs
elif search_type == "group":
docs = list(DocAlias.objects.filter(document__group=q))
docs = list(DocAlias.objects.filter(docs__group=q))
related = []
for doc in docs:
doc.product_of_this_wg = True
@ -714,7 +715,7 @@ def search(request):
# Search by rfc and id title
# Document list with IPRs
elif search_type == "doctitle":
docs = list(DocAlias.objects.filter(document__title__icontains=q))
docs = list(DocAlias.objects.filter(docs__title__icontains=q))
related = []
for doc in docs:
related += related_docs(doc)

View file

@ -1,3 +1,6 @@
# Copyright The IETF Trust 2011-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import datetime, os
import operator
import six
@ -25,7 +28,7 @@ from ietf.liaisons.fields import SearchableLiaisonStatementsField
from ietf.group.models import Group
from ietf.person.models import Email
from ietf.person.fields import SearchableEmailField
from ietf.doc.models import Document
from ietf.doc.models import Document, DocAlias
from ietf.utils.fields import DatepickerDateField
'''
@ -370,7 +373,7 @@ class LiaisonModelForm(BetterModelForm):
)
)
if created:
attach.docalias_set.create(name=attach.name)
DocAlias.objects.create(name=attach.name).docs.add(attach)
LiaisonStatementAttachment.objects.create(statement=self.instance,document=attach)
attach_file = open(os.path.join(settings.LIAISON_ATTACH_PATH, attach.name + extension), 'w')
attach_file.write(attached_file.read())

View file

@ -0,0 +1,29 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,20 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,22 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,23 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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

@ -1,3 +1,6 @@
# Copyright The IETF Trust 2016-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import os
import codecs
import datetime
@ -271,7 +274,7 @@ class InterimSessionModelForm(forms.ModelForm):
# FIXME: What about agendas in html or markdown format?
uploaded_filename='{}-00.txt'.format(filename))
doc.set_state(State.objects.get(type__slug=doc.type.slug, slug='active'))
DocAlias.objects.create(name=doc.name, document=doc)
DocAlias.objects.create(name=doc.name).docs.add(doc)
self.instance.sessionpresentation_set.create(document=doc, rev=doc.rev)
NewRevisionDocEvent.objects.create(
type='new_revision',

View file

@ -0,0 +1,29 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,34 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,26 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,23 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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

@ -1,3 +1,6 @@
# Copyright The IETF Trust 2007-2019, All Rights Reserved
# -*- coding: utf-8 -*-
# old meeting models can be found in ../proceedings/models.py
import pytz
@ -863,6 +866,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

@ -1,4 +1,5 @@
# Copyright The IETF Trust 2007-2018, All Rights Reserved
# Copyright The IETF Trust 2007-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import csv
import datetime
@ -38,7 +39,7 @@ from django.views.generic import RedirectView
from ietf.doc.fields import SearchableDocumentsField
from ietf.doc.models import Document, State, DocEvent, NewRevisionDocEvent
from ietf.doc.models import Document, State, DocEvent, NewRevisionDocEvent, DocAlias
from ietf.group.models import Group
from ietf.group.utils import can_manage_materials
from ietf.ietfauth.utils import role_required, has_role
@ -1218,7 +1219,7 @@ def upload_session_bluesheets(request, session_id, num):
rev = '00',
)
doc.states.add(State.objects.get(type_id='bluesheets',slug='active'))
doc.docalias_set.create(name=doc.name)
DocAlias.objects.create(name=doc.name).docs.add(doc)
session.sessionpresentation_set.create(document=doc,rev='00')
filename = '%s-%s%s'% ( doc.name, doc.rev, ext)
doc.uploaded_filename = filename
@ -1307,7 +1308,7 @@ def upload_session_minutes(request, session_id, num):
group = session.group,
rev = '00',
)
doc.docalias_set.create(name=doc.name)
DocAlias.objects.create(name=doc.name).docs.add(doc)
doc.states.add(State.objects.get(type_id='minutes',slug='active'))
if session.sessionpresentation_set.filter(document=doc).exists():
sp = session.sessionpresentation_set.get(document=doc)
@ -1410,7 +1411,7 @@ def upload_session_agenda(request, session_id, num):
group = session.group,
rev = '00',
)
doc.docalias_set.create(name=doc.name)
DocAlias.objects.create(name=doc.name).docs.add(doc)
doc.states.add(State.objects.get(type_id='agenda',slug='active'))
if session.sessionpresentation_set.filter(document=doc).exists():
sp = session.sessionpresentation_set.get(document=doc)
@ -1513,7 +1514,7 @@ def upload_session_slides(request, session_id, num, name):
group = session.group,
rev = '00',
)
doc.docalias_set.create(name=doc.name)
DocAlias.objects.create(name=doc.name).docs.add(doc)
doc.states.add(State.objects.get(type_id='slides',slug='active'))
doc.states.add(State.objects.get(type_id='reuse_policy',slug='single'))
if session.sessionpresentation_set.filter(document=doc).exists():
@ -2448,7 +2449,7 @@ def approve_proposed_slides(request, slidesubmission_id, num):
group = submission.session.group,
rev = '00',
)
doc.docalias_set.create(name=doc.name)
DocAlias.objects.create(name=doc.name).docs.add(doc)
doc.states.add(State.objects.get(type_id='slides',slug='active'))
doc.states.add(State.objects.get(type_id='reuse_policy',slug='single'))
if submission.session.sessionpresentation_set.filter(document=doc).exists():

View file

@ -0,0 +1,31 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,47 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,32 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,32 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,28 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,31 @@
# Copyright The IETF Trust 2019, All Rights Reserved
# -*- 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,59 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-08 11:58
# Copyright The IETF Trust 2019, All Rights Reserved
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,48 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-20 09:53
# Copyright The IETF Trust 2019, All Rights Reserved
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,32 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-21 05:31
# Copyright The IETF Trust 2019, All Rights Reserved
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,28 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-06-10 03:47
# Copyright The IETF Trust 2019, All Rights Reserved
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

@ -1,3 +1,5 @@
# Copyright The IETF Trust 2016-2019, All Rights Reserved
import datetime
from simple_history.models import HistoricalRecords
@ -119,14 +121,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)
@ -832,7 +834,7 @@ def make_assignment_choices(email_queryset, review_req):
possible_emails = list(email_queryset)
possible_person_ids = [e.person_id for e in possible_emails]
aliases = DocAlias.objects.filter(document=doc).values_list("name", flat=True)
aliases = DocAlias.objects.filter(docs=doc).values_list("name", flat=True)
# settings
reviewer_settings = {
@ -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

@ -1,3 +1,6 @@
# Copyright The IETF Trust 2013-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import datetime
import glob
import os
@ -579,7 +582,7 @@ def view(request, id):
draft.rfc_number = get_rfc_num(draft)
# check for replaced bys
qs = Document.objects.filter(relateddocument__target__document=draft, relateddocument__relationship='replaces')
qs = Document.objects.filter(relateddocument__target__docs=draft, relateddocument__relationship='replaces')
if qs:
draft.replaced_by = qs[0]

View file

@ -1,3 +1,6 @@
# Copyright The IETF Trust 2013-2019, All Rights Reserved
# -*- coding: utf-8 -*-
'''
proc_utils.py
@ -113,10 +116,10 @@ def attach_recording(doc, sessions):
document=doc,
rev=doc.rev)
session.sessionpresentation_set.add(presentation)
if not doc.docalias_set.filter(name__startswith='recording-{}-{}'.format(session.meeting.number,session.group.acronym)):
if not doc.docalias.filter(name__startswith='recording-{}-{}'.format(session.meeting.number,session.group.acronym)):
sequence = get_next_sequence(session.group,session.meeting,'recording')
name = 'recording-{}-{}-{}'.format(session.meeting.number,session.group.acronym,sequence)
doc.docalias_set.create(name=name)
DocAlias.objects.create(name=name).docs.add(doc)
def normalize_room_name(name):
'''Returns room name converted to be used as portion of filename'''
@ -150,7 +153,7 @@ def create_recording(session, url, title=None, user=None):
type_id='recording')
doc.set_state(State.objects.get(type='recording', slug='active'))
doc.docalias_set.create(name=name)
DocAlias.objects.create(name=doc.name).docs.add(doc)
# create DocEvent
NewRevisionDocEvent.objects.create(type='new_revision',
@ -207,10 +210,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 +227,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

@ -1,3 +1,6 @@
# Copyright The IETF Trust 2013-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import debug # pyflakes:ignore
import json
import os
@ -132,8 +135,8 @@ class RecordingTestCase(TestCase):
import_audio_files(meeting)
doc = mars_session.materials.filter(type='recording').first()
self.assertTrue(doc in ames_session.materials.all())
self.assertTrue(doc.docalias_set.filter(name='recording-42-mars-1'))
self.assertTrue(doc.docalias_set.filter(name='recording-42-ames-1'))
self.assertTrue(doc.docalias.filter(name='recording-42-mars-1'))
self.assertTrue(doc.docalias.filter(name='recording-42-ames-1'))
def test_normalize_room_name(self):
self.assertEqual(normalize_room_name('Test Room'),'testroom')

View file

@ -1,4 +1,6 @@
# Copyright The IETF Trust 2013-2019, All Rights Reserved
# -*- coding: utf-8 -*-
import datetime
from pyquery import PyQuery
@ -63,7 +65,7 @@ class SecrTelechatTestCase(TestCase):
draft = WgDraftFactory(ad=ad, intended_std_level_id='ps', states=[('draft-iesg','pub-req'),])
rfc = IndividualRfcFactory.create(stream_id='irtf', other_aliases=['rfc6666',],
states=[('draft','rfc'),('draft-iesg','pub')], std_level_id='inf', )
draft.relateddocument_set.create(target=rfc.docalias_set.get(name='rfc6666'),
draft.relateddocument_set.create(target=rfc.docalias.get(name='rfc6666'),
relationship_id='refnorm')
create_ballot_if_not_open(None, draft, ad, 'approve')
d = get_next_telechat_date()

Some files were not shown because too many files have changed in this diff Show more