chore: explore architecture change in RelatedDocument

This commit is contained in:
Robert Sparks 2023-06-16 14:58:42 -05:00
parent 7798ea8d66
commit 769d85a6c4
No known key found for this signature in database
GPG key ID: 6E2A6A5775F91318
37 changed files with 189 additions and 194 deletions

View file

@ -934,7 +934,7 @@ class RfcdiffSupportTests(TestCase):
self.assertNotIn('previous', received, 'Rev 00 has no previous name when not replacing a draft')
replaced = IndividualDraftFactory()
RelatedDocument.objects.create(relationship_id='replaces',source=draft,target=replaced.docalias.first())
RelatedDocument.objects.create(relationship_id='replaces',source=draft,target=replaced)
received = self.getJson(dict(name=draft.name, rev='00'))
self.assertEqual(received['previous'], f'{replaced.name}-{replaced.rev}',
'Rev 00 has a previous name when replacing a draft')

View file

@ -355,7 +355,7 @@ def rfcdiff_latest_json(request, name, rev=None):
if doc.rev == '00':
replaces_docs = (history.doc if condition=='historic version' else doc).related_that_doc('replaces')
if replaces_docs:
replaces = replaces_docs[0].document
replaces = replaces_docs[0]
response['previous'] = f'{replaces.name}-{replaces.rev}'
response['previous_url'] = get_previous_url(replaces.name, replaces.rev)
else:

View file

@ -43,6 +43,7 @@ class DocActionHolderInline(admin.TabularInline):
class RelatedDocumentInline(admin.TabularInline):
model = RelatedDocument
fk_name= 'source'
def this(self, instance):
return instance.source.canonical_name()
readonly_fields = ['this', ]
@ -125,7 +126,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__docs__name', ]
search_fields = ['source__name', 'target__name', 'target__name', ]
raw_id_fields = ['source', 'target', ]
admin.site.register(RelatedDocument, RelatedDocumentAdmin)

View file

@ -83,13 +83,7 @@ class BaseDocumentFactory(factory.django.DjangoModelFactory):
def relations(obj, create, extracted, **kwargs): # pylint: disable=no-self-argument
if create and extracted:
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)
obj.relateddocument_set.create(relationship_id=rel_id, target=doc)
@factory.post_generation
def create_revisions(obj, create, extracted, **kwargs): # pylint: disable=no-self-argument
@ -279,7 +273,7 @@ class StatusChangeFactory(BaseDocumentFactory):
for (rel, target) in extracted:
obj.relateddocument_set.create(relationship_id=rel,target=target)
else:
obj.relateddocument_set.create(relationship_id='tobcp', target=WgRfcFactory().docalias.first())
obj.relateddocument_set.create(relationship_id='tobcp', target=WgRfcFactory())
@factory.post_generation
def states(obj, create, extracted, **kwargs):
@ -306,9 +300,9 @@ class ConflictReviewFactory(BaseDocumentFactory):
if not create:
return
if extracted:
obj.relateddocument_set.create(relationship_id='conflrev',target=extracted.docalias.first())
obj.relateddocument_set.create(relationship_id='conflrev',target=extracted)
else:
obj.relateddocument_set.create(relationship_id='conflrev',target=DocumentFactory(name=obj.name.replace('conflict-review-','draft-'),type_id='draft',group=Group.objects.get(type_id='individ')).docalias.first())
obj.relateddocument_set.create(relationship_id='conflrev',target=DocumentFactory(name=obj.name.replace('conflict-review-','draft-'),type_id='draft',group=Group.objects.get(type_id='individ')))
@factory.post_generation

View file

@ -8,7 +8,7 @@ from django import forms
from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.core.validators import validate_email
from ietf.doc.fields import SearchableDocAliasesField, SearchableDocAliasField
from ietf.doc.fields import SearchableDocumentField, SearchableDocumentsField
from ietf.doc.models import RelatedDocument, DocExtResource
from ietf.iesg.models import TelechatDate
from ietf.iesg.utils import telechat_page_count
@ -134,11 +134,11 @@ class ActionHoldersForm(forms.Form):
IESG_APPROVED_STATE_LIST = ("ann", "rfcqueue", "pub")
class AddDownrefForm(forms.Form):
rfc = SearchableDocAliasField(
rfc = SearchableDocumentField(
label="Referenced RFC",
help_text="The RFC that is approved for downref",
required=True)
drafts = SearchableDocAliasesField(
drafts = SearchableDocumentsField(
label="Internet-Drafts that makes the reference",
help_text="The Internet-Drafts that approve the downref in their Last Call",
required=True)
@ -148,7 +148,7 @@ class AddDownrefForm(forms.Form):
raise forms.ValidationError("Please provide a referenced RFC and a referencing Internet-Draft")
rfc = self.cleaned_data['rfc']
if not rfc.document.is_rfc():
if not rfc.is_rfc():
raise forms.ValidationError("Cannot find the RFC: " + rfc.name)
return rfc
@ -158,10 +158,10 @@ class AddDownrefForm(forms.Form):
v_err_names = []
drafts = self.cleaned_data['drafts']
for da in drafts:
state = da.document.get_state("draft-iesg")
for d in drafts:
state = d.get_state("draft-iesg")
if not state or state.slug not in IESG_APPROVED_STATE_LIST:
v_err_names.append(da.name)
v_err_names.append(d.name)
if v_err_names:
raise forms.ValidationError("Internet-Draft is not yet approved: " + ", ".join(v_err_names))
return drafts
@ -173,23 +173,23 @@ class AddDownrefForm(forms.Form):
v_err_pairs = []
rfc = self.cleaned_data['rfc']
drafts = self.cleaned_data['drafts']
for da in drafts:
if RelatedDocument.objects.filter(source=da.document, target=rfc, relationship_id='downref-approval'):
v_err_pairs.append(da.name + " --> RFC " + rfc.document.rfc_number())
for d in drafts:
if RelatedDocument.objects.filter(source=d, target=rfc, relationship_id='downref-approval'):
v_err_pairs.append(d.name + " --> RFC " + rfc.rfc_number())
if v_err_pairs:
raise forms.ValidationError("Downref is already in the registry: " + ", ".join(v_err_pairs))
if 'save_downref_anyway' not in self.data:
# this check is skipped if the save_downref_anyway button is used
v_err_refnorm = ""
for da in drafts:
if not RelatedDocument.objects.filter(source=da.document, target=rfc, relationship_id='refnorm'):
for d in drafts:
if not RelatedDocument.objects.filter(source=d, target=rfc, relationship_id='refnorm'):
if v_err_refnorm:
v_err_refnorm = v_err_refnorm + " or " + da.name
v_err_refnorm = v_err_refnorm + " or " + d.name
else:
v_err_refnorm = da.name
v_err_refnorm = d.name
if v_err_refnorm:
v_err_refnorm_prefix = "There does not seem to be a normative reference to RFC " + rfc.document.rfc_number() + " by "
v_err_refnorm_prefix = "There does not seem to be a normative reference to RFC " + rfc.rfc_number() + " by "
raise forms.ValidationError(v_err_refnorm_prefix + v_err_refnorm)

View file

@ -54,7 +54,7 @@ def email_ad_approved_doc(request, doc, text):
def email_ad_approved_conflict_review(request, review, ok_to_publish):
"""Email notification when AD approves a conflict review"""
conflictdoc = review.relateddocument_set.get(relationship__slug='conflrev').target.document
conflictdoc = review.relateddocument_set.get(relationship__slug='conflrev').target
(to, cc) = gather_address_lists("ad_approved_conflict_review")
frm = request.user.person.formatted_email()
send_mail(request,

View file

@ -468,9 +468,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__docs=self, relationship__in=relationship).select_related('source')
return RelatedDocument.objects.filter(target=self, relationship__in=relationship).select_related('source')
elif isinstance(self, DocHistory):
return RelatedDocHistory.objects.filter(target__docs=self.doc, relationship__in=relationship).select_related('source')
return RelatedDocHistory.objects.filter(target=self.doc, relationship__in=relationship).select_related('source')
else:
raise TypeError("Expected method called on Document or DocHistory")
@ -504,8 +504,7 @@ class DocumentInfo(models.Model):
for r in rels:
if not r in related:
related += ( r, )
for doc in r.target.docs.all():
related = doc.all_relations_that_doc(relationship, related)
related = r.target.all_relations_that_doc(relationship, related)
return related
def related_that(self, relationship):
@ -668,7 +667,7 @@ STATUSCHANGE_RELATIONS = ('tops','tois','tohist','toinf','tobcp','toexp')
class RelatedDocument(models.Model):
source = ForeignKey('Document')
target = ForeignKey('DocAlias')
target = ForeignKey('Document', related_name='target')
relationship = ForeignKey(DocRelationshipName)
def action(self):
return self.relationship.name
@ -691,16 +690,16 @@ class RelatedDocument(models.Model):
if source_lvl not in ['bcp','ps','ds','std']:
return None
if self.target.document.get_state().slug == 'rfc':
if not self.target.document.std_level:
if self.target.get_state().slug == 'rfc':
if not self.target.std_level:
target_lvl = 'unkn'
else:
target_lvl = self.target.document.std_level.slug
target_lvl = self.target.std_level.slug
else:
if not self.target.document.intended_std_level:
if not self.target.intended_std_level:
target_lvl = 'unkn'
else:
target_lvl = self.target.document.intended_std_level.slug
target_lvl = self.target.intended_std_level.slug
rank = { 'ps':1, 'ds':2, 'std':3, 'bcp':3 }
@ -714,7 +713,7 @@ class RelatedDocument(models.Model):
def is_approved_downref(self):
if self.target.document.get_state().slug == 'rfc':
if self.target.get_state().slug == 'rfc':
if RelatedDocument.objects.filter(relationship_id='downref-approval', target=self.target):
return "Approved Downref"
@ -967,7 +966,15 @@ class Document(DocumentInfo):
document directly or indirectly obsoletes or replaces
"""
from ietf.ipr.models import IprDocRel
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()
iprs = (
IprDocRel.objects.filter(
document__in=list(self.docalias.all())
+ [x.docalias.first() for x in 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):
@ -1106,7 +1113,7 @@ class DocExtResource(ExtResource):
class RelatedDocHistory(models.Model):
source = ForeignKey('DocHistory')
target = ForeignKey('DocAlias', related_name="reversely_related_document_history_set")
target = ForeignKey('Document', related_name="reversely_related_document_history_set")
relationship = ForeignKey(DocRelationshipName)
def __str__(self):
return u"%s %s %s" % (self.source.doc.name, self.relationship.name.lower(), self.target.name)

View file

@ -288,8 +288,8 @@ def urlize_related_target_list(related, document_html=False):
"""Convert a list of RelatedDocuments into list of links using the target document's canonical name"""
links = []
for rel in related:
name=rel.target.document.canonical_name()
title = rel.target.document.title
name=rel.target.canonical_name()
title = rel.target.title
url = urlreverse('ietf.doc.views_doc.document_main' if document_html is False else 'ietf.doc.views_doc.document_html', kwargs=dict(name=name))
name = escape(name)
title = escape(title)

View file

@ -625,15 +625,15 @@ Man Expires September 22, 2015 [Page 3]
# Docs for testing relationships. Does not test 'possibly-replaces'. The 'replaced_by' direction
# is tested separately below.
replaced = IndividualDraftFactory()
draft.relateddocument_set.create(relationship_id='replaces',source=draft,target=replaced.docalias.first())
draft.relateddocument_set.create(relationship_id='replaces',source=draft,target=replaced)
obsoleted = IndividualDraftFactory()
draft.relateddocument_set.create(relationship_id='obs',source=draft,target=obsoleted.docalias.first())
draft.relateddocument_set.create(relationship_id='obs',source=draft,target=obsoleted)
obsoleted_by = IndividualDraftFactory()
obsoleted_by.relateddocument_set.create(relationship_id='obs',source=obsoleted_by,target=draft.docalias.first())
obsoleted_by.relateddocument_set.create(relationship_id='obs',source=obsoleted_by,target=draft)
updated = IndividualDraftFactory()
draft.relateddocument_set.create(relationship_id='updates',source=draft,target=updated.docalias.first())
draft.relateddocument_set.create(relationship_id='updates',source=draft,target=updated)
updated_by = IndividualDraftFactory()
updated_by.relateddocument_set.create(relationship_id='updates',source=obsoleted_by,target=draft.docalias.first())
updated_by.relateddocument_set.create(relationship_id='updates',source=obsoleted_by,target=draft)
external_resource = DocExtResourceFactory(doc=draft)
@ -819,7 +819,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.get(name__startswith="draft"),
target=draft,
relationship_id="replaces")
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name)))
@ -891,7 +891,7 @@ Man Expires September 22, 2015 [Page 3]
draft = WgRfcFactory()
status_change_doc = StatusChangeFactory(
group=draft.group,
changes_status_of=[('tops', draft.docalias.first())],
changes_status_of=[('tops', draft)],
)
status_change_url = urlreverse(
'ietf.doc.views_doc.document_main',
@ -899,7 +899,7 @@ Man Expires September 22, 2015 [Page 3]
)
proposed_status_change_doc = StatusChangeFactory(
group=draft.group,
changes_status_of=[('tobcp', draft.docalias.first())],
changes_status_of=[('tobcp', draft)],
states=[State.objects.get(slug='needshep', type='statchg')],
)
proposed_status_change_url = urlreverse(
@ -1610,7 +1610,7 @@ class DocTestCase(TestCase):
statchg = StatusChangeFactory()
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=statchg.name)))
self.assertEqual(r.status_code, 200)
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=statchg.relateddocument_set.first().target.document)))
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=statchg.relateddocument_set.first().target)))
self.assertEqual(r.status_code, 302)
def test_document_charter(self):
@ -1771,8 +1771,8 @@ class DocTestCase(TestCase):
self.assertNotContains(r, 'more YES or NO')
# status change
DocAlias.objects.create(name='rfc9998').docs.add(IndividualDraftFactory())
DocAlias.objects.create(name='rfc9999').docs.add(IndividualDraftFactory())
Document.objects.create(name='rfc9998')
Document.objects.create(name='rfc9999')
doc = DocumentFactory(type_id='statchg',name='status-change-imaginary-mid-review')
iesgeval_pk = str(State.objects.get(slug='iesgeval',type__slug='statchg').pk)
empty_outbox()
@ -1785,12 +1785,12 @@ class DocTestCase(TestCase):
self.assertIn('iesg-secretary',outbox[0]['To'])
self.assertIn('drafts-eval',outbox[1]['To'])
doc.relateddocument_set.create(target=DocAlias.objects.get(name='rfc9998'),relationship_id='tohist')
doc.relateddocument_set.create(target=Document.objects.get(name='rfc9998'),relationship_id='tohist')
r = self.client.get(urlreverse("ietf.doc.views_doc.document_ballot", kwargs=dict(name=doc.name)))
self.assertNotContains(r, 'Needs a YES')
self.assertNotContains(r, 'more YES or NO')
doc.relateddocument_set.create(target=DocAlias.objects.get(name='rfc9999'),relationship_id='tois')
doc.relateddocument_set.create(target=Document.objects.get(name='rfc9999'),relationship_id='tois')
r = self.client.get(urlreverse("ietf.doc.views_doc.document_ballot", kwargs=dict(name=doc.name)))
self.assertContains(r, 'more YES or NO')
@ -2088,7 +2088,7 @@ class ReferencesTest(TestCase):
def test_references(self):
doc1 = WgDraftFactory(name='draft-ietf-mars-test')
doc2 = IndividualDraftFactory(name='draft-imaginary-independent-submission').docalias.first()
doc2 = IndividualDraftFactory(name='draft-imaginary-independent-submission')
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

@ -803,8 +803,8 @@ class ApproveBallotTests(TestCase):
desc='Last call announcement was changed',
text='this is simple last call text.' )
rfc = IndividualRfcFactory.create(
name = "rfc6666",
stream_id='ise',
other_aliases=['rfc6666',],
states=[('draft','rfc'),('draft-iesg','pub')],
std_level_id='inf', )
@ -821,7 +821,7 @@ class ApproveBallotTests(TestCase):
self.assertContains(r, "No downward references for")
# Add a downref, the page should ask if it should be added to the registry
rel = draft.relateddocument_set.create(target=rfc.docalias.get(name='rfc6666'),relationship_id='refnorm')
rel = draft.relateddocument_set.create(target=rfc, 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)
@ -1122,12 +1122,12 @@ class RegenerateLastCallTestCase(TestCase):
rfc = IndividualRfcFactory.create(
stream_id='ise',
other_aliases=['rfc6666',],
name='rfc6666',
states=[('draft','rfc'),('draft-iesg','pub')],
std_level_id='inf',
)
draft.relateddocument_set.create(target=rfc.docalias.get(name='rfc6666'),relationship_id='refnorm')
draft.relateddocument_set.create(target=rfc,relationship_id='refnorm')
r = self.client.post(url, dict(regenerate_last_call_text="1"))
self.assertEqual(r.status_code, 200)
@ -1137,7 +1137,7 @@ class RegenerateLastCallTestCase(TestCase):
self.assertTrue("rfc6666" in lc_text)
self.assertTrue("Independent Submission" in lc_text)
draft.relateddocument_set.create(target=rfc.docalias.get(name='rfc6666'), relationship_id='downref-approval')
draft.relateddocument_set.create(target=rfc, relationship_id='downref-approval')
r = self.client.post(url, dict(regenerate_last_call_text="1"))
self.assertEqual(r.status_code, 200)

View file

@ -70,12 +70,12 @@ class ConflictReviewTests(TestCase):
self.assertEqual(review_doc.ad.name,'Areað Irector')
self.assertEqual(review_doc.notify,'ipu@ietf.org')
doc = Document.objects.get(name='draft-imaginary-independent-submission')
self.assertTrue(doc in [x.target.document for x in review_doc.relateddocument_set.filter(relationship__slug='conflrev')])
self.assertTrue(doc in [x.target for x in review_doc.relateddocument_set.filter(relationship__slug='conflrev')])
self.assertTrue(review_doc.latest_event(DocEvent,type="added_comment").desc.startswith("IETF conflict review requested"))
self.assertTrue(doc.latest_event(DocEvent,type="added_comment").desc.startswith("IETF conflict review initiated"))
self.assertTrue('Conflict Review requested' in outbox[-1]['Subject'])
# verify you can't start a review when a review is already in progress
r = self.client.post(url,dict(ad="Areað Irector",create_in_state="Needs Shepherd",notify='ipu@ietf.org'))
self.assertEqual(r.status_code, 404)
@ -119,7 +119,7 @@ class ConflictReviewTests(TestCase):
self.assertEqual(review_doc.ad.name,'Ietf Chair')
self.assertEqual(review_doc.notify,'ipu@ietf.org')
doc = Document.objects.get(name='draft-imaginary-independent-submission')
self.assertTrue(doc in [x.target.document for x in review_doc.relateddocument_set.filter(relationship__slug='conflrev')])
self.assertTrue(doc in [x.target for x in review_doc.relateddocument_set.filter(relationship__slug='conflrev')])
self.assertEqual(len(outbox), messages_before + 2)

View file

@ -22,9 +22,9 @@ class Downref(TestCase):
self.draftalias = self.draft.docalias.get(name='draft-ietf-mars-test')
self.doc = WgDraftFactory(name='draft-ietf-mars-approved-document',states=[('draft-iesg','rfcqueue')])
self.docalias = self.doc.docalias.get(name='draft-ietf-mars-approved-document')
self.rfc = WgRfcFactory(alias2__name='rfc9998')
self.rfc = WgRfcFactory(name='rfc9998')
self.rfcalias = self.rfc.docalias.get(name='rfc9998')
RelatedDocument.objects.create(source=self.doc, target=self.rfcalias, relationship_id='downref-approval')
RelatedDocument.objects.create(source=self.doc, target=self.rfc, relationship_id='downref-approval')
def test_downref_registry(self):
url = urlreverse('ietf.doc.views_downref.downref_registry')
@ -64,44 +64,44 @@ class Downref(TestCase):
self.assertContains(r, 'Save downref')
# error - already in the downref registry
r = self.client.post(url, dict(rfc=self.rfcalias.pk, drafts=(self.docalias.pk, )))
r = self.client.post(url, dict(rfc=self.rfc.pk, drafts=(self.doc.pk, )))
self.assertContains(r, 'Downref is already in the registry')
# error - source is not in an approved state
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
r = self.client.post(url, dict(rfc=self.rfcalias.pk, drafts=(self.draftalias.pk, )))
r = self.client.post(url, dict(rfc=self.rfc.pk, drafts=(self.draft.pk, )))
self.assertContains(r, 'Draft is not yet approved')
# error - the target is not a normative reference of the source
self.draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="pub"))
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
r = self.client.post(url, dict(rfc=self.rfcalias.pk, drafts=(self.draftalias.pk, )))
r = self.client.post(url, dict(rfc=self.rfc.pk, drafts=(self.draft.pk, )))
self.assertContains(r, 'There does not seem to be a normative reference to RFC')
self.assertContains(r, 'Save downref anyway')
# normal - approve the document so the downref is now okay
RelatedDocument.objects.create(source=self.draft, target=self.rfcalias, relationship_id='refnorm')
RelatedDocument.objects.create(source=self.draft, target=self.rfc, relationship_id='refnorm')
draft_de_count_before = self.draft.docevent_set.count()
rfc_de_count_before = self.rfc.docevent_set.count()
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
r = self.client.post(url, dict(rfc=self.rfcalias.pk, drafts=(self.draftalias.pk, )))
r = self.client.post(url, dict(rfc=self.rfc.pk, drafts=(self.draft.pk, )))
self.assertEqual(r.status_code, 302)
newurl = urlreverse('ietf.doc.views_downref.downref_registry')
r = self.client.get(newurl)
self.assertContains(r, '<a href="/doc/draft-ietf-mars-test')
self.assertTrue(RelatedDocument.objects.filter(source=self.draft, target=self.rfcalias, relationship_id='downref-approval'))
self.assertTrue(RelatedDocument.objects.filter(source=self.draft, target=self.rfc, relationship_id='downref-approval'))
self.assertEqual(self.draft.docevent_set.count(), draft_de_count_before + 1)
self.assertEqual(self.rfc.docevent_set.count(), rfc_de_count_before + 1)
def test_downref_last_call(self):
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.get(name='rfc9999'), relationship_id='refnorm')
rfc9999 = WgRfcFactory(name='rfc9999', std_level_id=None)
RelatedDocument.objects.create(source=draft, target=rfc9999, relationship_id='refnorm')
url = urlreverse('ietf.doc.views_ballot.lastcalltext', kwargs=dict(name=draft.name))
login_testing_unauthorized(self, "secretary", url)
@ -113,7 +113,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.get(name='rfc9999'),relationship_id='downref-approval')
RelatedDocument.objects.create(source=draft, target=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

@ -2017,10 +2017,10 @@ class ChangeReplacesTests(TestCase):
# Post that says replacea replaces base a
empty_outbox()
RelatedDocument.objects.create(source=self.replacea, target=self.basea.docalias.first(),
RelatedDocument.objects.create(source=self.replacea, target=self.basea,
relationship=DocRelationshipName.objects.get(slug="possibly-replaces"))
self.assertEqual(self.basea.get_state().slug,'active')
r = self.client.post(url, dict(replaces=self.basea.docalias.first().pk))
r = self.client.post(url, dict(replaces=self.basea.pk))
self.assertEqual(r.status_code, 302)
self.assertEqual(RelatedDocument.objects.filter(relationship__slug='replaces',source=self.replacea).count(),1)
self.assertEqual(Document.objects.get(name='draft-test-base-a').get_state().slug,'repl')
@ -2065,7 +2065,7 @@ class ChangeReplacesTests(TestCase):
def test_review_possibly_replaces(self):
replaced = self.basea.docalias.first()
replaced = self.basea
RelatedDocument.objects.create(source=self.replacea, target=replaced,
relationship=DocRelationshipName.objects.get(slug="possibly-replaces"))

View file

@ -74,7 +74,7 @@ class StatusChangeTests(TestCase):
self.assertEqual(status_change.rev,'00')
self.assertEqual(status_change.ad.name,'Areað Irector')
self.assertEqual(status_change.notify,'ipu@ietf.org')
self.assertTrue(status_change.relateddocument_set.filter(relationship__slug='tois',target__docs__name='draft-ietf-random-thing'))
self.assertTrue(status_change.relateddocument_set.filter(relationship__slug='tois',target__name='draft-ietf-random-thing'))
# Verify that it's possible to start a status change without a responsible ad.
r = self.client.post(url,dict(

View file

@ -218,7 +218,7 @@ def needed_ballot_positions(doc, active_positions):
else:
related_set = RelatedDocHistory.objects.none()
for rel in related_set.filter(relationship__slug__in=['tops', 'tois', 'tohist', 'toinf', 'tobcp', 'toexp']):
if (rel.target.document.std_level_id in ['bcp','ps','ds','std']) or (rel.relationship_id in ['tops','tois','tobcp']):
if (rel.target.std_level_id in ['bcp','ps','ds','std']) or (rel.relationship_id in ['tops','tois','tobcp']):
needed = two_thirds_rule(recused=len(recuse))
break
else:
@ -783,7 +783,7 @@ def rebuild_reference_relations(doc, filenames):
errors.append("Too many DocAlias objects found for %s"%ref)
else:
# Don't add references to ourself
if doc != refdoc[0].document:
if doc != refdoc[0]:
RelatedDocument.objects.get_or_create( source=doc, target=refdoc[ 0 ], relationship=DocRelationshipName.objects.get( slug='ref%s' % refType ) )
if unfound:
warnings.append('There were %d references with no matching DocAlias'%len(unfound))
@ -821,26 +821,26 @@ def set_replaces_for_document(request, doc, new_replaces, by, email_subject, com
for d in old_replaces:
if d not in new_replaces:
other_addrs = gather_address_lists('doc_replacement_changed',doc=d.document)
other_addrs = gather_address_lists('doc_replacement_changed',doc=d)
to.update(other_addrs.to)
cc.update(other_addrs.cc)
RelatedDocument.objects.filter(source=doc, target=d, relationship=relationship).delete()
if not RelatedDocument.objects.filter(target=d, relationship=relationship):
s = 'active' if d.document.expires > timezone.now() else 'expired'
d.document.set_state(State.objects.get(type='draft', slug=s))
s = 'active' if d.expires > timezone.now() else 'expired'
d.set_state(State.objects.get(type='draft', slug=s))
for d in new_replaces:
if d not in old_replaces:
other_addrs = gather_address_lists('doc_replacement_changed',doc=d.document)
other_addrs = gather_address_lists('doc_replacement_changed',doc=d)
to.update(other_addrs.to)
cc.update(other_addrs.cc)
RelatedDocument.objects.create(source=doc, target=d, relationship=relationship)
d.document.set_state(State.objects.get(type='draft', slug='repl'))
d.set_state(State.objects.get(type='draft', slug='repl'))
if d.document.stream_id in ('irtf','ise','iab'):
repl_state = State.objects.get(type_id='draft-stream-%s'%d.document.stream_id, slug='repl')
d.document.set_state(repl_state)
events.append(StateDocEvent.objects.create(doc=d.document, rev=d.document.rev, by=by, type='changed_state', desc="Set stream state to Replaced",state_type=repl_state.type, state=repl_state))
if d.stream_id in ('irtf','ise','iab'):
repl_state = State.objects.get(type_id='draft-stream-%s'%d.stream_id, slug='repl')
d.set_state(repl_state)
events.append(StateDocEvent.objects.create(doc=d, rev=d.rev, by=by, type='changed_state', desc="Set stream state to Replaced",state_type=repl_state.type, state=repl_state))
# make sure there are no lingering suggestions duplicating new replacements
RelatedDocument.objects.filter(source=doc, target__in=new_replaces, relationship="possibly-replaces").delete()
@ -910,7 +910,7 @@ def extract_complete_replaces_ancestor_mapping_for_docs(names):
break
relations = ( RelatedDocument.objects.filter(source__name__in=front, relationship="replaces")
.select_related("target").values_list("source__name", "target__docs__name") )
.select_related("target").values_list("source__name", "target__name") )
if not relations:
break
@ -1141,7 +1141,7 @@ def generate_idnits2_rfc_status():
def generate_idnits2_rfcs_obsoleted():
obsdict = defaultdict(list)
for r in RelatedDocument.objects.filter(relationship_id='obs'):
obsdict[int(r.target.document.rfc_number())].append(int(r.source.rfc_number()))
obsdict[int(r.target.rfc_number())].append(int(r.source.rfc_number()))
for k in obsdict:
obsdict[k] = sorted(obsdict[k])
return render_to_string('doc/idnits2-rfcs-obsoleted.txt', context={'obsitems':sorted(obsdict.items())})

View file

@ -144,7 +144,7 @@ def fill_in_document_table_attributes(docs, have_telechat_date=False):
relationship__in=("obs", "updates")).select_related('target')
rel_rfc_aliases = dict([ (a.document.id, re.sub(r"rfc(\d+)", r"RFC \1", a.name, flags=re.IGNORECASE)) 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.id]
if rel.relationship_id == "obs":
l = d.obsoleted_by_list
elif rel.relationship_id == "updates":

View file

@ -953,7 +953,7 @@ def approve_downrefs(request, name):
login = request.user.person
downrefs_to_rfc = [rel for rel in doc.relateddocument_set.all() if rel.is_downref() and not rel.is_approved_downref() and rel.target.document.is_rfc()]
downrefs_to_rfc = [rel for rel in doc.relateddocument_set.all() if rel.is_downref() and not rel.is_approved_downref() and rel.target.is_rfc()]
downrefs_to_rfc_qs = RelatedDocument.objects.filter(pk__in=[r.pk for r in downrefs_to_rfc])
@ -968,12 +968,12 @@ def approve_downrefs(request, name):
c = DocEvent(type="downref_approved", doc=rel.source,
rev=rel.source.rev, by=login)
c.desc = "Downref to RFC %s approved by Last Call for %s-%s" % (
rel.target.document.rfc_number(), rel.source, rel.source.rev)
rel.target.rfc_number(), rel.source, rel.source.rev)
c.save()
c = DocEvent(type="downref_approved", doc=rel.target.document,
rev=rel.target.document.rev, by=login)
c = DocEvent(type="downref_approved", doc=rel.target,
rev=rel.target.rev, by=login)
c.desc = "Downref to RFC %s approved by Last Call for %s-%s" % (
rel.target.document.rfc_number(), rel.source, rel.source.rev)
rel.target.rfc_number(), rel.source, rel.source.rev)
c.save()
return HttpResponseRedirect(doc.get_absolute_url())

View file

@ -113,7 +113,7 @@ def send_conflict_review_ad_changed_email(request, review, event):
by = request.user.person,
event = event,
review = review,
reviewed_doc = review.relateddocument_set.get(relationship__slug='conflrev').target.document,
reviewed_doc = review.relateddocument_set.get(relationship__slug='conflrev').target,
review_url = settings.IDTRACKER_BASE_URL+review.get_absolute_url(),
)
)
@ -128,7 +128,7 @@ def send_conflict_review_started_email(request, review):
cc = addrs.cc,
by = request.user.person,
review = review,
reviewed_doc = review.relateddocument_set.get(relationship__slug='conflrev').target.document,
reviewed_doc = review.relateddocument_set.get(relationship__slug='conflrev').target,
review_url = settings.IDTRACKER_BASE_URL+review.get_absolute_url(),
)
)
@ -137,7 +137,7 @@ def send_conflict_review_started_email(request, review):
addrs = gather_address_lists('conflrev_requested_iana',doc=review).as_strings(compact=False)
email_iana(request,
review.relateddocument_set.get(relationship__slug='conflrev').target.document,
review.relateddocument_set.get(relationship__slug='conflrev').target,
addrs.to,
msg,
cc=addrs.cc)
@ -155,7 +155,7 @@ def send_conflict_eval_email(request,review):
send_mail_preformatted(request,msg,override=override)
addrs = gather_address_lists('ballot_issued_iana',doc=review).as_strings()
email_iana(request,
review.relateddocument_set.get(relationship__slug='conflrev').target.document,
review.relateddocument_set.get(relationship__slug='conflrev').target,
addrs.to,
msg,
addrs.cc)
@ -247,7 +247,7 @@ def submit(request, name):
{'form': form,
'next_rev': next_rev,
'review' : review,
'conflictdoc' : review.relateddocument_set.get(relationship__slug='conflrev').target.document,
'conflictdoc' : review.relateddocument_set.get(relationship__slug='conflrev').target,
})
@role_required("Area Director", "Secretariat")
@ -275,7 +275,7 @@ def edit_ad(request, name):
form = AdForm(initial=init)
conflictdoc = review.relateddocument_set.get(relationship__slug='conflrev').target.document
conflictdoc = review.relateddocument_set.get(relationship__slug='conflrev').target
titletext = 'the conflict review of %s-%s' % (conflictdoc.canonical_name(),conflictdoc.rev)
return render(request, 'doc/change_ad.html',
{'form': form,
@ -287,7 +287,7 @@ def edit_ad(request, name):
def default_approval_text(review):
current_text = review.text_or_error() # pyflakes:ignore
conflictdoc = review.relateddocument_set.get(relationship__slug='conflrev').target.document
conflictdoc = review.relateddocument_set.get(relationship__slug='conflrev').target
if conflictdoc.stream_id=='ise':
receiver = 'Independent Submissions Editor'
elif conflictdoc.stream_id=='irtf':
@ -365,7 +365,7 @@ def approve_conflict_review(request, name):
return render(request, 'doc/conflict_review/approve.html',
dict(
review = review,
conflictdoc = review.relateddocument_set.get(relationship__slug='conflrev').target.document,
conflictdoc = review.relateddocument_set.get(relationship__slug='conflrev').target,
form = form,
))
@ -416,7 +416,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.all() for rel in alias.relateddocument_set.filter(relationship='conflrev') ]:
if [ rel.source for rel in doc_to_review.target.filter(relationship='conflrev') ]: # TODO whould be targets or targets_related
raise Http404
return doc_to_review
@ -452,7 +452,7 @@ def build_conflict_review_document(login, doc_to_review, ad, notify, create_in_s
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')
conflict_review.relateddocument_set.create(target=doc_to_review, relationship_id='conflrev')
c = DocEvent(type="added_comment", doc=conflict_review, rev=conflict_review.rev, by=login)
c.desc = "IETF conflict review requested"

View file

@ -151,8 +151,8 @@ def interesting_doc_relations(doc):
that_doc_relationships = ('replaces', 'possibly_replaces', 'updates', 'obs')
interesting_relations_that = cls.objects.filter(target__docs=target, relationship__in=that_relationships).select_related('source')
interesting_relations_that_doc = cls.objects.filter(source=doc, relationship__in=that_doc_relationships).prefetch_related('target__docs')
interesting_relations_that = cls.objects.filter(target=target, relationship__in=that_relationships).select_related('source')
interesting_relations_that_doc = cls.objects.filter(source=doc, relationship__in=that_doc_relationships).prefetch_related('target')
return interesting_relations_that, interesting_relations_that_doc
@ -656,7 +656,7 @@ def document_main(request, name, rev=None, document_html=False):
if doc.get_state_slug() in ("iesgeval", ) and doc.active_ballot():
ballot_summary = needed_ballot_positions(doc, list(doc.active_ballot().active_balloter_positions().values()))
conflictdoc = doc.related_that_doc('conflrev')[0].document
conflictdoc = doc.related_that_doc('conflrev')[0]
return render(request, "doc/document_conflict_review.html",
dict(doc=doc,
@ -972,8 +972,8 @@ def get_diff_revisions(request, name, doc):
diff_documents = [doc]
diff_documents.extend(
Document.objects.filter(
docalias__relateddocument__source=doc,
docalias__relateddocument__relationship="replaces",
relateddocument__source=doc,
relateddocument__relationship="replaces",
)
)
@ -1538,7 +1538,7 @@ def telechat_date(request, name):
def doc_titletext(doc):
if doc.type.slug=='conflrev':
conflictdoc = doc.relateddocument_set.get(relationship__slug='conflrev').target.document
conflictdoc = doc.relateddocument_set.get(relationship__slug='conflrev').target
return 'the conflict review of %s' % conflictdoc.canonical_name()
return doc.canonical_name()

View file

@ -19,7 +19,7 @@ def downref_registry(request):
downref_doc_pairs = [ ]
downref_relations = RelatedDocument.objects.filter(relationship_id='downref-approval')
for rel in downref_relations:
downref_doc_pairs.append((rel.target.document, rel.source))
downref_doc_pairs.append((rel.target, rel.source))
return render(request, 'doc/downref.html', {
"doc_pairs": downref_doc_pairs,
@ -38,18 +38,18 @@ def downref_registry_add(request):
if form.is_valid():
drafts = form.cleaned_data['drafts']
rfc = form.cleaned_data['rfc']
for da in drafts:
RelatedDocument.objects.create(source=da.document,
for d in drafts:
RelatedDocument.objects.create(source=d,
target=rfc, relationship_id='downref-approval')
c = DocEvent(type="downref_approved", doc=da.document,
rev=da.document.rev, by=login)
c = DocEvent(type="downref_approved", doc=d,
rev=d.rev, by=login)
c.desc = "Downref to RFC %s approved by Last Call for %s-%s" % (
rfc.document.rfc_number(), da.name, da.document.rev)
rfc.rfc_number(), d.name, d.rev)
c.save()
c = DocEvent(type="downref_approved", doc=rfc.document,
rev=rfc.document.rev, by=login)
c = DocEvent(type="downref_approved", doc=rfc,
rev=rfc.rev, by=login)
c.desc = "Downref to RFC %s approved by Last Call for %s-%s" % (
rfc.document.rfc_number(), da.name, da.document.rev)
rfc.rfc_number(), d.name, d.rev)
c.save()
return HttpResponseRedirect(urlreverse('ietf.doc.views_downref.downref_registry'))

View file

@ -38,7 +38,7 @@ from ietf.doc.utils import ( add_state_change_event, can_adopt_draft, can_unadop
set_replaces_for_document, default_consensus, tags_suffix, can_edit_docextresources,
update_doc_extresources )
from ietf.doc.lastcall import request_last_call
from ietf.doc.fields import SearchableDocAliasesField
from ietf.doc.fields import SearchableDocumentsField
from ietf.doc.forms import ExtResourceForm
from ietf.group.models import Group, Role, GroupFeatures
from ietf.iesg.models import TelechatDate
@ -333,7 +333,7 @@ def change_stream(request, name):
))
class ReplacesForm(forms.Form):
replaces = SearchableDocAliasesField(required=False)
replaces = SearchableDocumentsField(required=False)
comment = forms.CharField(widget=forms.Textarea, required=False, strip=False)
def __init__(self, *args, **kwargs):
@ -343,9 +343,9 @@ class ReplacesForm(forms.Form):
def clean_replaces(self):
for d in self.cleaned_data['replaces']:
if d.document == self.doc:
if d == self.doc:
raise forms.ValidationError("An Internet-Draft can't replace itself")
if d.document.type_id == "draft" and d.document.get_state_slug() == "rfc":
if d.type_id == "draft" and d.get_state_slug() == "rfc":
raise forms.ValidationError("An Internet-Draft can't replace an RFC")
return self.cleaned_data['replaces']
@ -383,7 +383,7 @@ def replaces(request, name):
))
class SuggestedReplacesForm(forms.Form):
replaces = forms.ModelMultipleChoiceField(queryset=DocAlias.objects.all(),
replaces = forms.ModelMultipleChoiceField(queryset=Document.objects.all(),
label="Suggestions", required=False, widget=forms.CheckboxSelectMultiple,
help_text="Select only the documents that are replaced by this document")
comment = forms.CharField(label="Optional comment", widget=forms.Textarea, required=False, strip=False)
@ -673,7 +673,7 @@ def edit_info(request, name):
e.save()
events.append(e)
replaces = Document.objects.filter(docalias__relateddocument__source=doc, docalias__relateddocument__relationship="replaces")
replaces = Document.objects.filter(target__source=doc, target__relationship="replaces") # TODO: again target needs to change
if replaces:
# this should perhaps be somewhere else, e.g. the
# place where the replace relationship is established?

View file

@ -98,8 +98,8 @@ def change_state(request, name, option=None):
relationship__slug__in=STATUSCHANGE_RELATIONS
)
related_doc_info = [
dict(title=rel_doc.target.document.title,
canonical_name=rel_doc.target.document.canonical_name(),
dict(title=rel_doc.target.title,
canonical_name=rel_doc.target.canonical_name(),
newstatus=newstatus(rel_doc))
for rel_doc in related_docs
]
@ -309,7 +309,7 @@ def default_approval_text(status_change,relateddoc):
current_text = status_change.text_or_error() # pyflakes:ignore
if relateddoc.target.document.std_level_id in ('std','ps','ds','bcp',):
if relateddoc.target.std_level_id in ('std','ps','ds','bcp',):
action = "Protocol Action"
else:
action = "Document Action"
@ -320,7 +320,7 @@ def default_approval_text(status_change,relateddoc):
dict(status_change=status_change,
status_change_url = settings.IDTRACKER_BASE_URL+status_change.get_absolute_url(),
relateddoc= relateddoc,
relateddoc_url = settings.IDTRACKER_BASE_URL+relateddoc.target.document.get_absolute_url(),
relateddoc_url = settings.IDTRACKER_BASE_URL+relateddoc.target.get_absolute_url(),
approved_text = current_text,
action=action,
newstatus=newstatus(relateddoc),
@ -388,7 +388,7 @@ def approve(request, name):
for rel in status_change.relateddocument_set.filter(relationship__slug__in=STATUSCHANGE_RELATIONS):
# Add a document event to each target
c = DocEvent(type="added_comment", doc=rel.target.document, rev=rel.target.document.rev, by=login)
c = DocEvent(type="added_comment", doc=rel.target, rev=rel.target.rev, by=login)
c.desc = "New status of %s approved by the IESG\n%s%s" % (newstatus(rel), settings.IDTRACKER_BASE_URL,reverse('ietf.doc.views_doc.document_main', kwargs={'name': status_change.name}))
c.save()
@ -399,7 +399,7 @@ def approve(request, name):
init = []
for rel in status_change.relateddocument_set.filter(relationship__slug__in=STATUSCHANGE_RELATIONS):
init.append({"announcement_text" : escape(default_approval_text(status_change,rel)),
"label": "Announcement text for %s to %s"%(rel.target.document.canonical_name(),newstatus(rel)),
"label": "Announcement text for %s to %s"%(rel.target.canonical_name(),newstatus(rel)),
})
formset = AnnouncementFormSet(initial=init)
for form in formset.forms:
@ -605,7 +605,7 @@ def edit_relations(request, name):
old_relations={}
for rel in status_change.relateddocument_set.filter(relationship__slug__in=STATUSCHANGE_RELATIONS):
old_relations[rel.target.document.canonical_name()]=rel.relationship.slug
old_relations[rel.target.canonical_name()]=rel.relationship.slug
new_relations=form.cleaned_data['relations']
status_change.relateddocument_set.filter(relationship__slug__in=STATUSCHANGE_RELATIONS).delete()
for key in new_relations:
@ -626,7 +626,7 @@ def edit_relations(request, name):
else:
relations={}
for rel in status_change.relateddocument_set.filter(relationship__slug__in=STATUSCHANGE_RELATIONS):
relations[rel.target.document.canonical_name()]=rel.relationship.slug
relations[rel.target.canonical_name()]=rel.relationship.slug
init = { "relations":relations,
}
form = EditStatusChangeForm(initial=init)
@ -653,8 +653,8 @@ def generate_last_call_text(request, doc):
settings=settings,
requester=requester,
expiration_date=expiration_date.strftime("%Y-%m-%d"),
changes=['%s from %s to %s\n (%s)'%(rel.target.name.upper(),rel.target.document.std_level.name,newstatus(rel),rel.target.document.title) for rel in doc.relateddocument_set.filter(relationship__slug__in=STATUSCHANGE_RELATIONS)],
urls=[rel.target.document.get_absolute_url() for rel in doc.relateddocument_set.filter(relationship__slug__in=STATUSCHANGE_RELATIONS)],
changes=['%s from %s to %s\n (%s)'%(rel.target.name.upper(),rel.target.std_level.name,newstatus(rel),rel.target.title) for rel in doc.relateddocument_set.filter(relationship__slug__in=STATUSCHANGE_RELATIONS)],
urls=[rel.target.get_absolute_url() for rel in doc.relateddocument_set.filter(relationship__slug__in=STATUSCHANGE_RELATIONS)],
cc=cc
)
)

View file

@ -757,7 +757,7 @@ def dependencies(request, acronym, group_type=None):
relationship__slug__startswith="ref",
)
both_rfcs = Q(source__states__slug="rfc", target__docs__states__slug="rfc")
both_rfcs = Q(source__states__slug="rfc", target__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"])
@ -771,19 +771,19 @@ def dependencies(request, acronym, group_type=None):
links = set()
for x in relations:
target_state = x.target.document.get_state_slug("draft")
target_state = x.target.get_state_slug("draft")
if target_state != "rfc" or x.is_downref():
links.add(x)
replacements = RelatedDocument.objects.filter(
relationship__slug="replaces",
target__docs__in=[x.target.document for x in links],
target__in=[x.target for x in links],
)
for x in replacements:
links.add(x)
nodes = set([x.source for x in links]).union([x.target.document for x in links])
nodes = set([x.source for x in links]).union([x.target for x in links])
graph = {
"nodes": [
{
@ -806,7 +806,7 @@ def dependencies(request, acronym, group_type=None):
"links": [
{
"source": x.source.canonical_name(),
"target": x.target.document.canonical_name(),
"target": x.target.canonical_name(),
"rel": "downref" if x.is_downref() else x.relationship.slug,
}
for x in links

View file

@ -34,7 +34,7 @@ def all_id_txt():
rfc_aliases = dict(DocAlias.objects.filter(name__startswith="rfc",
docs__states=State.objects.get(type="draft", slug="rfc")).values_list("docs__name", "name"))
replacements = dict(RelatedDocument.objects.filter(target__docs__states=State.objects.get(type="draft", slug="repl"),
replacements = dict(RelatedDocument.objects.filter(target__states=State.objects.get(type="draft", slug="repl"),
relationship="replaces").values_list("target__name", "source__name"))
@ -115,7 +115,7 @@ def all_id2_txt():
rfc_aliases = dict(DocAlias.objects.filter(name__startswith="rfc",
docs__states=State.objects.get(type="draft", slug="rfc")).values_list("docs__name", "name"))
replacements = dict(RelatedDocument.objects.filter(target__docs__states=State.objects.get(type="draft", slug="repl"),
replacements = dict(RelatedDocument.objects.filter(target__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__name", "time"))

View file

@ -66,7 +66,7 @@ def get_doc_section(doc):
elif doc.type_id == 'statchg':
protocol_action = False
for relation in doc.relateddocument_set.filter(relationship__slug__in=('tops','tois','tohist','toinf','tobcp','toexp')):
if relation.relationship_id in ('tops','tois') or relation.target.document.std_level_id in ('std','ds','ps'):
if relation.relationship_id in ('tops','tois') or relation.target.std_level_id in ('std','ds','ps'):
protocol_action = True
if protocol_action:
s = "2.3"
@ -186,7 +186,7 @@ def fill_in_agenda_docs(date, sections, docs=None):
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
doc.conflictdoc = doc.relateddocument_set.get(relationship__slug='conflrev').target
elif doc.type_id == "charter":
pass
@ -219,4 +219,4 @@ def agenda_data(date=None):
fill_in_agenda_docs(date, sections)
fill_in_agenda_management_issues(date, sections)
return { 'date': date.isoformat(), 'sections': sections }
return { 'date': date.isoformat(), 'sections': sections }

View file

@ -32,10 +32,10 @@ def telechat_page_count(date=None, docs=None):
pages_for_action += d.pages or 0
elif d.type_id == 'statchg':
for rel in d.related_that_doc(STATUSCHANGE_RELATIONS):
pages_for_action += rel.document.pages or 0
pages_for_action += rel.pages or 0
elif d.type_id == 'conflrev':
for rel in d.related_that_doc('conflrev'):
pages_for_action += rel.document.pages or 0
pages_for_action += rel.pages or 0
else:
pass
@ -43,10 +43,10 @@ def telechat_page_count(date=None, docs=None):
for d in for_approval-set(drafts):
if d.type_id == 'statchg':
for rel in d.related_that_doc(STATUSCHANGE_RELATIONS):
related_pages += rel.document.pages or 0
related_pages += rel.pages or 0
elif d.type_id == 'conflrev':
for rel in d.related_that_doc('conflrev'):
related_pages += rel.document.pages or 0
related_pages += rel.pages or 0
else:
# There's really nothing to rely on to give a reading load estimate for charters
pass

View file

@ -172,7 +172,7 @@ def agenda_json(request, date=None):
elif doc.type_id == 'conflrev':
docinfo['rev'] = doc.rev
td = doc.relateddocument_set.get(relationship__slug='conflrev').target.document
td = doc.relateddocument_set.get(relationship__slug='conflrev').target
docinfo['target-docname'] = td.canonical_name()
docinfo['target-title'] = td.title
docinfo['target-rev'] = td.rev

View file

@ -94,7 +94,7 @@ admin.site.register(IprDocRel, IprDocRelAdmin)
class RelatedIprAdmin(admin.ModelAdmin):
list_display = ['source', 'target', 'relationship', ]
search_fields = ['source__name', 'target__name', 'target__docs__name', ]
search_fields = ['source__name', 'target__name', ]
raw_id_fields = ['source', 'target', ]
admin.site.register(RelatedIpr, RelatedIprAdmin)

View file

@ -41,24 +41,17 @@ def iprs_from_docs(aliases,**kwargs):
iprdocrels += document.ipr(**kwargs)
return list(set([i.disclosure for i in iprdocrels]))
def related_docs(alias, relationship=('replaces', 'obs')):
def related_docs(doc, relationship=('replaces', 'obs')):
"""Returns list of related documents"""
results = []
for doc in alias.docs.all():
results += list(doc.docalias.all())
rels = []
for doc in alias.docs.all():
rels += list(doc.all_relations_that_doc(relationship))
results = [doc]
rels = list(doc.document.all_relations_that_doc(relationship))
for rel in rels:
rel_aliases = list(rel.target.document.docalias.all())
for x in rel_aliases:
x.related = rel
x.relation = rel.relationship.revname
results += rel_aliases
rel.target.related = rel
rel.target.relation = rel.relationship.revname
results += [x.target for x in rels]
return list(set(results))

View file

@ -96,35 +96,35 @@ class Recipient(models.Model):
addrs = []
if 'doc' in kwargs:
for reldoc in kwargs['doc'].related_that_doc(('conflrev','tohist','tois','tops')):
addrs.extend(Recipient.objects.get(slug='doc_authors').gather(**{'doc':reldoc.document}))
addrs.extend(Recipient.objects.get(slug='doc_authors').gather(**{'doc':reldoc}))
return addrs
def gather_doc_affecteddoc_group_chairs(self, **kwargs):
addrs = []
if 'doc' in kwargs:
for reldoc in kwargs['doc'].related_that_doc(('conflrev','tohist','tois','tops')):
addrs.extend(Recipient.objects.get(slug='doc_group_chairs').gather(**{'doc':reldoc.document}))
addrs.extend(Recipient.objects.get(slug='doc_group_chairs').gather(**{'doc':reldoc}))
return addrs
def gather_doc_affecteddoc_notify(self, **kwargs):
addrs = []
if 'doc' in kwargs:
for reldoc in kwargs['doc'].related_that_doc(('conflrev','tohist','tois','tops')):
addrs.extend(Recipient.objects.get(slug='doc_notify').gather(**{'doc':reldoc.document}))
addrs.extend(Recipient.objects.get(slug='doc_notify').gather(**{'doc':reldoc}))
return addrs
def gather_conflict_review_stream_manager(self, **kwargs):
addrs = []
if 'doc' in kwargs:
for reldoc in kwargs['doc'].related_that_doc(('conflrev',)):
addrs.extend(Recipient.objects.get(slug='doc_stream_manager').gather(**{'doc':reldoc.document}))
addrs.extend(Recipient.objects.get(slug='doc_stream_manager').gather(**{'doc':reldoc}))
return addrs
def gather_conflict_review_steering_group(self,**kwargs):
addrs = []
if 'doc' in kwargs:
for reldoc in kwargs['doc'].related_that_doc(('conflrev',)):
if reldoc.document.stream_id=='irtf':
if reldoc.stream_id=='irtf':
addrs.append('"Internet Research Steering Group" <irsg@irtf.org>')
return addrs

View file

@ -313,7 +313,7 @@ def doc_detail(request, date, name):
# if this is a conflict review document add referenced document
if doc.type_id == 'conflrev':
conflictdoc = doc.relateddocument_set.get(relationship__slug='conflrev').target.document
conflictdoc = doc.relateddocument_set.get(relationship__slug='conflrev').target
else:
conflictdoc = None

View file

@ -85,13 +85,13 @@
{% if downrefs %}
<h2 id="downrefs">Downward References</h2>
{% for ref in downrefs %}
<p>Add {{ref.target.document.canonical_name}}
({{ref.target.document.std_level}} - {{ref.target.document.stream.desc}})
<p>Add {{ref.target.canonical_name}}
({{ref.target.std_level}} - {{ref.target.stream.desc}})
to downref registry.<br>
{% if not ref.target.document.std_level %}
{% if not ref.target.std_level %}
+++ Warning: The standards level has not been set yet!!!<br>
{% endif %}
{% if not ref.target.document.stream %}
{% if not ref.target.stream %}
+++ Warning: document stream has not been set yet!!!<br>
{% endif %}
{% endfor %}</p>

View file

@ -35,7 +35,7 @@
<a href="{% url 'ietf.doc.views_doc.document_main' name=name %}">{{ name|prettystdname }}</a>
</td>
<td>
<b>{{ ref.target.document.title }}</b>
<b>{{ ref.target.title }}</b>
<br>
<a class="btn btn-primary btn-sm"
href="{% url 'ietf.doc.views_doc.document_references' name %}"
@ -51,12 +51,12 @@
</a>
</td>
<td>
{% if ref.target.document.get_state.slug == 'rfc' %}
{% with ref.target.document.std_level as lvl %}
{% if ref.target.get_state.slug == 'rfc' %}
{% with ref.target.std_level as lvl %}
{% if lvl %}{{ lvl }}{% endif %}
{% endwith %}
{% else %}
{% with ref.target.document.intended_std_level as lvl %}
{% with ref.target.intended_std_level as lvl %}
{% if lvl %}{{ lvl }}{% endif %}
{% endwith %}
{% endif %}

View file

@ -52,7 +52,7 @@
<td class="edit"></td>
<td>
{% for rel in relation_group.list %}
{{ rel.target.document.canonical_name|upper|urlize_ietf_docs }}{% if not forloop.last %},{% endif %}
{{ rel.target.canonical_name|upper|urlize_ietf_docs }}{% if not forloop.last %},{% endif %}
{% endfor %}
</td>
</tr>

View file

@ -33,7 +33,7 @@ No IPR declarations have been submitted directly on this I-D.
{% if downrefs %}
The document contains these normative downward references.
See RFC 3967 for additional information:
{% for ref in downrefs %} {{ref.target.document.canonical_name}}: {{ref.target.document.title}} ({{ref.target.document.std_level}} - {{ref.target.document.stream.desc}})
{% for ref in downrefs %} {{ref.target.canonical_name}}: {{ref.target.title}} ({{ref.target.std_level}} - {{ref.target.stream.desc}})
{% endfor %}{%endif%}
{% endautoescape %}

View file

@ -1,11 +1,11 @@
{% load ietf_filters %}{% load mail_filters %}{% autoescape off %}From: The IESG <iesg-secretary@ietf.org>
To: {{ to }}{% if cc %}
Cc: {{ cc }}{% endif %}
Subject: {{action}}: {{relateddoc.target.document.title}} to {{newstatus}}
Subject: {{action}}: {{relateddoc.target.title}} to {{newstatus}}
{% filter wordwrap:78 %}The IESG has approved changing the status of the following document:
- {{relateddoc.target.document.title }}
({{relateddoc.target.document.canonical_name }}) to {{ newstatus }}
- {{relateddoc.target.title }}
({{relateddoc.target.canonical_name }}) to {{ newstatus }}
This {{action|lower}} is documented at:
{{status_change_url}}

View file

@ -165,13 +165,13 @@ Parts Copyright (c) 2009 The IETF Trust, all rights reserved.
{% if downrefs %}
<p>If APPROVED - The Secretariat will add to the downref registry:<br>
{% for ref in downrefs %}
+ Add {{ref.target.document.canonical_name}}
({{ref.target.document.std_level}} - {{ref.target.document.stream.desc}})
+ Add {{ref.target.canonical_name}}
({{ref.target.std_level}} - {{ref.target.stream.desc}})
to downref registry.<br>
{% if not ref.target.document.std_level %}
{% if not ref.target.std_level %}
+++ Warning: The standards level has not been set yet!!!<br>
{% endif %}
{% if not ref.target.document.stream %}
{% if not ref.target.stream %}
+++ Warning: document stream has not been set yet!!!<br>
{% endif %}
{% endfor %}</p>