chore: checkpoint: halfway through removing docalias

This commit is contained in:
Robert Sparks 2023-08-15 09:11:53 -05:00
parent a867de25b0
commit 4946430159
No known key found for this signature in database
GPG key ID: 6E2A6A5775F91318
49 changed files with 8623 additions and 8682 deletions

File diff suppressed because it is too large Load diff

View file

@ -60,7 +60,7 @@ def reset_name_contains_index_for_rule(rule):
if not rule.rule_type == "name_contains": if not rule.rule_type == "name_contains":
return return
rule.name_contains_index.set(Document.objects.filter(docalias__name__regex=rule.text)) rule.name_contains_index.set(Document.objects.filter(name__regex=rule.text))
def update_name_contains_indexes_with_new_doc(doc): def update_name_contains_indexes_with_new_doc(doc):
for r in SearchRule.objects.filter(rule_type="name_contains"): for r in SearchRule.objects.filter(rule_type="name_contains"):
@ -182,7 +182,7 @@ def docs_tracked_by_community_list(clist):
doc_ids = set() doc_ids = set()
for doc in clist.added_docs.all(): for doc in clist.added_docs.all():
doc_ids.add(doc.pk) doc_ids.add(doc.pk)
doc_ids.update(alias.docs.first().pk for alias in doc.related_that_doc("became_rfc")) doc_ids.update(rfc.pk for rfc in doc.related_that_doc("became_rfc"))
for rule in clist.searchrule_set.all(): for rule in clist.searchrule_set.all():
doc_ids = doc_ids | set(docs_matching_community_list_rule(rule).values_list("pk", flat=True)) doc_ids = doc_ids | set(docs_matching_community_list_rule(rule).values_list("pk", flat=True))

View file

@ -129,7 +129,7 @@ def manage_list(request, username=None, acronym=None, group_type=None):
@login_required @login_required
def track_document(request, name, username=None, acronym=None): def track_document(request, name, username=None, acronym=None):
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
if request.method == "POST": if request.method == "POST":
clist = lookup_community_list(username, acronym) clist = lookup_community_list(username, acronym)
@ -153,7 +153,7 @@ def track_document(request, name, username=None, acronym=None):
@login_required @login_required
def untrack_document(request, name, username=None, acronym=None): def untrack_document(request, name, username=None, acronym=None):
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
clist = lookup_community_list(username, acronym) clist = lookup_community_list(username, acronym)
if not can_manage_community_list(request.user, clist): if not can_manage_community_list(request.user, clist):
permission_denied(request, "You do not have permission to access this view") permission_denied(request, "You do not have permission to access this view")

View file

@ -52,15 +52,6 @@ class BaseDocumentFactory(factory.django.DjangoModelFactory):
newrevisiondocevent = factory.RelatedFactory('ietf.doc.factories.NewRevisionDocEventFactory','doc') newrevisiondocevent = factory.RelatedFactory('ietf.doc.factories.NewRevisionDocEventFactory','doc')
@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 name in extracted:
alias = DocAliasFactory(name=name)
alias.docs.add(obj)
@factory.post_generation @factory.post_generation
def states(obj, create, extracted, **kwargs): # pylint: disable=no-self-argument def states(obj, create, extracted, **kwargs): # pylint: disable=no-self-argument
if create and extracted: if create and extracted:

View file

@ -36,7 +36,7 @@ class DocumentChangesFeed(Feed):
feed_type = Atom1Feed feed_type = Atom1Feed
def get_object(self, request, name): def get_object(self, request, name):
return Document.objects.get(docalias__name=name) return Document.objects.get(name=name)
def title(self, obj): def title(self, obj):
return "Changes for %s" % obj.display_name() return "Changes for %s" % obj.display_name()

View file

@ -13,7 +13,7 @@ from django.urls import reverse as urlreverse
import debug # pyflakes:ignore import debug # pyflakes:ignore
from ietf.doc.models import Document, DocAlias from ietf.doc.models import Document
from ietf.doc.utils import uppercase_std_abbreviated_name from ietf.doc.utils import uppercase_std_abbreviated_name
from ietf.utils.fields import SearchableField from ietf.utils.fields import SearchableField
@ -69,19 +69,3 @@ class SearchableDocumentsField(SearchableField):
class SearchableDocumentField(SearchableDocumentsField): class SearchableDocumentField(SearchableDocumentsField):
"""Specialized to only return one Document""" """Specialized to only return one Document"""
max_entries = 1 max_entries = 1
class SearchableDocAliasesField(SearchableDocumentsField):
"""Search DocAliases instead of Documents"""
model = DocAlias # type: Type[models.Model]
def doc_type_filter(self, queryset):
"""Filter to include only desired doc type
For DocAlias, pass through to the docs to check type.
"""
return queryset.filter(docs__type=self.doc_type)
class SearchableDocAliasField(SearchableDocAliasesField):
"""Specialized to only return one DocAlias"""
max_entries = 1

View file

@ -19,7 +19,7 @@ from ietf.doc.templatetags.mail_filters import std_level_prompt
from ietf.utils import log from ietf.utils import log
from ietf.utils.mail import send_mail, send_mail_text from ietf.utils.mail import send_mail, send_mail_text
from ietf.ipr.utils import iprs_from_docs, related_docs from ietf.ipr.utils import iprs_from_docs, related_docs
from ietf.doc.models import WriteupDocEvent, LastCallDocEvent, DocAlias, ConsensusDocEvent from ietf.doc.models import WriteupDocEvent, LastCallDocEvent, ConsensusDocEvent
from ietf.doc.utils import needed_ballot_positions from ietf.doc.utils import needed_ballot_positions
from ietf.doc.utils_bofreq import bofreq_editors, bofreq_responsible from ietf.doc.utils_bofreq import bofreq_editors, bofreq_responsible
from ietf.group.models import Role from ietf.group.models import Role
@ -202,7 +202,7 @@ def generate_last_call_announcement(request, doc):
doc.filled_title = textwrap.fill(doc.title, width=70, subsequent_indent=" " * 3) doc.filled_title = textwrap.fill(doc.title, width=70, subsequent_indent=" " * 3)
iprs = iprs_from_docs(related_docs(DocAlias.objects.get(name=doc.canonical_name()))) iprs = iprs_from_docs(related_docs(Document.objects.get(name=doc.canonical_name())))
if iprs: if iprs:
ipr_links = [ urlreverse("ietf.ipr.views.show", kwargs=dict(id=i.id)) for i in iprs] ipr_links = [ urlreverse("ietf.ipr.views.show", kwargs=dict(id=i.id)) for i in iprs]
ipr_links = [ settings.IDTRACKER_BASE_URL+url if not url.startswith("http") else url for url in ipr_links ] ipr_links = [ settings.IDTRACKER_BASE_URL+url if not url.startswith("http") else url for url in ipr_links ]
@ -670,7 +670,7 @@ def send_review_possibly_replaces_request(request, doc, submitter_info):
to = set(addrs.to) to = set(addrs.to)
cc = set(addrs.cc) cc = set(addrs.cc)
possibly_replaces = Document.objects.filter(name__in=[alias.name for alias in doc.related_that_doc("possibly-replaces")]) possibly_replaces = Document.objects.filter(name__in=[related.name for related in doc.related_that_doc("possibly-replaces")])
for other_doc in possibly_replaces: for other_doc in possibly_replaces:
(other_to, other_cc) = gather_address_lists('doc_replacement_suggested',doc=other_doc) (other_to, other_cc) = gather_address_lists('doc_replacement_suggested',doc=other_doc)
to.update(other_to) to.update(other_to)

View file

@ -355,7 +355,7 @@ class DocumentInfo(models.Model):
elif state.slug == "repl": elif state.slug == "repl":
rs = self.related_that("replaces") rs = self.related_that("replaces")
if rs: 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.name)), 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=related.name)), related) for related in rs))
else: else:
return "Replaced" return "Replaced"
elif state.slug == "active": elif state.slug == "active":
@ -493,10 +493,10 @@ class DocumentInfo(models.Model):
return related return related
def related_that(self, relationship): def related_that(self, relationship):
return list(set([x.source.docalias.get(name=x.source.name) for x in self.relations_that(relationship)])) return list(set([x.source for x in self.relations_that(relationship)]))
def all_related_that(self, relationship, related=None): def all_related_that(self, relationship, related=None):
return list(set([x.source.docalias.get(name=x.source.name) for x in self.all_relations_that(relationship)])) return list(set([x.source for x in self.all_relations_that(relationship)]))
def related_that_doc(self, relationship): def related_that_doc(self, relationship):
return list(set([x.target for x in self.relations_that_doc(relationship)])) return list(set([x.target for x in self.relations_that_doc(relationship)]))
@ -843,20 +843,6 @@ class Document(DocumentInfo):
e = model.objects.filter(doc=self).filter(**filter_args).order_by('-time', '-id').first() e = model.objects.filter(doc=self).filter(**filter_args).order_by('-time', '-id').first()
return e return e
def canonical_name(self):
if not hasattr(self, '_canonical_name'):
name = self.name
if self.type_id == "draft" and self.get_state_slug() == "rfc":
a = self.docalias.filter(name__startswith="rfc").order_by('-name').first()
if a:
name = a.name
self._canonical_name = name
return self._canonical_name
def canonical_docalias(self):
return self.docalias.get(name=self.name)
def display_name(self): def display_name(self):
name = self.canonical_name() name = self.canonical_name()
if name.startswith('rfc'): if name.startswith('rfc'):
@ -963,8 +949,8 @@ class Document(DocumentInfo):
from ietf.ipr.models import IprDocRel from ietf.ipr.models import IprDocRel
iprs = ( iprs = (
IprDocRel.objects.filter( IprDocRel.objects.filter(
document__in=list(self.docalias.all()) document__in=list(self)
+ [x.docalias.first() for x in self.all_related_that_doc(("obs", "replaces"))] # this really is docalias until IprDocRel changes + self.all_related_that_doc(("obs", "replaces"))
) )
.filter(disclosure__state__in=("posted", "removed")) .filter(disclosure__state__in=("posted", "removed"))
.values_list("disclosure", flat=True) .values_list("disclosure", flat=True)
@ -1157,10 +1143,6 @@ class DocHistory(DocumentInfo):
def groupmilestone_set(self): def groupmilestone_set(self):
return self.doc.groupmilestone_set return self.doc.groupmilestone_set
@property
def docalias(self):
return self.doc.docalias
def is_dochistory(self): def is_dochistory(self):
return True return True

View file

@ -490,7 +490,7 @@ api.doc.register(BallotDocEventResource())
from ietf.name.resources import DocRelationshipNameResource from ietf.name.resources import DocRelationshipNameResource
class RelatedDocumentResource(ModelResource): class RelatedDocumentResource(ModelResource):
source = ToOneField(DocumentResource, 'source') source = ToOneField(DocumentResource, 'source')
target = ToOneField(DocAliasResource, 'target') target = ToOneField(DocumentResource, 'target')
relationship = ToOneField(DocRelationshipNameResource, 'relationship') relationship = ToOneField(DocRelationshipNameResource, 'relationship')
class Meta: class Meta:
cache = SimpleCache() cache = SimpleCache()
@ -509,7 +509,7 @@ api.doc.register(RelatedDocumentResource())
from ietf.name.resources import DocRelationshipNameResource from ietf.name.resources import DocRelationshipNameResource
class RelatedDocHistoryResource(ModelResource): class RelatedDocHistoryResource(ModelResource):
source = ToOneField(DocHistoryResource, 'source') source = ToOneField(DocHistoryResource, 'source')
target = ToOneField(DocAliasResource, 'target') target = ToOneField(DocumentResource, 'target')
relationship = ToOneField(DocRelationshipNameResource, 'relationship') relationship = ToOneField(DocRelationshipNameResource, 'relationship')
class Meta: class Meta:
cache = SimpleCache() cache = SimpleCache()

View file

@ -22,7 +22,7 @@ from django.utils import timezone
import debug # pyflakes:ignore import debug # pyflakes:ignore
from ietf.doc.models import BallotDocEvent, DocAlias from ietf.doc.models import BallotDocEvent, Document
from ietf.doc.models import ConsensusDocEvent from ietf.doc.models import ConsensusDocEvent
from ietf.ietfauth.utils import can_request_rfc_publication as utils_can_request_rfc_publication from ietf.ietfauth.utils import can_request_rfc_publication as utils_can_request_rfc_publication
from ietf.utils.html import sanitize_fragment from ietf.utils.html import sanitize_fragment
@ -146,8 +146,9 @@ def doc_canonical_name(name):
key = hash(n) key = hash(n)
found = cache.get(key) found = cache.get(key)
if not found: if not found:
exact = DocAlias.objects.filter(name=n).first() exact = Document.objects.filter(name=n)
found = exact.name if exact else "_" found = exact.name if exact else "_"
# TODO review this cache policy (and the need for these entire function)
cache.set(key, found, timeout=60*60*24) # cache for one day cache.set(key, found, timeout=60*60*24) # cache for one day
return None if found == "_" else found return None if found == "_" else found

View file

@ -8,7 +8,7 @@ from ietf.doc.factories import (
CharterFactory, CharterFactory,
NewRevisionDocEventFactory, NewRevisionDocEventFactory,
) )
from ietf.doc.models import State, DocEvent, DocAlias from ietf.doc.models import State, DocEvent, Document
from ietf.doc.templatetags.ietf_filters import urlize_ietf_docs, is_valid_url from ietf.doc.templatetags.ietf_filters import urlize_ietf_docs, is_valid_url
from ietf.person.models import Person from ietf.person.models import Person
from ietf.utils.test_utils import TestCase from ietf.utils.test_utils import TestCase
@ -25,23 +25,21 @@ class IetfFiltersTests(TestCase):
self.assertEqual(is_valid_url(url), result) self.assertEqual(is_valid_url(url), result)
def test_urlize_ietf_docs(self): def test_urlize_ietf_docs(self):
wg_id = WgDraftFactory() rfc = WgDraftFactory(rfc_number=123456,std_level_id="bcp")
wg_id.set_state(State.objects.get(type="draft", slug="rfc")) rfc.save_with_history(
wg_id.std_level_id = "bcp"
wg_id.save_with_history(
[ [
DocEvent.objects.create( DocEvent.objects.create(
doc=wg_id, doc=rfc,
rev=wg_id.rev, rev=rfc.rev,
type="published_rfc", type="published_rfc",
by=Person.objects.get(name="(System)"), by=Person.objects.get(name="(System)"),
) )
] ]
) )
DocAlias.objects.create(name="rfc123456").docs.add(wg_id) # TODO - bring these into existance when subseries are well modeled
DocAlias.objects.create(name="bcp123456").docs.add(wg_id) # DocAlias.objects.create(name="bcp123456").docs.add(rfc)
DocAlias.objects.create(name="std123456").docs.add(wg_id) # DocAlias.objects.create(name="std123456").docs.add(rfc)
DocAlias.objects.create(name="fyi123456").docs.add(wg_id) # DocAlias.objects.create(name="fyi123456").docs.add(rfc)
id = IndividualDraftFactory(name="draft-me-rfc123456bis") id = IndividualDraftFactory(name="draft-me-rfc123456bis")
id_num = IndividualDraftFactory(name="draft-rosen-rfcefdp-update-2026") id_num = IndividualDraftFactory(name="draft-rosen-rfcefdp-update-2026")
@ -67,7 +65,7 @@ class IetfFiltersTests(TestCase):
), ),
("rfc123456", '<a href="/doc/rfc123456/">rfc123456</a>'), ("rfc123456", '<a href="/doc/rfc123456/">rfc123456</a>'),
("Rfc 0123456", '<a href="/doc/rfc123456/">Rfc 0123456</a>'), ("Rfc 0123456", '<a href="/doc/rfc123456/">Rfc 0123456</a>'),
(wg_id.name, f'<a href="/doc/{wg_id.name}/">{wg_id.name}</a>'), (rfc.name, f'<a href="/doc/{rfc.name}/">{rfc.name}</a>'),
( (
f"{id.name}-{id.rev}.txt", f"{id.name}-{id.rev}.txt",
f'<a href="/doc/{id.name}/{id.rev}/">{id.name}-{id.rev}.txt</a>', f'<a href="/doc/{id.name}/{id.rev}/">{id.name}-{id.rev}.txt</a>',

View file

@ -33,7 +33,7 @@ from tastypie.test import ResourceTestCaseMixin
import debug # pyflakes:ignore import debug # pyflakes:ignore
from ietf.doc.models import ( Document, DocAlias, DocRelationshipName, RelatedDocument, State, from ietf.doc.models import ( Document, DocRelationshipName, RelatedDocument, State,
DocEvent, BallotPositionDocEvent, LastCallDocEvent, WriteupDocEvent, NewRevisionDocEvent, BallotType, DocEvent, BallotPositionDocEvent, LastCallDocEvent, WriteupDocEvent, NewRevisionDocEvent, BallotType,
EditedAuthorsDocEvent ) EditedAuthorsDocEvent )
from ietf.doc.factories import ( DocumentFactory, DocEventFactory, CharterFactory, from ietf.doc.factories import ( DocumentFactory, DocEventFactory, CharterFactory,
@ -324,7 +324,6 @@ class SearchTests(TestCase):
draft.set_state(State.objects.get(type='draft-iesg', slug='lc')) draft.set_state(State.objects.get(type='draft-iesg', slug='lc'))
rfc = IndividualDraftFactory(ad=ad) rfc = IndividualDraftFactory(ad=ad)
rfc.set_state(State.objects.get(type='draft', slug='rfc')) rfc.set_state(State.objects.get(type='draft', slug='rfc'))
DocAlias.objects.create(name='rfc6666').docs.add(rfc)
conflrev = DocumentFactory(type_id='conflrev',ad=ad) conflrev = DocumentFactory(type_id='conflrev',ad=ad)
conflrev.set_state(State.objects.get(type='conflrev', slug='iesgeval')) conflrev.set_state(State.objects.get(type='conflrev', slug='iesgeval'))
statchg = DocumentFactory(type_id='statchg',ad=ad) statchg = DocumentFactory(type_id='statchg',ad=ad)
@ -415,19 +414,6 @@ class SearchTests(TestCase):
data = r.json() data = r.json()
self.assertEqual(data[0]["id"], draft.pk) self.assertEqual(data[0]["id"], draft.pk)
# DocAlias
doc_alias = draft.docalias.first()
url = urlreverse('ietf.doc.views_search.ajax_select2_search_docs', kwargs={
"model_name": "docalias",
"doc_type": "draft",
})
r = self.client.get(url, dict(q=doc_alias.name))
self.assertEqual(r.status_code, 200)
data = r.json()
self.assertEqual(data[0]["id"], doc_alias.pk)
def test_recent_drafts(self): def test_recent_drafts(self):
# Three drafts to show with various warnings # Three drafts to show with various warnings
drafts = WgDraftFactory.create_batch(3,states=[('draft','active'),('draft-iesg','ad-eval')]) drafts = WgDraftFactory.create_batch(3,states=[('draft','active'),('draft-iesg','ad-eval')])

View file

@ -18,7 +18,7 @@ from django.utils import timezone
from ietf.group.factories import RoleFactory from ietf.group.factories import RoleFactory
from ietf.doc.factories import BofreqFactory, NewRevisionDocEventFactory from ietf.doc.factories import BofreqFactory, NewRevisionDocEventFactory
from ietf.doc.models import State, Document, DocAlias, NewRevisionDocEvent from ietf.doc.models import State, Document, NewRevisionDocEvent
from ietf.doc.utils_bofreq import bofreq_editors, bofreq_responsible from ietf.doc.utils_bofreq import bofreq_editors, bofreq_responsible
from ietf.ietfauth.utils import has_role from ietf.ietfauth.utils import has_role
from ietf.person.factories import PersonFactory from ietf.person.factories import PersonFactory
@ -366,7 +366,6 @@ This test section has some text.
name = f"bofreq-{xslugify(nobody.last_name())[:64]}-{postdict['title']}".replace(' ','-') name = f"bofreq-{xslugify(nobody.last_name())[:64]}-{postdict['title']}".replace(' ','-')
bofreq = Document.objects.filter(name=name,type_id='bofreq').first() bofreq = Document.objects.filter(name=name,type_id='bofreq').first()
self.assertIsNotNone(bofreq) self.assertIsNotNone(bofreq)
self.assertIsNotNone(DocAlias.objects.filter(name=name).first())
self.assertEqual(bofreq.title, postdict['title']) self.assertEqual(bofreq.title, postdict['title'])
self.assertEqual(bofreq.rev, '00') self.assertEqual(bofreq.rev, '00')
self.assertEqual(bofreq.get_state_slug(), 'proposed') self.assertEqual(bofreq.get_state_slug(), 'proposed')

View file

@ -19,11 +19,8 @@ class Downref(TestCase):
super().setUp() super().setUp()
PersonFactory(name='Plain Man',user__username='plain') PersonFactory(name='Plain Man',user__username='plain')
self.draft = WgDraftFactory(name='draft-ietf-mars-test') self.draft = WgDraftFactory(name='draft-ietf-mars-test')
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.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(rfc_number=9998) self.rfc = WgRfcFactory(rfc_number=9998)
self.rfcalias = self.rfc.docalias.get(name='rfc9998')
RelatedDocument.objects.create(source=self.doc, target=self.rfc, relationship_id='downref-approval') RelatedDocument.objects.create(source=self.doc, target=self.rfc, relationship_id='downref-approval')
def test_downref_registry(self): def test_downref_registry(self):

View file

@ -15,7 +15,7 @@ from django.conf import settings
from django.urls import reverse as urlreverse from django.urls import reverse as urlreverse
from django.utils import timezone from django.utils import timezone
from ietf.doc.models import Document, State, DocAlias, NewRevisionDocEvent from ietf.doc.models import Document, State, NewRevisionDocEvent
from ietf.group.factories import RoleFactory from ietf.group.factories import RoleFactory
from ietf.group.models import Group from ietf.group.models import Group
from ietf.meeting.factories import MeetingFactory, SessionFactory from ietf.meeting.factories import MeetingFactory, SessionFactory
@ -54,7 +54,6 @@ class GroupMaterialTests(TestCase):
doc = Document.objects.create(name="slides-testteam-test-file", rev="01", type_id="slides", group=group) 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="slides", slug="active"))
doc.set_state(State.objects.get(type="reuse_policy", slug="multiple")) doc.set_state(State.objects.get(type="reuse_policy", slug="multiple"))
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='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') NewRevisionDocEvent.objects.create(doc=doc,by=Person.objects.get(name="(System)"),rev='01',type='new_revision',desc='New revision available')

View file

@ -12,7 +12,7 @@ from django.template.loader import render_to_string
from django.urls import reverse as urlreverse from django.urls import reverse as urlreverse
from ietf.doc.factories import StatementFactory, DocEventFactory from ietf.doc.factories import StatementFactory, DocEventFactory
from ietf.doc.models import Document, DocAlias, State, NewRevisionDocEvent from ietf.doc.models import Document, State, NewRevisionDocEvent
from ietf.group.models import Group from ietf.group.models import Group
from ietf.person.factories import PersonFactory from ietf.person.factories import PersonFactory
from ietf.utils.mail import outbox, empty_outbox from ietf.utils.mail import outbox, empty_outbox
@ -241,7 +241,6 @@ This test section has some text.
name=name, type_id="statement" name=name, type_id="statement"
).first() ).first()
self.assertIsNotNone(statement) self.assertIsNotNone(statement)
self.assertIsNotNone(DocAlias.objects.filter(name=name).first())
self.assertEqual(statement.title, postdict["title"]) self.assertEqual(statement.title, postdict["title"])
self.assertEqual(statement.rev, "00") self.assertEqual(statement.rev, "00")
self.assertEqual(statement.get_state_slug(), "active") self.assertEqual(statement.get_state_slug(), "active")

View file

@ -90,7 +90,7 @@ urlpatterns = [
url(r'^all/?$', views_search.index_all_drafts), url(r'^all/?$', views_search.index_all_drafts),
url(r'^active/?$', views_search.index_active_drafts), url(r'^active/?$', views_search.index_active_drafts),
url(r'^recent/?$', views_search.recent_drafts), url(r'^recent/?$', views_search.recent_drafts),
url(r'^select2search/(?P<model_name>(document|docalias))/(?P<doc_type>draft)/$', views_search.ajax_select2_search_docs), url(r'^select2search/(?P<model_name>document)/(?P<doc_type>draft)/$', views_search.ajax_select2_search_docs),
url(r'^ballots/irsg/$', views_ballot.irsg_ballot_status), url(r'^ballots/irsg/$', views_ballot.irsg_ballot_status),
url(r'^ballots/rsab/$', views_ballot.rsab_ballot_status), url(r'^ballots/rsab/$', views_ballot.rsab_ballot_status),

View file

@ -775,7 +775,6 @@ def rebuild_reference_relations(doc, filenames):
if not refdoc and re.match(r"^draft-.*-\d{2}$", ref): if not refdoc and re.match(r"^draft-.*-\d{2}$", ref):
refdoc = Document.objects.filter(name=ref[:-3]) refdoc = Document.objects.filter(name=ref[:-3])
count = refdoc.count() count = refdoc.count()
# As of Dec 2021, DocAlias has a unique constraint on the name field, so count > 1 should not occur
if count == 0: if count == 0:
unfound.add( "%s" % ref ) unfound.add( "%s" % ref )
continue continue
@ -933,22 +932,20 @@ def make_rev_history(doc):
if predecessors is None: if predecessors is None:
predecessors = [] predecessors = []
if hasattr(doc, 'relateddocument_set'): if hasattr(doc, 'relateddocument_set'):
for alias in doc.related_that_doc('replaces'): for document in in doc.related_that_doc('replaces'):
for document in alias.docs.all(): if document not in predecessors:
if document not in predecessors: predecessors.append(document)
predecessors.append(document) predecessors.extend(get_predecessors(document, predecessors))
predecessors.extend(get_predecessors(document, predecessors))
return predecessors return predecessors
def get_ancestors(doc, ancestors = None): def get_ancestors(doc, ancestors = None):
if ancestors is None: if ancestors is None:
ancestors = [] ancestors = []
if hasattr(doc, 'relateddocument_set'): if hasattr(doc, 'relateddocument_set'):
for alias in doc.related_that('replaces'): for document in doc.related_that('replaces'):
for document in alias.docs.all(): if document not in ancestors:
if document not in ancestors: ancestors.append(document)
ancestors.append(document) ancestors.extend(get_ancestors(document, ancestors))
ancestors.extend(get_ancestors(document, ancestors))
return ancestors return ancestors
def get_replaces_tree(doc): def get_replaces_tree(doc):
@ -1120,6 +1117,9 @@ def generate_idnits2_rfc_status():
# Workarounds for unusual states in the datatracker # Workarounds for unusual states in the datatracker
# The explanation for 6312 is from before docalias was removed
# The workaround is still needed, even if the datatracker
# state no longer matches what's described here:
# Document.get(docalias='rfc6312').rfc_number == 6342 # Document.get(docalias='rfc6312').rfc_number == 6342
# 6312 was published with the wrong rfc number in it # 6312 was published with the wrong rfc number in it
# weird workaround in the datatracker - there are two # weird workaround in the datatracker - there are two
@ -1177,12 +1177,12 @@ def fuzzy_find_documents(name, rev=None):
sought_type = "draft" sought_type = "draft"
# see if we can find a document using this name # see if we can find a document using this name
docs = Document.objects.filter(docalias__name=name, type_id=sought_type) docs = Document.objects.filter(name=name, type_id=sought_type)
if rev and not docs.exists(): if rev and not docs.exists():
# No document found, see if the name/rev split has been misidentified. # No document found, see if the name/rev split has been misidentified.
# Handles some special cases, like draft-ietf-tsvwg-ieee-802-11. # Handles some special cases, like draft-ietf-tsvwg-ieee-802-11.
name = '%s-%s' % (name, rev) name = '%s-%s' % (name, rev)
docs = Document.objects.filter(docalias__name=name, type_id='draft') docs = Document.objects.filter(name=name, type_id='draft')
if docs.exists(): if docs.exists():
rev = None # found a doc by name with rev = None, so update that rev = None # found a doc by name with rev = None, so update that

View file

@ -9,7 +9,7 @@ from zoneinfo import ZoneInfo
from django.conf import settings from django.conf import settings
from ietf.doc.models import Document, DocAlias, RelatedDocument, DocEvent, TelechatDocEvent, BallotDocEvent from ietf.doc.models import Document, RelatedDocument, DocEvent, TelechatDocEvent, BallotDocEvent
from ietf.doc.expire import expirable_drafts from ietf.doc.expire import expirable_drafts
from ietf.doc.utils import augment_docs_and_user_with_user_info from ietf.doc.utils import augment_docs_and_user_with_user_info
from ietf.meeting.models import SessionPresentation, Meeting, Session from ietf.meeting.models import SessionPresentation, Meeting, Session
@ -54,12 +54,13 @@ def fill_in_document_sessions(docs, doc_dict, doc_ids):
def fill_in_document_table_attributes(docs, have_telechat_date=False): def fill_in_document_table_attributes(docs, have_telechat_date=False):
# fill in some attributes for the document table results to save # fill in some attributes for the document table results to save
# some hairy template code and avoid repeated SQL queries # some hairy template code and avoid repeated SQL queries
# TODO - this function evolved from something that assumed it was handling only drafts. It still has places where it assumes all docs are drafts where that is not a correct assumption # TODO - this function evolved from something that assumed it was handling only drafts.
# It still has places where it assumes all docs are drafts where that is not a correct assumption
doc_dict = dict((d.pk, d) for d in docs) doc_dict = dict((d.pk, d) for d in docs)
doc_ids = list(doc_dict.keys()) doc_ids = list(doc_dict.keys())
rfc_aliases = dict([ (a.document.id, a.name) for a in DocAlias.objects.filter(name__startswith="rfc", docs__id__in=doc_ids) ]) rfcs = dict((d.pk, d.name) for d in docs if d.type_id='rfc')
# latest event cache # latest event cache
event_types = ("published_rfc", event_types = ("published_rfc",
@ -90,8 +91,6 @@ def fill_in_document_table_attributes(docs, have_telechat_date=False):
# misc # misc
expirable_pks = expirable_drafts(Document.objects.filter(pk__in=doc_ids)).values_list('pk', flat=True) expirable_pks = expirable_drafts(Document.objects.filter(pk__in=doc_ids)).values_list('pk', flat=True)
for d in docs: for d in docs:
# emulate canonical name which is used by a lot of the utils
# d.canonical_name = wrap_value(rfc_aliases[d.pk] if d.pk in rfc_aliases else d.name)
if d.type_id == "rfc" and d.latest_event_cache["published_rfc"]: if d.type_id == "rfc" and d.latest_event_cache["published_rfc"]:
d.latest_revision_date = d.latest_event_cache["published_rfc"].time d.latest_revision_date = d.latest_event_cache["published_rfc"].time
@ -128,29 +127,30 @@ def fill_in_document_table_attributes(docs, have_telechat_date=False):
# RFCs # RFCs
# errata # errata
erratas = set(Document.objects.filter(tags="errata", id__in=list(rfc_aliases.keys())).distinct().values_list("name", flat=True)) erratas = set(Document.objects.filter(tags="errata", id__in=list(rfcs.keys())).distinct().values_list("name", flat=True))
verified_erratas = set(Document.objects.filter(tags="verified-errata", id__in=list(rfc_aliases.keys())).distinct().values_list("name", flat=True)) verified_erratas = set(Document.objects.filter(tags="verified-errata", id__in=list(rfcs.keys())).distinct().values_list("name", flat=True))
for d in docs: for d in docs:
d.has_errata = d.name in erratas d.has_errata = d.name in erratas
d.has_verified_errata = d.name in verified_erratas d.has_verified_errata = d.name in verified_erratas
# obsoleted/updated by # obsoleted/updated by
for a in rfc_aliases: for rfc in rfcs:
d = doc_dict[a] d = doc_dict[rfc]
d.obsoleted_by_list = [] d.obsoleted_by_list = []
d.updated_by_list = [] d.updated_by_list = []
# Revisit this block after RFCs become first-class Document objects # Revisit this block after RFCs become first-class Document objects
xed_by = list( xed_by = list(
RelatedDocument.objects.filter( RelatedDocument.objects.filter(
target__name__in=list(rfc_aliases.values()), target__name__in=list(rfcs.values()),
relationship__in=("obs", "updates"), relationship__in=("obs", "updates"),
).select_related("target") ).select_related("target")
) )
rel_rfc_aliases = { # TODO - this likely reduces to something even simpler
rel_rfcs = {
a.document.id: re.sub(r"rfc(\d+)", r"RFC \1", a.name, flags=re.IGNORECASE) a.document.id: re.sub(r"rfc(\d+)", r"RFC \1", a.name, flags=re.IGNORECASE)
for a in DocAlias.objects.filter( for a in Document.objects.filter(
name__startswith="rfc", docs__id__in=[rel.source_id for rel in xed_by] type_id="rfc", docs__id__in=[rel.source_id for rel in xed_by]
) )
} }
xed_by.sort( xed_by.sort(
@ -158,7 +158,7 @@ def fill_in_document_table_attributes(docs, have_telechat_date=False):
re.sub( re.sub(
r"rfc\s*(\d+)", r"rfc\s*(\d+)",
r"\1", r"\1",
rel_rfc_aliases[rel.source_id], rel_rfcs[rel.source_id],
flags=re.IGNORECASE, flags=re.IGNORECASE,
) )
) )
@ -192,7 +192,7 @@ def prepare_document_table(request, docs, query=None, max_results=200):
# the number of queries # the number of queries
docs = docs.select_related("ad", "std_level", "intended_std_level", "group", "stream", "shepherd", ) 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", docs = docs.prefetch_related("states__type", "tags", "groupmilestone_set__group", "reviewrequest_set__team",
"ad__email_set", "docalias__iprdocrel_set") "ad__email_set", "iprdocrel_set")
docs = docs[:max_results] # <- that is still a queryset, but with a LIMIT now docs = docs[:max_results] # <- that is still a queryset, but with a LIMIT now
docs = list(docs) docs = list(docs)
else: else:

View file

@ -179,7 +179,7 @@ def save_position(form, doc, ballot, balloter, login=None, send_email=False):
@role_required("Area Director", "Secretariat", "IRSG Member", "RSAB Member") @role_required("Area Director", "Secretariat", "IRSG Member", "RSAB Member")
def edit_position(request, name, ballot_id): def edit_position(request, name, ballot_id):
"""Vote and edit discuss and comment on document""" """Vote and edit discuss and comment on document"""
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
ballot = get_object_or_404(BallotDocEvent, type="created_ballot", pk=ballot_id, doc=doc) ballot = get_object_or_404(BallotDocEvent, type="created_ballot", pk=ballot_id, doc=doc)
balloter = login = request.user.person balloter = login = request.user.person
@ -256,7 +256,7 @@ def api_set_position(request):
if not name: if not name:
return err(400, "Missing document name") return err(400, "Missing document name")
try: try:
doc = Document.objects.get(docalias__name=name) doc = Document.objects.get(name=name)
except Document.DoesNotExist: except Document.DoesNotExist:
return err(400, "Document not found") return err(400, "Document not found")
position_names = BallotPositionName.objects.values_list('slug', flat=True) position_names = BallotPositionName.objects.values_list('slug', flat=True)
@ -323,7 +323,7 @@ def build_position_email(balloter, doc, pos):
@role_required('Area Director','Secretariat','IRSG Member', 'RSAB Member') @role_required('Area Director','Secretariat','IRSG Member', 'RSAB Member')
def send_ballot_comment(request, name, ballot_id): def send_ballot_comment(request, name, ballot_id):
"""Email document ballot position discuss/comment for Area Director.""" """Email document ballot position discuss/comment for Area Director."""
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
ballot = get_object_or_404(BallotDocEvent, type="created_ballot", pk=ballot_id, doc=doc) ballot = get_object_or_404(BallotDocEvent, type="created_ballot", pk=ballot_id, doc=doc)
if not has_role(request.user, 'Secretariat'): if not has_role(request.user, 'Secretariat'):
@ -413,7 +413,7 @@ def clear_ballot(request, name, ballot_type_slug):
@role_required('Area Director','Secretariat') @role_required('Area Director','Secretariat')
def defer_ballot(request, name): def defer_ballot(request, name):
"""Signal post-pone of ballot, notifying relevant parties.""" """Signal post-pone of ballot, notifying relevant parties."""
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
if doc.type_id not in ('draft','conflrev','statchg'): if doc.type_id not in ('draft','conflrev','statchg'):
raise Http404 raise Http404
interesting_state = dict(draft='draft-iesg',conflrev='conflrev',statchg='statchg') interesting_state = dict(draft='draft-iesg',conflrev='conflrev',statchg='statchg')
@ -467,7 +467,7 @@ def defer_ballot(request, name):
@role_required('Area Director','Secretariat') @role_required('Area Director','Secretariat')
def undefer_ballot(request, name): def undefer_ballot(request, name):
"""undo deferral of ballot ballot.""" """undo deferral of ballot ballot."""
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
if doc.type_id not in ('draft','conflrev','statchg'): if doc.type_id not in ('draft','conflrev','statchg'):
raise Http404 raise Http404
if doc.type_id == 'draft' and not doc.get_state("draft-iesg"): if doc.type_id == 'draft' and not doc.get_state("draft-iesg"):
@ -503,7 +503,7 @@ class LastCallTextForm(forms.Form):
@role_required('Area Director','Secretariat') @role_required('Area Director','Secretariat')
def lastcalltext(request, name): def lastcalltext(request, name):
"""Editing of the last call text""" """Editing of the last call text"""
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
if not doc.get_state("draft-iesg"): if not doc.get_state("draft-iesg"):
raise Http404 raise Http404
@ -589,7 +589,7 @@ class BallotWriteupForm(forms.Form):
@role_required('Area Director','Secretariat') @role_required('Area Director','Secretariat')
def ballot_writeupnotes(request, name): def ballot_writeupnotes(request, name):
"""Editing of ballot write-up and notes""" """Editing of ballot write-up and notes"""
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
prev_state = doc.get_state("draft-iesg") prev_state = doc.get_state("draft-iesg")
login = request.user.person login = request.user.person
@ -700,7 +700,7 @@ class BallotRfcEditorNoteForm(forms.Form):
@role_required('Area Director','Secretariat','IAB Chair','IRTF Chair','ISE') @role_required('Area Director','Secretariat','IAB Chair','IRTF Chair','ISE')
def ballot_rfceditornote(request, name): def ballot_rfceditornote(request, name):
"""Editing of RFC Editor Note""" """Editing of RFC Editor Note"""
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
if not is_authorized_in_doc_stream(request.user, doc): if not is_authorized_in_doc_stream(request.user, doc):
permission_denied(request, "You do not have the necessary permissions to change the RFC Editor Note for this document") permission_denied(request, "You do not have the necessary permissions to change the RFC Editor Note for this document")
@ -765,7 +765,7 @@ class ApprovalTextForm(forms.Form):
@role_required('Area Director','Secretariat') @role_required('Area Director','Secretariat')
def ballot_approvaltext(request, name): def ballot_approvaltext(request, name):
"""Editing of approval text""" """Editing of approval text"""
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
if not doc.get_state("draft-iesg"): if not doc.get_state("draft-iesg"):
raise Http404 raise Http404
@ -816,7 +816,7 @@ def ballot_approvaltext(request, name):
@role_required('Secretariat') @role_required('Secretariat')
def approve_ballot(request, name): def approve_ballot(request, name):
"""Approve ballot, sending out announcement, changing state.""" """Approve ballot, sending out announcement, changing state."""
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
if not doc.get_state("draft-iesg"): if not doc.get_state("draft-iesg"):
raise Http404 raise Http404
@ -947,7 +947,7 @@ class ApproveDownrefsForm(forms.Form):
@role_required('Secretariat') @role_required('Secretariat')
def approve_downrefs(request, name): def approve_downrefs(request, name):
"""Document ballot was just approved; add the checked downwared references to the downref registry.""" """Document ballot was just approved; add the checked downwared references to the downref registry."""
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
if not doc.get_state("draft-iesg"): if not doc.get_state("draft-iesg"):
raise Http404 raise Http404
@ -1001,7 +1001,7 @@ class MakeLastCallForm(forms.Form):
@role_required('Secretariat') @role_required('Secretariat')
def make_last_call(request, name): def make_last_call(request, name):
"""Make last call for Internet-Draft, sending out announcement.""" """Make last call for Internet-Draft, sending out announcement."""
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
if not (doc.get_state("draft-iesg") or doc.get_state("statchg")): if not (doc.get_state("draft-iesg") or doc.get_state("statchg")):
raise Http404 raise Http404
@ -1109,7 +1109,7 @@ def make_last_call(request, name):
@role_required('Secretariat', 'IRTF Chair') @role_required('Secretariat', 'IRTF Chair')
def issue_irsg_ballot(request, name): def issue_irsg_ballot(request, name):
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
if doc.stream.slug != "irtf" or doc.type != DocTypeName.objects.get(slug="draft"): if doc.stream.slug != "irtf" or doc.type != DocTypeName.objects.get(slug="draft"):
raise Http404 raise Http404
@ -1164,7 +1164,7 @@ def issue_irsg_ballot(request, name):
@role_required('Secretariat', 'IRTF Chair') @role_required('Secretariat', 'IRTF Chair')
def close_irsg_ballot(request, name): def close_irsg_ballot(request, name):
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
if doc.stream.slug != "irtf" or doc.type != DocTypeName.objects.get(slug="draft"): if doc.stream.slug != "irtf" or doc.type != DocTypeName.objects.get(slug="draft"):
raise Http404 raise Http404
@ -1205,7 +1205,7 @@ def irsg_ballot_status(request):
@role_required('Secretariat', 'RSAB Chair') @role_required('Secretariat', 'RSAB Chair')
def issue_rsab_ballot(request, name): def issue_rsab_ballot(request, name):
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
if doc.stream.slug != "editorial" or doc.type != DocTypeName.objects.get(slug="draft"): if doc.stream.slug != "editorial" or doc.type != DocTypeName.objects.get(slug="draft"):
raise Http404 raise Http404
@ -1254,7 +1254,7 @@ def issue_rsab_ballot(request, name):
@role_required('Secretariat', 'RSAB Chair') @role_required('Secretariat', 'RSAB Chair')
def close_rsab_ballot(request, name): def close_rsab_ballot(request, name):
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
if doc.stream.slug != "editorial" or doc.type_id != "draft": if doc.stream.slug != "editorial" or doc.type_id != "draft":
raise Http404 raise Http404

View file

@ -15,7 +15,7 @@ from django.utils.html import escape
from ietf.doc.mails import (email_bofreq_title_changed, email_bofreq_editors_changed, from ietf.doc.mails import (email_bofreq_title_changed, email_bofreq_editors_changed,
email_bofreq_new_revision, email_bofreq_responsible_changed) email_bofreq_new_revision, email_bofreq_responsible_changed)
from ietf.doc.models import (Document, DocAlias, DocEvent, NewRevisionDocEvent, from ietf.doc.models import (Document, DocEvent, NewRevisionDocEvent,
BofreqEditorDocEvent, BofreqResponsibleDocEvent, State) BofreqEditorDocEvent, BofreqResponsibleDocEvent, State)
from ietf.doc.utils import add_state_change_event from ietf.doc.utils import add_state_change_event
from ietf.doc.utils_bofreq import bofreq_editors, bofreq_responsible from ietf.doc.utils_bofreq import bofreq_editors, bofreq_responsible
@ -168,8 +168,6 @@ def new_bof_request(request):
) )
e2.editors.set([request.user.person]) e2.editors.set([request.user.person])
bofreq.save_with_history([e1,e2]) bofreq.save_with_history([e1,e2])
alias = DocAlias.objects.create(name=name)
alias.docs.set([bofreq])
bofreq_submission = form.cleaned_data['bofreq_submission'] bofreq_submission = form.cleaned_data['bofreq_submission']
if bofreq_submission == "upload": if bofreq_submission == "upload":
content = get_cleaned_text_file_content(form.cleaned_data["bofreq_file"]) content = get_cleaned_text_file_content(form.cleaned_data["bofreq_file"])

View file

@ -22,7 +22,7 @@ from django.utils.html import escape
import debug # pyflakes:ignore import debug # pyflakes:ignore
from ietf.doc.models import ( Document, DocAlias, DocHistory, State, DocEvent, from ietf.doc.models import ( Document, DocHistory, State, DocEvent,
BallotDocEvent, BallotPositionDocEvent, InitialReviewDocEvent, NewRevisionDocEvent, BallotDocEvent, BallotPositionDocEvent, InitialReviewDocEvent, NewRevisionDocEvent,
WriteupDocEvent, TelechatDocEvent ) WriteupDocEvent, TelechatDocEvent )
from ietf.doc.utils import ( add_state_change_event, close_open_ballots, from ietf.doc.utils import ( add_state_change_event, close_open_ballots,
@ -412,7 +412,6 @@ def submit(request, name, option=None):
abstract=group.name, abstract=group.name,
rev=next_rev, rev=next_rev,
) )
DocAlias.objects.create(name=name).docs.add(charter)
charter.set_state( charter.set_state(
State.objects.get(used=True, type="charter", slug="notrev") State.objects.get(used=True, type="charter", slug="notrev")

View file

@ -16,7 +16,7 @@ from django.utils.html import escape
import debug # pyflakes:ignore import debug # pyflakes:ignore
from ietf.doc.models import ( BallotDocEvent, BallotPositionDocEvent, DocAlias, DocEvent, from ietf.doc.models import ( BallotDocEvent, BallotPositionDocEvent, DocEvent,
Document, NewRevisionDocEvent, State ) Document, NewRevisionDocEvent, State )
from ietf.doc.utils import ( add_state_change_event, close_open_ballots, from ietf.doc.utils import ( add_state_change_event, close_open_ballots,
create_ballot_if_not_open, update_telechat ) create_ballot_if_not_open, update_telechat )
@ -448,9 +448,6 @@ def build_conflict_review_document(login, doc_to_review, ad, notify, create_in_s
group=iesg_group, group=iesg_group,
) )
conflict_review.set_state(create_in_state) conflict_review.set_state(create_in_state)
DocAlias.objects.create( name=review_name).docs.add( conflict_review )
conflict_review.relateddocument_set.create(target=doc_to_review, relationship_id='conflrev') conflict_review.relateddocument_set.create(target=doc_to_review, relationship_id='conflrev')

View file

@ -193,7 +193,7 @@ def document_main(request, name, rev=None, document_html=False):
if name.startswith("rfc") and rev is not None: if name.startswith("rfc") and rev is not None:
raise Http404() raise Http404()
doc = get_object_or_404(Document.objects.select_related(), docalias__name=name) doc = get_object_or_404(Document.objects.select_related(), name=name)
# take care of possible redirections # take care of possible redirections
if document_html is False and rev is None: if document_html is False and rev is None:
@ -328,9 +328,9 @@ def document_main(request, name, rev=None, document_html=False):
if html: if html:
css += Path(finders.find("ietf/css/document_html_txt.css")).read_text() css += Path(finders.find("ietf/css/document_html_txt.css")).read_text()
draft_that_became_rfc = None draft_that_became_rfc = None
became_rfc_alias = next(iter(doc.related_that("became_rfc")), None) became_rfc = next(iter(doc.related_that("became_rfc")), None)
if became_rfc_alias: if became_rfc:
draft_that_became_rfc = became_rfc_alias.document draft_that_became_rfc = became_rfc
# submission # submission
submission = "" submission = ""
if group is None: if group is None:
@ -1124,7 +1124,7 @@ def get_doc_email_aliases(name):
return aliases return aliases
def document_email(request,name): def document_email(request,name):
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
top = render_document_top(request, doc, "email", name) top = render_document_top(request, doc, "email", name)
aliases = get_doc_email_aliases(name) if doc.type_id=='draft' else None aliases = get_doc_email_aliases(name) if doc.type_id=='draft' else None
@ -1168,12 +1168,15 @@ def get_diff_revisions(request, name, doc):
relateddocument__relationship="replaces", relateddocument__relationship="replaces",
) )
) )
diff_documents.extend(
Document.objects.filter(
relateddocument__target=doc,
relateddocument__relationship="became_rfc"
)
)
if doc.get_state_slug() == "rfc": if doc.tyoe_id == "rfc":
e = doc.latest_event(type="published_rfc") e = doc.latest_event(type="published_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)) diff_revisions.append((name, "", e.time if e else doc.time, name))
seen = set() seen = set()
@ -1209,7 +1212,7 @@ def get_diff_revisions(request, name, doc):
def document_history(request, name): def document_history(request, name):
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
top = render_document_top(request, doc, "history", name) top = render_document_top(request, doc, "history", name)
diff_revisions = get_diff_revisions(request, name, doc) diff_revisions = get_diff_revisions(request, name, doc)
@ -1276,7 +1279,7 @@ def document_bibtex(request, name, rev=None):
name = name+"-"+rev name = name+"-"+rev
rev = None rev = None
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
doi = None doi = None
draft_became_rfc = None draft_became_rfc = None
@ -1285,7 +1288,7 @@ def document_bibtex(request, name, rev=None):
if doc.type_id == "draft": if doc.type_id == "draft":
latest_revision = doc.latest_event(NewRevisionDocEvent, type="new_revision") latest_revision = doc.latest_event(NewRevisionDocEvent, type="new_revision")
replaced_by = [d.name for d in doc.related_that("replaces")] replaced_by = [d.name for d in doc.related_that("replaces")]
draft_became_rfc_alias = next(iter(doc.related_that_doc("became_rfc")), None) draft_became_rfc = next(iter(doc.related_that_doc("became_rfc")), None)
if rev != None and rev != doc.rev: if rev != None and rev != doc.rev:
# find the entry in the history # find the entry in the history
@ -1293,14 +1296,10 @@ def document_bibtex(request, name, rev=None):
if rev == h.rev: if rev == h.rev:
doc = h doc = h
break break
if draft_became_rfc_alias:
draft_became_rfc = draft_became_rfc_alias.document
elif doc.type_id == "rfc": elif doc.type_id == "rfc":
# This needs to be replaced with a lookup, as the mapping may change # This needs to be replaced with a lookup, as the mapping may change
# over time. Probably by updating ietf/sync/rfceditor.py to add the # over time.
# as a DocAlias, and use a method on Document to retrieve it.
doi = f"10.17487/RFC{doc.rfc_number:04d}" doi = f"10.17487/RFC{doc.rfc_number:04d}"
if doc.is_dochistory(): if doc.is_dochistory():
@ -1348,7 +1347,7 @@ def document_bibxml(request, name, rev=None):
def document_writeup(request, name): def document_writeup(request, name):
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
top = render_document_top(request, doc, "writeup", name) top = render_document_top(request, doc, "writeup", name)
def text_from_writeup(event_type): def text_from_writeup(event_type):
@ -1412,7 +1411,7 @@ def document_writeup(request, name):
)) ))
def document_shepherd_writeup(request, name): def document_shepherd_writeup(request, name):
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
lastwriteup = doc.latest_event(WriteupDocEvent,type="changed_protocol_writeup") lastwriteup = doc.latest_event(WriteupDocEvent,type="changed_protocol_writeup")
if lastwriteup: if lastwriteup:
writeup_text = lastwriteup.text writeup_text = lastwriteup.text
@ -1449,12 +1448,12 @@ def document_shepherd_writeup_template(request, type):
def document_references(request, name): def document_references(request, name):
doc = get_object_or_404(Document,docalias__name=name) doc = get_object_or_404(Document,name=name)
refs = doc.references() refs = doc.references()
return render(request, "doc/document_references.html",dict(doc=doc,refs=sorted(refs,key=lambda x:x.target.name),)) return render(request, "doc/document_references.html",dict(doc=doc,refs=sorted(refs,key=lambda x:x.target.name),))
def document_referenced_by(request, name): def document_referenced_by(request, name):
doc = get_object_or_404(Document,docalias__name=name) doc = get_object_or_404(Document,name=name)
refs = doc.referenced_by() refs = doc.referenced_by()
full = ( request.GET.get('full') != None ) full = ( request.GET.get('full') != None )
numdocs = refs.count() numdocs = refs.count()
@ -1464,7 +1463,7 @@ def document_referenced_by(request, name):
numdocs=None numdocs=None
refs=sorted(refs,key=lambda x:(['refnorm','refinfo','refunk','refold'].index(x.relationship.slug),x.source.canonical_name())) refs=sorted(refs,key=lambda x:(['refnorm','refinfo','refunk','refold'].index(x.relationship.slug),x.source.canonical_name()))
return render(request, "doc/document_referenced_by.html", return render(request, "doc/document_referenced_by.html",
dict(alias_name=name, dict(name=name,
doc=doc, doc=doc,
numdocs=numdocs, numdocs=numdocs,
refs=refs, refs=refs,
@ -1538,7 +1537,7 @@ def document_ballot_content(request, doc, ballot_id, editable=True):
request=request) request=request)
def document_ballot(request, name, ballot_id=None): def document_ballot(request, name, ballot_id=None):
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
all_ballots = list(BallotDocEvent.objects.filter(doc=doc, type="created_ballot").order_by("time")) all_ballots = list(BallotDocEvent.objects.filter(doc=doc, type="created_ballot").order_by("time"))
if not ballot_id: if not ballot_id:
if all_ballots: if all_ballots:
@ -1574,7 +1573,7 @@ def document_ballot(request, name, ballot_id=None):
)) ))
def document_irsg_ballot(request, name, ballot_id=None): def document_irsg_ballot(request, name, ballot_id=None):
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
top = render_document_top(request, doc, "irsgballot", name) top = render_document_top(request, doc, "irsgballot", name)
if not ballot_id: if not ballot_id:
ballot = doc.latest_event(BallotDocEvent, type="created_ballot", ballot_type__slug='irsg-approve') ballot = doc.latest_event(BallotDocEvent, type="created_ballot", ballot_type__slug='irsg-approve')
@ -1593,7 +1592,7 @@ def document_irsg_ballot(request, name, ballot_id=None):
)) ))
def document_rsab_ballot(request, name, ballot_id=None): def document_rsab_ballot(request, name, ballot_id=None):
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
top = render_document_top(request, doc, "rsabballot", name) top = render_document_top(request, doc, "rsabballot", name)
if not ballot_id: if not ballot_id:
ballot = doc.latest_event(BallotDocEvent, type="created_ballot", ballot_type__slug='rsab-approve') ballot = doc.latest_event(BallotDocEvent, type="created_ballot", ballot_type__slug='rsab-approve')
@ -1615,7 +1614,7 @@ def document_rsab_ballot(request, name, ballot_id=None):
) )
def ballot_popup(request, name, ballot_id): def ballot_popup(request, name, ballot_id):
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
c = document_ballot_content(request, doc, ballot_id=ballot_id, editable=False) c = document_ballot_content(request, doc, ballot_id=ballot_id, editable=False)
ballot = get_object_or_404(BallotDocEvent,id=ballot_id) ballot = get_object_or_404(BallotDocEvent,id=ballot_id)
return render(request, "doc/ballot_popup.html", return render(request, "doc/ballot_popup.html",
@ -1628,7 +1627,7 @@ def ballot_popup(request, name, ballot_id):
def document_json(request, name, rev=None): def document_json(request, name, rev=None):
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
def extract_name(s): def extract_name(s):
return s.name if s else None return s.name if s else None
@ -1648,7 +1647,8 @@ def document_json(request, name, rev=None):
data["expires"] = doc.expires.strftime("%Y-%m-%d %H:%M:%S") if doc.expires else None data["expires"] = doc.expires.strftime("%Y-%m-%d %H:%M:%S") if doc.expires else None
data["title"] = doc.title data["title"] = doc.title
data["abstract"] = doc.abstract data["abstract"] = doc.abstract
data["aliases"] = list(doc.docalias.values_list("name", flat=True)) # Preserve aliases in this api? What about showing rfc_number directly?
data["aliases"] = list(doc.name)
data["state"] = extract_name(doc.get_state()) data["state"] = extract_name(doc.get_state())
data["intended_std_level"] = extract_name(doc.intended_std_level) data["intended_std_level"] = extract_name(doc.intended_std_level)
data["std_level"] = extract_name(doc.std_level) data["std_level"] = extract_name(doc.std_level)
@ -1683,7 +1683,7 @@ class AddCommentForm(forms.Form):
@role_required('Area Director', 'Secretariat', 'IRTF Chair', 'WG Chair', 'RG Chair', 'WG Secretary', 'RG Secretary', 'IANA', 'RFC Editor') @role_required('Area Director', 'Secretariat', 'IRTF Chair', 'WG Chair', 'RG Chair', 'WG Secretary', 'RG Secretary', 'IANA', 'RFC Editor')
def add_comment(request, name): def add_comment(request, name):
"""Add comment to history of document.""" """Add comment to history of document."""
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
login = request.user.person login = request.user.person
@ -2173,14 +2173,13 @@ def idnits2_rfc_status(request):
def idnits2_state(request, name, rev=None): def idnits2_state(request, name, rev=None):
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
if doc.type_id not in ["draft", "rfc"]: if doc.type_id not in ["draft", "rfc"]:
raise Http404 raise Http404
zero_revision = None zero_revision = None
if doc.type_id == "rfc": if doc.type_id == "rfc":
draft_alias = next(iter(doc.related_that('became_rfc')), None) draft = next(iter(doc.related_that('became_rfc')), None)
if draft_alias: if draft:
draft = draft_alias.document
zero_revision = NewRevisionDocEvent.objects.filter(doc=draft,rev='00').first() zero_revision = NewRevisionDocEvent.objects.filter(doc=draft,rev='00').first()
else: else:
zero_revision = NewRevisionDocEvent.objects.filter(doc=doc,rev='00').first() zero_revision = NewRevisionDocEvent.objects.filter(doc=doc,rev='00').first()

View file

@ -66,7 +66,7 @@ class ChangeStateForm(forms.Form):
state = self.cleaned_data.get('state', '(None)') state = self.cleaned_data.get('state', '(None)')
tag = self.cleaned_data.get('substate','') tag = self.cleaned_data.get('substate','')
comment = self.cleaned_data['comment'].strip() # pyflakes:ignore comment = self.cleaned_data['comment'].strip() # pyflakes:ignore
doc = get_object_or_404(Document, docalias__name=self.docname) doc = get_object_or_404(Document, name=self.docname)
prev = doc.get_state("draft-iesg") prev = doc.get_state("draft-iesg")
# tag handling is a bit awkward since the UI still works # tag handling is a bit awkward since the UI still works
@ -86,7 +86,7 @@ class ChangeStateForm(forms.Form):
def change_state(request, name): def change_state(request, name):
"""Change IESG state of Internet-Draft, notifying parties as necessary """Change IESG state of Internet-Draft, notifying parties as necessary
and logging the change as a comment.""" and logging the change as a comment."""
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
if (not doc.latest_event(type="started_iesg_process")) or doc.get_state_slug() == "expired": if (not doc.latest_event(type="started_iesg_process")) or doc.get_state_slug() == "expired":
raise Http404 raise Http404
@ -205,7 +205,7 @@ class AddIanaExpertsCommentForm(forms.Form):
@role_required('Secretariat', 'IANA') @role_required('Secretariat', 'IANA')
def add_iana_experts_comment(request, name): def add_iana_experts_comment(request, name):
doc = get_object_or_404(Document, docalias__name = name) doc = get_object_or_404(Document, name = name)
if request.method == 'POST': if request.method == 'POST':
form = AddIanaExpertsCommentForm(request.POST) form = AddIanaExpertsCommentForm(request.POST)
if form.is_valid(): if form.is_valid():
@ -231,7 +231,7 @@ class ChangeIanaStateForm(forms.Form):
def change_iana_state(request, name, state_type): def change_iana_state(request, name, state_type):
"""Change IANA review state of Internet-Draft. Normally, this is done via """Change IANA review state of Internet-Draft. Normally, this is done via
automatic sync, but this form allows one to set it manually.""" automatic sync, but this form allows one to set it manually."""
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
state_type = doc.type_id + "-" + state_type state_type = doc.type_id + "-" + state_type
@ -271,7 +271,7 @@ class ChangeStreamForm(forms.Form):
def change_stream(request, name): def change_stream(request, name):
"""Change the stream of a Document of type 'draft', notifying parties as necessary """Change the stream of a Document of type 'draft', notifying parties as necessary
and logging the change as a comment.""" and logging the change as a comment."""
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
if not doc.type_id=='draft': if not doc.type_id=='draft':
raise Http404 raise Http404
@ -352,7 +352,7 @@ class ReplacesForm(forms.Form):
def replaces(request, name): def replaces(request, name):
"""Change 'replaces' set of a Document of type 'draft' , notifying parties """Change 'replaces' set of a Document of type 'draft' , notifying parties
as necessary and logging the change as a comment.""" as necessary and logging the change as a comment."""
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
if doc.type_id != 'draft': if doc.type_id != 'draft':
raise Http404 raise Http404
if not (has_role(request.user, ("Secretariat", "Area Director", "WG Chair", "RG Chair", "WG Secretary", "RG Secretary")) if not (has_role(request.user, ("Secretariat", "Area Director", "WG Chair", "RG Chair", "WG Secretary", "RG Secretary"))
@ -396,7 +396,7 @@ class SuggestedReplacesForm(forms.Form):
self.fields["replaces"].choices = [(d.pk, d.name) for d in suggested] self.fields["replaces"].choices = [(d.pk, d.name) for d in suggested]
def review_possibly_replaces(request, name): def review_possibly_replaces(request, name):
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
if doc.type_id != 'draft': if doc.type_id != 'draft':
raise Http404 raise Http404
if not (has_role(request.user, ("Secretariat", "Area Director")) if not (has_role(request.user, ("Secretariat", "Area Director"))
@ -451,7 +451,7 @@ class ChangeIntentionForm(forms.Form):
def change_intention(request, name): def change_intention(request, name):
"""Change the intended publication status of a Document of type 'draft' , notifying parties """Change the intended publication status of a Document of type 'draft' , notifying parties
as necessary and logging the change as a comment.""" as necessary and logging the change as a comment."""
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
if doc.type_id != 'draft': if doc.type_id != 'draft':
raise Http404 raise Http404
@ -520,7 +520,7 @@ class EditInfoForm(forms.Form):
def to_iesg(request,name): def to_iesg(request,name):
""" Submit an IETF stream document to the IESG for publication """ """ Submit an IETF stream document to the IESG for publication """
doc = get_object_or_404(Document, docalias__name=name, stream='ietf') doc = get_object_or_404(Document, name=name, stream='ietf')
if doc.get_state_slug('draft') == "expired" or doc.get_state_slug('draft-iesg') == 'pub-req' : if doc.get_state_slug('draft') == "expired" or doc.get_state_slug('draft-iesg') == 'pub-req' :
raise Http404 raise Http404
@ -633,7 +633,7 @@ def to_iesg(request,name):
def edit_info(request, name): def edit_info(request, name):
"""Edit various Internet-Draft attributes, notifying parties as """Edit various Internet-Draft attributes, notifying parties as
necessary and logging changes as document events.""" necessary and logging changes as document events."""
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
if doc.get_state_slug() == "expired": if doc.get_state_slug() == "expired":
raise Http404 raise Http404
@ -791,7 +791,7 @@ def edit_info(request, name):
@role_required('Area Director','Secretariat') @role_required('Area Director','Secretariat')
def request_resurrect(request, name): def request_resurrect(request, name):
"""Request resurrect of expired Internet-Draft.""" """Request resurrect of expired Internet-Draft."""
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
if doc.get_state_slug() != "expired": if doc.get_state_slug() != "expired":
raise Http404 raise Http404
@ -814,7 +814,7 @@ def request_resurrect(request, name):
@role_required('Secretariat') @role_required('Secretariat')
def resurrect(request, name): def resurrect(request, name):
"""Resurrect expired Internet-Draft.""" """Resurrect expired Internet-Draft."""
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
if doc.get_state_slug() != "expired": if doc.get_state_slug() != "expired":
raise Http404 raise Http404

View file

@ -16,7 +16,7 @@ from django.urls import reverse as urlreverse
import debug # pyflakes:ignore import debug # pyflakes:ignore
from ietf.doc.models import Document, DocAlias, DocTypeName, DocEvent, State from ietf.doc.models import Document, DocTypeName, DocEvent, State
from ietf.doc.models import NewRevisionDocEvent from ietf.doc.models import NewRevisionDocEvent
from ietf.doc.utils import add_state_change_event, check_common_doc_name_rules from ietf.doc.utils import add_state_change_event, check_common_doc_name_rules
from ietf.group.models import Group from ietf.group.models import Group
@ -156,10 +156,6 @@ def edit_material(request, name=None, acronym=None, action=None, doc_type=None):
for chunk in f.chunks(): for chunk in f.chunks():
dest.write(chunk) dest.write(chunk)
if action == "new":
alias, __ = DocAlias.objects.get_or_create(name=doc.name)
alias.docs.add(doc)
if prev_rev != doc.rev: if prev_rev != doc.rev:
e = NewRevisionDocEvent(type="new_revision", doc=doc, rev=doc.rev) e = NewRevisionDocEvent(type="new_revision", doc=doc, rev=doc.rev)
e.by = request.user.person e.by = request.user.person

View file

@ -28,7 +28,7 @@ from django.core.exceptions import ValidationError
from django.template.loader import render_to_string, TemplateDoesNotExist from django.template.loader import render_to_string, TemplateDoesNotExist
from django.urls import reverse as urlreverse from django.urls import reverse as urlreverse
from ietf.doc.models import (Document, NewRevisionDocEvent, State, DocAlias, from ietf.doc.models import (Document, NewRevisionDocEvent, State,
LastCallDocEvent, ReviewRequestDocEvent, ReviewAssignmentDocEvent, DocumentAuthor) LastCallDocEvent, ReviewRequestDocEvent, ReviewAssignmentDocEvent, DocumentAuthor)
from ietf.name.models import (ReviewRequestStateName, ReviewAssignmentStateName, ReviewResultName, from ietf.name.models import (ReviewRequestStateName, ReviewAssignmentStateName, ReviewResultName,
ReviewTypeName) ReviewTypeName)
@ -715,9 +715,7 @@ def complete_review(request, name, assignment_id=None, acronym=None):
name=review_name, name=review_name,
defaults={'type_id': 'review', 'group': team}, defaults={'type_id': 'review', 'group': team},
) )
if created: if not created:
DocAlias.objects.create(name=review_name).docs.add(review)
else:
messages.warning(request, message='Attempt to save review failed: review document already exists. This most likely occurred because the review was submitted twice in quick succession. If you intended to submit a new review, rather than update an existing one, things are probably OK. Please verify that the shown review is what you expected.') messages.warning(request, message='Attempt to save review failed: review document already exists. This most likely occurred because the review was submitted twice in quick succession. If you intended to submit a new review, rather than update an existing one, things are probably OK. Please verify that the shown review is what you expected.')
return redirect("ietf.doc.views_doc.document_main", name=review_name) return redirect("ietf.doc.views_doc.document_main", name=review_name)
@ -1055,7 +1053,7 @@ class ReviewWishAddForm(forms.Form):
@login_required @login_required
def review_wish_add(request, name): def review_wish_add(request, name):
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
if request.method == "POST": if request.method == "POST":
form = ReviewWishAddForm(request.user, doc, request.POST) form = ReviewWishAddForm(request.user, doc, request.POST)
@ -1072,7 +1070,7 @@ def review_wish_add(request, name):
@login_required @login_required
def review_wishes_remove(request, name): def review_wishes_remove(request, name):
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, name=name)
person = get_object_or_404(Person, user=request.user) person = get_object_or_404(Person, user=request.user)
if request.method == "POST": if request.method == "POST":

View file

@ -53,7 +53,7 @@ from django.utils.cache import _generate_cache_key # type: ignore
import debug # pyflakes:ignore import debug # pyflakes:ignore
from ietf.doc.models import ( Document, DocHistory, DocAlias, State, from ietf.doc.models import ( Document, DocHistory, State,
LastCallDocEvent, NewRevisionDocEvent, IESG_SUBSTATE_TAGS, LastCallDocEvent, NewRevisionDocEvent, IESG_SUBSTATE_TAGS,
IESG_BALLOT_ACTIVE_STATES, IESG_STATCHG_CONFLREV_ACTIVE_STATES, IESG_BALLOT_ACTIVE_STATES, IESG_STATCHG_CONFLREV_ACTIVE_STATES,
IESG_CHARTER_ACTIVE_STATES ) IESG_CHARTER_ACTIVE_STATES )
@ -166,7 +166,7 @@ def retrieve_search_results(form, all_types=False):
# name # name
if query["name"]: if query["name"]:
docs = docs.filter(Q(docalias__name__icontains=query["name"]) | docs = docs.filter(Q(name__icontains=query["name"]) |
Q(title__icontains=query["name"])).distinct() Q(title__icontains=query["name"])).distinct()
# rfc/active/old check buttons # rfc/active/old check buttons
@ -248,17 +248,17 @@ def frontpage(request):
def search_for_name(request, name): def search_for_name(request, name):
def find_unique(n): def find_unique(n):
exact = DocAlias.objects.filter(name__iexact=n).first() exact = Document.objects.filter(name__iexact=n).first()
if exact: if exact:
return exact.name return exact.name
aliases = DocAlias.objects.filter(name__istartswith=n)[:2] startswith = Document.objects.filter(name__istartswith=n)[:2]
if len(aliases) == 1: if len(startswith) == 1:
return aliases[0].name return startswith.name
aliases = DocAlias.objects.filter(name__icontains=n)[:2] contains = Document.objects.filter(name__icontains=n)[:2]
if len(aliases) == 1: if len(contains) == 1:
return aliases[0].name return contains[0].name
return None return None
@ -291,7 +291,7 @@ def search_for_name(request, name):
if redirect_to: if redirect_to:
rev = rev_split.group(2) rev = rev_split.group(2)
# check if we can redirect directly to the rev if it's draft, if rfc - always redirect to main page # check if we can redirect directly to the rev if it's draft, if rfc - always redirect to main page
if not redirect_to.startswith('rfc') and DocHistory.objects.filter(doc__docalias__name=redirect_to, rev=rev).exists(): if not redirect_to.startswith('rfc') and DocHistory.objects.filter(doc__name=redirect_to, rev=rev).exists():
return cached_redirect(cache_key, urlreverse("ietf.doc.views_doc.document_main", kwargs={ "name": redirect_to, "rev": rev })) return cached_redirect(cache_key, urlreverse("ietf.doc.views_doc.document_main", kwargs={ "name": redirect_to, "rev": rev }))
else: else:
return cached_redirect(cache_key, urlreverse("ietf.doc.views_doc.document_main", kwargs={ "name": redirect_to })) return cached_redirect(cache_key, urlreverse("ietf.doc.views_doc.document_main", kwargs={ "name": redirect_to }))
@ -818,23 +818,12 @@ def index_all_drafts(request): # Should we rename this
else: else:
heading = "%s Internet-Drafts" % state.name heading = "%s Internet-Drafts" % state.name
draft_names = DocAlias.objects.filter(docs__type_id="draft", docs__states=state).values_list("name", "docs__name") drafts = Document.objects.filter(docs__type_id="draft", docs__states=state).order_by("name")
names = [] names = [
names_to_skip = set() f'<a href=\"{urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=doc.name))}\">{doc.name}</a>'
for name, doc in draft_names: for doc in drafts
sort_key = name ]
if name != doc:
if not name.startswith("rfc"):
name, doc = doc, name
names_to_skip.add(doc) # this is filtering out subseries docaliases (which we will delete, so TODO clean this out after doing so)
names.append((name, sort_key))
names.sort(key=lambda t: t[1])
names = [f'<a href=\"{urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=n))}\">{n}</a>'
for n, __ in names if n not in names_to_skip]
categories.append((state, categories.append((state,
heading, heading,
@ -843,24 +832,11 @@ def index_all_drafts(request): # Should we rename this
)) ))
# gather RFCs # gather RFCs
rfc_names = DocAlias.objects.filter(docs__type_id="rfc").values_list("name", "docs__name") rfcs = Document.objects.filter(docs__type_id="rfc").order_by('-rfc_number')
names = [] names = [
names_to_skip = set() f'<a href=\"{urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=rfc.name))}\">{rfc.name}</a>'
for name, doc in rfc_names: for rfc in rfcs
sort_key = name ]
if name != doc: # There are some std docalias that pointed to rfc names pre-migration.
if not name.startswith("rfc"):
name, doc = doc, name
names_to_skip.add(doc) # this is filtering out those std docaliases (which we will delete, so TODO clean this out after doing so)
name = name.upper()
sort_key = '%09d' % (100000000-int(name[3:]))
names.append((name, sort_key))
names.sort(key=lambda t: t[1])
names = [f'<a href=\"{urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=n))}\">{n}</a>'
for n, __ in names if n not in names_to_skip]
state = State.objects.get(type_id="rfc", slug="published") state = State.objects.get(type_id="rfc", slug="published")
@ -884,23 +860,15 @@ def index_active_drafts(request):
slowcache.set(cache_key, groups, 15*60) slowcache.set(cache_key, groups, 15*60)
return render(request, "doc/index_active_drafts.html", { 'groups': groups }) return render(request, "doc/index_active_drafts.html", { 'groups': groups })
def ajax_select2_search_docs(request, model_name, doc_type): def ajax_select2_search_docs(request, model_name, doc_type): # TODO - remove model_name argument...
if model_name == "docalias": model = Document # Earlier versions allowed searching over DocAlias which no longer exists
model = DocAlias
else:
model = Document
q = [w.strip() for w in request.GET.get('q', '').split() if w.strip()] q = [w.strip() for w in request.GET.get('q', '').split() if w.strip()]
if not q: if not q:
objs = model.objects.none() objs = model.objects.none()
else: else:
qs = model.objects.all() qs = model.objects.filter(type=doc_type)
if model == Document:
qs = qs.filter(type=doc_type)
elif model == DocAlias:
qs = qs.filter(docs__type=doc_type)
for t in q: for t in q:
qs = qs.filter(name__icontains=t) qs = qs.filter(name__icontains=t)

View file

@ -13,7 +13,7 @@ from django.template.loader import render_to_string
from ietf.utils import markdown from ietf.utils import markdown
from django.utils.html import escape from django.utils.html import escape
from ietf.doc.models import Document, DocAlias, DocEvent, NewRevisionDocEvent, State from ietf.doc.models import Document, DocEvent, NewRevisionDocEvent, State
from ietf.group.models import Group from ietf.group.models import Group
from ietf.ietfauth.utils import role_required from ietf.ietfauth.utils import role_required
from ietf.utils.text import xslugify from ietf.utils.text import xslugify
@ -241,8 +241,6 @@ def new_statement(request):
desc="Statement published", desc="Statement published",
) )
statement.save_with_history([e1, e2]) statement.save_with_history([e1, e2])
alias = DocAlias.objects.create(name=name)
alias.docs.set([statement])
markdown_content = "" markdown_content = ""
if statement_submission == "upload": if statement_submission == "upload":
if not writing_pdf: if not writing_pdf:

View file

@ -21,7 +21,7 @@ from django.utils.html import escape
import debug # pyflakes:ignore import debug # pyflakes:ignore
from ietf.doc.mails import email_ad_approved_status_change from ietf.doc.mails import email_ad_approved_status_change
from ietf.doc.models import ( Document, DocAlias, State, DocEvent, BallotDocEvent, from ietf.doc.models import ( Document, State, DocEvent, BallotDocEvent,
BallotPositionDocEvent, NewRevisionDocEvent, WriteupDocEvent, STATUSCHANGE_RELATIONS ) BallotPositionDocEvent, NewRevisionDocEvent, WriteupDocEvent, STATUSCHANGE_RELATIONS )
from ietf.doc.forms import AdForm from ietf.doc.forms import AdForm
from ietf.doc.lastcall import request_last_call from ietf.doc.lastcall import request_last_call
@ -537,7 +537,7 @@ def start_rfc_status_change(request, name=None):
if name: if name:
if not re.match("(?i)rfc[0-9]{1,4}",name): if not re.match("(?i)rfc[0-9]{1,4}",name):
raise Http404 raise Http404
seed_rfc = get_object_or_404(Document, type="draft", docalias__name=name) seed_rfc = get_object_or_404(Document, type="rfc", name=name)
login = request.user.person login = request.user.person
@ -560,8 +560,6 @@ def start_rfc_status_change(request, name=None):
group=iesg_group, group=iesg_group,
) )
status_change.set_state(form.cleaned_data['create_in_state']) status_change.set_state(form.cleaned_data['create_in_state'])
DocAlias.objects.create( name= 'status-change-'+form.cleaned_data['document_name']).docs.add(status_change)
for key in form.cleaned_data['relations']: for key in form.cleaned_data['relations']:
status_change.relateddocument_set.create(target=Document.objects.get(name=key), status_change.relateddocument_set.create(target=Document.objects.get(name=key),

View file

@ -27,7 +27,7 @@ from django.utils.html import escape
from ietf.community.models import CommunityList from ietf.community.models import CommunityList
from ietf.community.utils import reset_name_contains_index_for_rule from ietf.community.utils import reset_name_contains_index_for_rule
from ietf.doc.factories import WgDraftFactory, IndividualDraftFactory, CharterFactory, BallotDocEventFactory from ietf.doc.factories import WgDraftFactory, IndividualDraftFactory, CharterFactory, BallotDocEventFactory
from ietf.doc.models import Document, DocAlias, DocEvent, State from ietf.doc.models import Document, DocEvent, State
from ietf.doc.utils_charter import charter_name_for_group from ietf.doc.utils_charter import charter_name_for_group
from ietf.group.admin import GroupForm as AdminGroupForm from ietf.group.admin import GroupForm as AdminGroupForm
from ietf.group.factories import (GroupFactory, RoleFactory, GroupEventFactory, from ietf.group.factories import (GroupFactory, RoleFactory, GroupEventFactory,
@ -387,7 +387,6 @@ class GroupPagesTests(TestCase):
type_id="slides", type_id="slides",
) )
doc.set_state(State.objects.get(type="slides", slug="active")) doc.set_state(State.objects.get(type="slides", slug="active"))
DocAlias.objects.create(name=doc.name).docs.add(doc)
for url in group_urlreverse_list(group, 'ietf.group.views.materials'): for url in group_urlreverse_list(group, 'ietf.group.views.materials'):
r = self.client.get(url) r = self.client.get(url)

View file

@ -61,7 +61,7 @@ import debug # pyflakes:ignore
from ietf.community.models import CommunityList, EmailSubscription from ietf.community.models import CommunityList, EmailSubscription
from ietf.community.utils import docs_tracked_by_community_list from ietf.community.utils import docs_tracked_by_community_list
from ietf.doc.models import DocTagName, State, DocAlias, RelatedDocument, Document, DocEvent from ietf.doc.models import DocTagName, State, RelatedDocument, Document, DocEvent
from ietf.doc.templatetags.ietf_filters import clean_whitespace from ietf.doc.templatetags.ietf_filters import clean_whitespace
from ietf.doc.utils import get_chartering_type, get_tags_for_stream_id from ietf.doc.utils import get_chartering_type, get_tags_for_stream_id
from ietf.doc.utils_charter import charter_name_for_group, replace_charter_of_replaced_group from ietf.doc.utils_charter import charter_name_for_group, replace_charter_of_replaced_group
@ -186,17 +186,12 @@ def fill_in_wg_roles(group):
group.secretaries = get_roles("secr", []) group.secretaries = get_roles("secr", [])
def fill_in_wg_drafts(group): def fill_in_wg_drafts(group):
aliases = DocAlias.objects.filter(docs__type="draft", docs__group=group).prefetch_related('docs').order_by("name") group.drafts = Document.objects.filter(type_id="draft", group=group).order_by("name")
group.drafts = [] group.rfcs = Document.objects.filter(type_id="rfc", group=group).order_by("rfc_number")
group.rfcs = [] for rfc in group.rfcs:
for a in aliases: # TODO: remote_field?
if a.name.startswith("draft"): rfc.remote_field = RelatedDocument.objects.filter(source=rfc,relationship_id__in=['obs','updates']).distinct()
group.drafts.append(a) rfc.invrel = RelatedDocument.objects.filter(target=rfc,relationship_id__in=['obs','updates']).distinct()
else:
group.rfcs.append(a)
a.remote_field = RelatedDocument.objects.filter(source=a.document,relationship_id__in=['obs','updates']).distinct()
a.invrel = RelatedDocument.objects.filter(target=a,relationship_id__in=['obs','updates']).distinct()
def check_group_email_aliases(): def check_group_email_aliases():
pattern = re.compile(r'expand-(.*?)(-\w+)@.*? +(.*)$') pattern = re.compile(r'expand-(.*?)(-\w+)@.*? +(.*)$')

View file

@ -14,7 +14,7 @@ from django.utils import timezone
import debug # pyflakes:ignore import debug # pyflakes:ignore
from ietf.doc.models import Document, DocEvent, DocumentAuthor, RelatedDocument, DocAlias, State from ietf.doc.models import Document, DocEvent, DocumentAuthor, RelatedDocument, State
from ietf.doc.models import LastCallDocEvent, NewRevisionDocEvent from ietf.doc.models import LastCallDocEvent, NewRevisionDocEvent
from ietf.doc.models import IESG_SUBSTATE_TAGS from ietf.doc.models import IESG_SUBSTATE_TAGS
from ietf.doc.templatetags.ietf_filters import clean_whitespace from ietf.doc.templatetags.ietf_filters import clean_whitespace
@ -31,15 +31,17 @@ def all_id_txt():
t = revision_time.get(name) t = revision_time.get(name)
return t.strftime("%Y-%m-%d") if t else "" return t.strftime("%Y-%m-%d") if t else ""
rfc_aliases = dict(DocAlias.objects.filter(name__startswith="rfc", rfcs = dict()
docs__states=State.objects.get(type="draft", slug="rfc")).values_list("docs__name", "name")) for rfc in Document.objects.filter(type_id="rfc"):
draft = next(iter(doc.related_that("became_rfc")), None)
rfcs[rfc.name] = draft.name if draft else rfc.name
replacements = dict(RelatedDocument.objects.filter(target__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")) relationship="replaces").values_list("target__name", "source__name"))
# we need a distinct to prevent the queries below from multiplying the result # we need a distinct to prevent the queries below from multiplying the result
all_ids = Document.objects.filter(type="draft").order_by('name').exclude(name__startswith="rfc").distinct() all_ids = Document.objects.filter(type="draft").order_by('name').distinct()
res = ["\nInternet-Drafts Status Summary\n"] res = ["\nInternet-Drafts Status Summary\n"]
@ -77,9 +79,9 @@ def all_id_txt():
last_field = "" last_field = ""
if s.slug == "rfc": if s.slug == "rfc":
a = rfc_aliases.get(name) rfc = rfcs.get(name)
if a: if rfc:
last_field = a[3:] last_field = rfc[3:] # Rework this to take advantage of having the number at hand already.
elif s.slug == "repl": elif s.slug == "repl":
state += " replaced by " + replacements.get(name, "0") state += " replaced by " + replacements.get(name, "0")
@ -112,8 +114,10 @@ def all_id2_txt():
drafts = drafts.select_related('group', 'group__parent', 'ad', 'intended_std_level', 'shepherd', ) drafts = drafts.select_related('group', 'group__parent', 'ad', 'intended_std_level', 'shepherd', )
drafts = drafts.prefetch_related("states") drafts = drafts.prefetch_related("states")
rfc_aliases = dict(DocAlias.objects.filter(name__startswith="rfc", rfcs = dict()
docs__states=State.objects.get(type="draft", slug="rfc")).values_list("docs__name", "name")) for rfc in Document.objects.filter(type_id="rfc"):
draft = next(iter(doc.related_that("became_rfc")), None)
rfcs[rfc.name] = draft.name if draft else rfc.name
replacements = dict(RelatedDocument.objects.filter(target__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")) relationship="replaces").values_list("target__name", "source__name"))
@ -164,9 +168,9 @@ def all_id2_txt():
# 4 # 4
rfc_number = "" rfc_number = ""
if state == "rfc": if state == "rfc":
a = rfc_aliases.get(d.name) rfc = rfcs.get(d.name)
if a: if rfc:
rfc_number = a[3:] rfc_number = rfc[3:]
fields.append(rfc_number) fields.append(rfc_number)
# 5 # 5
repl = "" repl = ""

View file

@ -11,8 +11,8 @@ from django.utils import timezone
import debug # pyflakes:ignore import debug # pyflakes:ignore
from ietf.doc.factories import WgDraftFactory from ietf.doc.factories import WgDraftFactory, RfcFactory
from ietf.doc.models import Document, DocAlias, RelatedDocument, State, LastCallDocEvent, NewRevisionDocEvent from ietf.doc.models import Document, RelatedDocument, State, LastCallDocEvent, NewRevisionDocEvent
from ietf.group.factories import GroupFactory from ietf.group.factories import GroupFactory
from ietf.name.models import DocRelationshipName from ietf.name.models import DocRelationshipName
from ietf.idindex.index import all_id_txt, all_id2_txt, id_index_txt from ietf.idindex.index import all_id_txt, all_id2_txt, id_index_txt
@ -41,7 +41,8 @@ class IndexTests(TestCase):
# published # published
draft.set_state(State.objects.get(type="draft", slug="rfc")) draft.set_state(State.objects.get(type="draft", slug="rfc"))
DocAlias.objects.create(name="rfc1234").docs.add(draft) rfc = RfcFactory(number=1234)
draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc)
txt = all_id_txt() txt = all_id_txt()
self.assertTrue(draft.name + "-" + draft.rev in txt) self.assertTrue(draft.name + "-" + draft.rev in txt)
@ -108,7 +109,8 @@ class IndexTests(TestCase):
# test RFC # test RFC
draft.set_state(State.objects.get(type="draft", slug="rfc")) draft.set_state(State.objects.get(type="draft", slug="rfc"))
DocAlias.objects.create(name="rfc1234").docs.add(draft) rfc = RfcFactory(rfc_number=1234)
draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc)
t = get_fields(all_id2_txt()) t = get_fields(all_id2_txt())
self.assertEqual(t[4], "1234") self.assertEqual(t[4], "1234")

View file

@ -41,7 +41,7 @@ class IprDisclosureBaseFactory(factory.django.DjangoModelFactory):
return return
if extracted: if extracted:
for doc in extracted: for doc in extracted:
IprDocRel.objects.create(disclosure=self,document=doc.docalias.first()) IprDocRel.objects.create(disclosure=self,document=doc)
@factory.post_generation @factory.post_generation
def updates(self, create, extracted, **kwargs): def updates(self, create, extracted, **kwargs):

View file

@ -14,7 +14,7 @@ from django.utils.encoding import force_str
import debug # pyflakes:ignore import debug # pyflakes:ignore
from ietf.group.models import Group from ietf.group.models import Group
from ietf.doc.fields import SearchableDocAliasField from ietf.doc.fields import SearchableDocumentField
from ietf.ipr.mail import utc_from_string from ietf.ipr.mail import utc_from_string
from ietf.ipr.fields import SearchableIprDisclosuresField from ietf.ipr.fields import SearchableIprDisclosuresField
from ietf.ipr.models import (IprDocRel, IprDisclosureBase, HolderIprDisclosure, from ietf.ipr.models import (IprDocRel, IprDisclosureBase, HolderIprDisclosure,
@ -95,7 +95,7 @@ class AddEmailForm(forms.Form):
return self.cleaned_data return self.cleaned_data
class DraftForm(forms.ModelForm): class DraftForm(forms.ModelForm):
document = SearchableDocAliasField(label="I-D name/RFC number", required=True, doc_type="draft") document = SearchableDocumentField(label="I-D name/RFC number", required=True, doc_type="draft") # TODO - this needs to be an or, or the form needs modification
class Meta: class Meta:
model = IprDocRel model = IprDocRel

View file

@ -0,0 +1,78 @@
# Generated by Django 4.2.2 on 2023-06-16 13:40
from django.db import migrations
import django.db.models.deletion
from django.db.models import F, Subquery, OuterRef
import ietf.utils.models
def forward(apps, schema_editor):
IprDocRel = apps.get_model("ipr", "IprDocRel")
DocAlias = apps.get_model("doc", "DocAlias")
subquery = Subquery(DocAlias.objects.filter(pk=OuterRef("deprecated_document")).values("docs")[:1])
IprDocRel.objects.annotate(firstdoc=subquery).update(document=F("firstdoc"))
# This might not be right - we may need here (and in the relateddocument migrations) to pay attention to
# whether the name being pointed to is and rfc name or a draft name and point to the right object instead...
def reverse(apps, schema_editor):
pass
class Migration(migrations.Migration):
dependencies = [
("ipr", "0001_initial"),
("doc", "0014_relate_hist_no_aliases")
]
operations = [
migrations.AlterField(
model_name='iprdocrel',
name='document',
field=ietf.utils.models.ForeignKey(
db_index=False,
on_delete=django.db.models.deletion.CASCADE,
to='doc.docalias',
),
),
migrations.RenameField(
model_name="iprdocrel",
old_name="document",
new_name="deprecated_document"
),
migrations.AlterField(
model_name='iprdocrel',
name='deprecated_document',
field=ietf.utils.models.ForeignKey(
db_index=True,
on_delete=django.db.models.deletion.CASCADE,
to='doc.docalias',
),
),
migrations.AddField(
model_name="iprdocrel",
name="document",
field=ietf.utils.models.ForeignKey(
default=1, # A lie, but a convenient one - no iprdocrel objects point here.
on_delete=django.db.models.deletion.CASCADE,
to="doc.document",
db_index=False,
),
preserve_default=False,
),
migrations.RunPython(forward, reverse),
migrations.AlterField(
model_name="iprdocrel",
name="document",
field=ietf.utils.models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="doc.document",
db_index=True,
),
),
migrations.RemoveField(
model_name="iprdocrel",
name="deprecated_document",
field=ietf.utils.models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to='doc.DocAlias',
),
),
]

View file

@ -7,7 +7,7 @@ from django.db import models
from django.urls import reverse from django.urls import reverse
from django.utils import timezone from django.utils import timezone
from ietf.doc.models import DocAlias, DocEvent from ietf.doc.models import Document, DocEvent
from ietf.name.models import DocRelationshipName,IprDisclosureStateName,IprLicenseTypeName,IprEventTypeName from ietf.name.models import DocRelationshipName,IprDisclosureStateName,IprLicenseTypeName,IprEventTypeName
from ietf.person.models import Person from ietf.person.models import Person
from ietf.message.models import Message from ietf.message.models import Message
@ -16,7 +16,7 @@ from ietf.utils.models import ForeignKey
class IprDisclosureBase(models.Model): class IprDisclosureBase(models.Model):
by = ForeignKey(Person) # who was logged in, or System if nobody was logged in by = ForeignKey(Person) # who was logged in, or System if nobody was logged in
compliant = models.BooleanField("Complies to RFC3979", default=True) compliant = models.BooleanField("Complies to RFC3979", default=True)
docs = models.ManyToManyField(DocAlias, through='IprDocRel') docs = models.ManyToManyField(Document, through='IprDocRel')
holder_legal_name = models.CharField(max_length=255) holder_legal_name = models.CharField(max_length=255)
notes = models.TextField("Additional notes", blank=True) notes = models.TextField("Additional notes", blank=True)
other_designations = models.CharField("Designations for other contributions", blank=True, max_length=255) other_designations = models.CharField("Designations for other contributions", blank=True, max_length=255)
@ -160,7 +160,7 @@ class GenericIprDisclosure(IprDisclosureBase):
class IprDocRel(models.Model): class IprDocRel(models.Model):
disclosure = ForeignKey(IprDisclosureBase) disclosure = ForeignKey(IprDisclosureBase)
document = ForeignKey(DocAlias) document = ForeignKey(Document)
sections = models.TextField(blank=True) sections = models.TextField(blank=True)
revisions = models.CharField(max_length=16,blank=True) # allows strings like 01-07 revisions = models.CharField(max_length=16,blank=True) # allows strings like 01-07
@ -233,10 +233,7 @@ class IprEvent(models.Model):
'removed': 'removed_related_ipr', 'removed': 'removed_related_ipr',
} }
if self.type_id in event_type_map: if self.type_id in event_type_map:
related_docs = set() # related docs, no duplicates for doc in self.disclosure.docs.distinct():
for alias in self.disclosure.docs.all():
related_docs.update(alias.docs.all())
for doc in related_docs:
DocEvent.objects.create( DocEvent.objects.create(
type=event_type_map[self.type_id], type=event_type_map[self.type_id],
time=self.time, time=self.time,

View file

@ -16,11 +16,11 @@ from ietf.ipr.models import ( IprDisclosureBase, IprDocRel, HolderIprDisclosure,
from ietf.person.resources import PersonResource from ietf.person.resources import PersonResource
from ietf.name.resources import IprDisclosureStateNameResource from ietf.name.resources import IprDisclosureStateNameResource
from ietf.doc.resources import DocAliasResource from ietf.doc.resources import DocumentResource
class IprDisclosureBaseResource(ModelResource): class IprDisclosureBaseResource(ModelResource):
by = ToOneField(PersonResource, 'by') by = ToOneField(PersonResource, 'by')
state = ToOneField(IprDisclosureStateNameResource, 'state') state = ToOneField(IprDisclosureStateNameResource, 'state')
docs = ToManyField(DocAliasResource, 'docs', null=True) docs = ToManyField(DocumentResource, 'docs', null=True)
rel = ToManyField('ietf.ipr.resources.IprDisclosureBaseResource', 'rel', null=True) rel = ToManyField('ietf.ipr.resources.IprDisclosureBaseResource', 'rel', null=True)
class Meta: class Meta:
queryset = IprDisclosureBase.objects.all() queryset = IprDisclosureBase.objects.all()
@ -45,10 +45,9 @@ class IprDisclosureBaseResource(ModelResource):
} }
api.ipr.register(IprDisclosureBaseResource()) api.ipr.register(IprDisclosureBaseResource())
from ietf.doc.resources import DocAliasResource
class IprDocRelResource(ModelResource): class IprDocRelResource(ModelResource):
disclosure = ToOneField(IprDisclosureBaseResource, 'disclosure') disclosure = ToOneField(IprDisclosureBaseResource, 'disclosure')
document = ToOneField(DocAliasResource, 'document') document = ToOneField(DocumentResource, 'document')
class Meta: class Meta:
cache = SimpleCache() cache = SimpleCache()
queryset = IprDocRel.objects.all() queryset = IprDocRel.objects.all()
@ -66,13 +65,12 @@ api.ipr.register(IprDocRelResource())
from ietf.person.resources import PersonResource from ietf.person.resources import PersonResource
from ietf.name.resources import IprDisclosureStateNameResource, IprLicenseTypeNameResource from ietf.name.resources import IprDisclosureStateNameResource, IprLicenseTypeNameResource
from ietf.doc.resources import DocAliasResource
class HolderIprDisclosureResource(ModelResource): class HolderIprDisclosureResource(ModelResource):
by = ToOneField(PersonResource, 'by') by = ToOneField(PersonResource, 'by')
state = ToOneField(IprDisclosureStateNameResource, 'state') state = ToOneField(IprDisclosureStateNameResource, 'state')
iprdisclosurebase_ptr = ToOneField(IprDisclosureBaseResource, 'iprdisclosurebase_ptr') iprdisclosurebase_ptr = ToOneField(IprDisclosureBaseResource, 'iprdisclosurebase_ptr')
licensing = ToOneField(IprLicenseTypeNameResource, 'licensing') licensing = ToOneField(IprLicenseTypeNameResource, 'licensing')
docs = ToManyField(DocAliasResource, 'docs', null=True) docs = ToManyField(DocumentResource, 'docs', null=True)
rel = ToManyField(IprDisclosureBaseResource, 'rel', null=True) rel = ToManyField(IprDisclosureBaseResource, 'rel', null=True)
class Meta: class Meta:
cache = SimpleCache() cache = SimpleCache()
@ -111,12 +109,11 @@ api.ipr.register(HolderIprDisclosureResource())
from ietf.person.resources import PersonResource from ietf.person.resources import PersonResource
from ietf.name.resources import IprDisclosureStateNameResource from ietf.name.resources import IprDisclosureStateNameResource
from ietf.doc.resources import DocAliasResource
class ThirdPartyIprDisclosureResource(ModelResource): class ThirdPartyIprDisclosureResource(ModelResource):
by = ToOneField(PersonResource, 'by') by = ToOneField(PersonResource, 'by')
state = ToOneField(IprDisclosureStateNameResource, 'state') state = ToOneField(IprDisclosureStateNameResource, 'state')
iprdisclosurebase_ptr = ToOneField(IprDisclosureBaseResource, 'iprdisclosurebase_ptr') iprdisclosurebase_ptr = ToOneField(IprDisclosureBaseResource, 'iprdisclosurebase_ptr')
docs = ToManyField(DocAliasResource, 'docs', null=True) docs = ToManyField(DocumentResource, 'docs', null=True)
rel = ToManyField(IprDisclosureBaseResource, 'rel', null=True) rel = ToManyField(IprDisclosureBaseResource, 'rel', null=True)
class Meta: class Meta:
cache = SimpleCache() cache = SimpleCache()
@ -168,12 +165,11 @@ api.ipr.register(RelatedIprResource())
from ietf.person.resources import PersonResource from ietf.person.resources import PersonResource
from ietf.name.resources import IprDisclosureStateNameResource from ietf.name.resources import IprDisclosureStateNameResource
from ietf.doc.resources import DocAliasResource
class NonDocSpecificIprDisclosureResource(ModelResource): class NonDocSpecificIprDisclosureResource(ModelResource):
by = ToOneField(PersonResource, 'by') by = ToOneField(PersonResource, 'by')
state = ToOneField(IprDisclosureStateNameResource, 'state') state = ToOneField(IprDisclosureStateNameResource, 'state')
iprdisclosurebase_ptr = ToOneField(IprDisclosureBaseResource, 'iprdisclosurebase_ptr') iprdisclosurebase_ptr = ToOneField(IprDisclosureBaseResource, 'iprdisclosurebase_ptr')
docs = ToManyField(DocAliasResource, 'docs', null=True) docs = ToManyField(DocumentResource, 'docs', null=True)
rel = ToManyField(IprDisclosureBaseResource, 'rel', null=True) rel = ToManyField(IprDisclosureBaseResource, 'rel', null=True)
class Meta: class Meta:
cache = SimpleCache() cache = SimpleCache()
@ -207,12 +203,11 @@ api.ipr.register(NonDocSpecificIprDisclosureResource())
from ietf.person.resources import PersonResource from ietf.person.resources import PersonResource
from ietf.name.resources import IprDisclosureStateNameResource from ietf.name.resources import IprDisclosureStateNameResource
from ietf.doc.resources import DocAliasResource
class GenericIprDisclosureResource(ModelResource): class GenericIprDisclosureResource(ModelResource):
by = ToOneField(PersonResource, 'by') by = ToOneField(PersonResource, 'by')
state = ToOneField(IprDisclosureStateNameResource, 'state') state = ToOneField(IprDisclosureStateNameResource, 'state')
iprdisclosurebase_ptr = ToOneField(IprDisclosureBaseResource, 'iprdisclosurebase_ptr') iprdisclosurebase_ptr = ToOneField(IprDisclosureBaseResource, 'iprdisclosurebase_ptr')
docs = ToManyField(DocAliasResource, 'docs', null=True) docs = ToManyField(DocumentResource, 'docs', null=True)
rel = ToManyField(IprDisclosureBaseResource, 'rel', null=True) rel = ToManyField(IprDisclosureBaseResource, 'rel', null=True)
class Meta: class Meta:
cache = SimpleCache() cache = SimpleCache()

View file

@ -15,8 +15,7 @@ from django.utils import timezone
import debug # pyflakes:ignore import debug # pyflakes:ignore
from ietf.doc.models import DocAlias from ietf.doc.factories import DocumentFactory, WgDraftFactory, WgRfcFactory. RfcFactory
from ietf.doc.factories import DocumentFactory, WgDraftFactory, WgRfcFactory
from ietf.group.factories import RoleFactory from ietf.group.factories import RoleFactory
from ietf.ipr.factories import HolderIprDisclosureFactory, GenericIprDisclosureFactory, IprEventFactory from ietf.ipr.factories import HolderIprDisclosureFactory, GenericIprDisclosureFactory, IprEventFactory
from ietf.ipr.mail import (process_response_email, get_reply_to, get_update_submitter_emails, from ietf.ipr.mail import (process_response_email, get_reply_to, get_update_submitter_emails,
@ -164,7 +163,8 @@ class IprTests(TestCase):
self.assertContains(r, draft.name) self.assertContains(r, draft.name)
self.assertNotContains(r, ipr.title) self.assertNotContains(r, ipr.title)
DocAlias.objects.create(name="rfc321").docs.add(draft) rfc = RfcFactory(rfc_number=321)
draft.relateddocument_set.create(relationship_id="became_rfc",target=rfc)
# find RFC # find RFC
r = self.client.get(url + "?submit=rfc&rfc=321") r = self.client.get(url + "?submit=rfc&rfc=321")
@ -251,7 +251,7 @@ class IprTests(TestCase):
"""Add a new specific disclosure. Note: submitter does not need to be logged in. """Add a new specific disclosure. Note: submitter does not need to be logged in.
""" """
draft = WgDraftFactory() draft = WgDraftFactory()
WgRfcFactory() rfc = WgRfcFactory()
url = urlreverse("ietf.ipr.views.new", kwargs={ "type": "specific" }) url = urlreverse("ietf.ipr.views.new", kwargs={ "type": "specific" })
# successful post # successful post
@ -265,9 +265,9 @@ class IprTests(TestCase):
"ietfer_contact_info": "555-555-0101", "ietfer_contact_info": "555-555-0101",
"iprdocrel_set-TOTAL_FORMS": 2, "iprdocrel_set-TOTAL_FORMS": 2,
"iprdocrel_set-INITIAL_FORMS": 0, "iprdocrel_set-INITIAL_FORMS": 0,
"iprdocrel_set-0-document": draft.docalias.first().pk, "iprdocrel_set-0-document": draft.pk,
"iprdocrel_set-0-revisions": '00', "iprdocrel_set-0-revisions": '00',
"iprdocrel_set-1-document": DocAlias.objects.filter(name__startswith="rfc").first().pk, "iprdocrel_set-1-document": rfc.pk,
"patent_number": "SE12345678901", "patent_number": "SE12345678901",
"patent_inventor": "A. Nonymous", "patent_inventor": "A. Nonymous",
"patent_title": "A method of transferring bits", "patent_title": "A method of transferring bits",
@ -309,7 +309,7 @@ class IprTests(TestCase):
"""Add a new third-party disclosure. Note: submitter does not need to be logged in. """Add a new third-party disclosure. Note: submitter does not need to be logged in.
""" """
draft = WgDraftFactory() draft = WgDraftFactory()
WgRfcFactory() rfc = WgRfcFactory()
url = urlreverse("ietf.ipr.views.new", kwargs={ "type": "third-party" }) url = urlreverse("ietf.ipr.views.new", kwargs={ "type": "third-party" })
# successful post # successful post
@ -321,9 +321,9 @@ class IprTests(TestCase):
"ietfer_contact_info": "555-555-0101", "ietfer_contact_info": "555-555-0101",
"iprdocrel_set-TOTAL_FORMS": 2, "iprdocrel_set-TOTAL_FORMS": 2,
"iprdocrel_set-INITIAL_FORMS": 0, "iprdocrel_set-INITIAL_FORMS": 0,
"iprdocrel_set-0-document": draft.docalias.first().pk, "iprdocrel_set-0-document": draft.pk,
"iprdocrel_set-0-revisions": '00', "iprdocrel_set-0-revisions": '00',
"iprdocrel_set-1-document": DocAlias.objects.filter(name__startswith="rfc").first().pk, "iprdocrel_set-1-document": rfc.pk,
"patent_number": "SE12345678901", "patent_number": "SE12345678901",
"patent_inventor": "A. Nonymous", "patent_inventor": "A. Nonymous",
"patent_title": "A method of transferring bits", "patent_title": "A method of transferring bits",
@ -368,7 +368,7 @@ class IprTests(TestCase):
"holder_legal_name": "Test Legal", "holder_legal_name": "Test Legal",
"ietfer_contact_info": "555-555-0101", "ietfer_contact_info": "555-555-0101",
"ietfer_name": "Test Participant", "ietfer_name": "Test Participant",
"iprdocrel_set-0-document": draft.docalias.first().pk, "iprdocrel_set-0-document": draft.pk,
"iprdocrel_set-0-revisions": '00', "iprdocrel_set-0-revisions": '00',
"iprdocrel_set-INITIAL_FORMS": 0, "iprdocrel_set-INITIAL_FORMS": 0,
"iprdocrel_set-TOTAL_FORMS": 1, "iprdocrel_set-TOTAL_FORMS": 1,
@ -396,7 +396,7 @@ class IprTests(TestCase):
def test_update(self): def test_update(self):
draft = WgDraftFactory() draft = WgDraftFactory()
WgRfcFactory() rfc = WgRfcFactory()
original_ipr = HolderIprDisclosureFactory(docs=[draft,]) original_ipr = HolderIprDisclosureFactory(docs=[draft,])
# get # get
@ -417,9 +417,9 @@ class IprTests(TestCase):
"ietfer_contact_info": "555-555-0101", "ietfer_contact_info": "555-555-0101",
"iprdocrel_set-TOTAL_FORMS": 2, "iprdocrel_set-TOTAL_FORMS": 2,
"iprdocrel_set-INITIAL_FORMS": 0, "iprdocrel_set-INITIAL_FORMS": 0,
"iprdocrel_set-0-document": draft.docalias.first().pk, "iprdocrel_set-0-document": draft.pk,
"iprdocrel_set-0-revisions": '00', "iprdocrel_set-0-revisions": '00',
"iprdocrel_set-1-document": DocAlias.objects.filter(name__startswith="rfc").first().pk, "iprdocrel_set-1-document": rfc.pk,
"patent_number": "SE12345678901", "patent_number": "SE12345678901",
"patent_inventor": "A. Nonymous", "patent_inventor": "A. Nonymous",
"patent_title": "A method of transferring bits", "patent_title": "A method of transferring bits",
@ -454,7 +454,7 @@ class IprTests(TestCase):
"holder_contact_email": "test@holder.com", "holder_contact_email": "test@holder.com",
"iprdocrel_set-TOTAL_FORMS": 1, "iprdocrel_set-TOTAL_FORMS": 1,
"iprdocrel_set-INITIAL_FORMS": 0, "iprdocrel_set-INITIAL_FORMS": 0,
"iprdocrel_set-0-document": draft.docalias.first().pk, "iprdocrel_set-0-document": draft.pk,
"iprdocrel_set-0-revisions": '00', "iprdocrel_set-0-revisions": '00',
"patent_number": "SE12345678901", "patent_number": "SE12345678901",
"patent_inventor": "A. Nonymous", "patent_inventor": "A. Nonymous",

View file

@ -32,13 +32,12 @@ def get_ipr_summary(disclosure):
return summary if len(summary) <= 128 else summary[:125]+'...' return summary if len(summary) <= 128 else summary[:125]+'...'
def iprs_from_docs(aliases,**kwargs): def iprs_from_docs(docs,**kwargs):
"""Returns a list of IPRs related to doc aliases""" """Returns a list of IPRs related to docs"""
iprdocrels = [] iprdocrels = []
for alias in aliases: for document in docs:
for document in alias.docs.all(): if document.ipr(**kwargs):
if document.ipr(**kwargs): iprdocrels += document.ipr(**kwargs)
iprdocrels += document.ipr(**kwargs)
return list(set([i.disclosure for i in iprdocrels])) return list(set([i.disclosure for i in iprdocrels]))
def related_docs(doc, relationship=('replaces', 'obs')): def related_docs(doc, relationship=('replaces', 'obs')):
@ -60,17 +59,16 @@ def generate_draft_recursive_txt():
docipr = {} docipr = {}
for o in IprDocRel.objects.filter(disclosure__state='posted').select_related('document'): for o in IprDocRel.objects.filter(disclosure__state='posted').select_related('document'):
alias = o.document doc = o.document
name = alias.name name = doc.name
for document in alias.docs.all(): related_set = set(doc) | set(doc.all_related_that_doc(('obs', 'replaces')))
related = set(document.docalias.all()) | set(document.all_related_that_doc(('obs', 'replaces'))) for related in related_set:
for alias in related: name = related.name
name = alias.name if name.startswith("rfc"):
if name.startswith("rfc"): name = name.upper()
name = name.upper() if not name in docipr:
if not name in docipr: docipr[name] = []
docipr[name] = [] docipr[name].append(o.disclosure_id)
docipr[name].append(o.disclosure_id)
lines = [ "# Machine-readable list of IPR disclosures by Internet-Draft name" ] lines = [ "# Machine-readable list of IPR disclosures by Internet-Draft name" ]
for name, iprs in docipr.items(): for name, iprs in docipr.items():

View file

@ -18,7 +18,7 @@ from django.utils.html import escape
import debug # pyflakes:ignore import debug # pyflakes:ignore
from ietf.doc.models import DocAlias from ietf.doc.models import Document
from ietf.group.models import Role, Group from ietf.group.models import Role, Group
from ietf.ietfauth.utils import role_required, has_role from ietf.ietfauth.utils import role_required, has_role
from ietf.ipr.mail import (message_from_message, get_reply_to, get_update_submitter_emails) from ietf.ipr.mail import (message_from_message, get_reply_to, get_update_submitter_emails)
@ -663,18 +663,18 @@ def search(request):
doc = q doc = q
if docid: if docid:
start = DocAlias.objects.filter(name__iexact=docid) start = Document.objects.filter(name__iexact=docid)
else: else:
if search_type == "draft": if search_type == "draft":
q = normalize_draftname(q) q = normalize_draftname(q)
start = DocAlias.objects.filter(name__icontains=q, name__startswith="draft") start = Document.objects.filter(name__icontains=q, name__startswith="draft")
elif search_type == "rfc": elif search_type == "rfc":
start = DocAlias.objects.filter(name="rfc%s" % q.lstrip("0")) start = Document.objects.filter(name="rfc%s" % q.lstrip("0"))
# one match # one match
if len(start) == 1: if len(start) == 1:
first = start[0] first = start[0]
doc = first.document doc = first
docs = related_docs(first) docs = related_docs(first)
iprs = iprs_from_docs(docs,states=states) iprs = iprs_from_docs(docs,states=states)
template = "ipr/search_doc_result.html" template = "ipr/search_doc_result.html"
@ -706,7 +706,7 @@ def search(request):
# Search by wg acronym # Search by wg acronym
# Document list with IPRs # Document list with IPRs
elif search_type == "group": elif search_type == "group":
docs = list(DocAlias.objects.filter(docs__group=q)) docs = list(Document.objects.filter(docs__group=q))
related = [] related = []
for doc in docs: for doc in docs:
doc.product_of_this_wg = True doc.product_of_this_wg = True
@ -720,7 +720,7 @@ def search(request):
# Search by rfc and id title # Search by rfc and id title
# Document list with IPRs # Document list with IPRs
elif search_type == "doctitle": elif search_type == "doctitle":
docs = list(DocAlias.objects.filter(docs__title__icontains=q)) docs = list(Document.objects.filter(docs__title__icontains=q))
related = [] related = []
for doc in docs: for doc in docs:
related += related_docs(doc) related += related_docs(doc)

View file

@ -31,7 +31,7 @@ from ietf.liaisons.fields import SearchableLiaisonStatementsField
from ietf.group.models import Group from ietf.group.models import Group
from ietf.person.models import Email from ietf.person.models import Email
from ietf.person.fields import SearchableEmailField from ietf.person.fields import SearchableEmailField
from ietf.doc.models import Document, DocAlias from ietf.doc.models import Document
from ietf.utils.fields import DatepickerDateField from ietf.utils.fields import DatepickerDateField
from ietf.utils.timezone import date_today, datetime_from_date, DEADLINE_TZINFO from ietf.utils.timezone import date_today, datetime_from_date, DEADLINE_TZINFO
from functools import reduce from functools import reduce
@ -375,8 +375,6 @@ class LiaisonModelForm(forms.ModelForm):
uploaded_filename = name + extension, uploaded_filename = name + extension,
) )
) )
if created:
DocAlias.objects.create(name=attach.name).docs.add(attach)
LiaisonStatementAttachment.objects.create(statement=self.instance,document=attach) LiaisonStatementAttachment.objects.create(statement=self.instance,document=attach)
attach_file = io.open(os.path.join(settings.LIAISON_ATTACH_PATH, attach.name + extension), 'wb') attach_file = io.open(os.path.join(settings.LIAISON_ATTACH_PATH, attach.name + extension), 'wb')
attach_file.write(attached_file.read()) attach_file.write(attached_file.read())

View file

@ -19,7 +19,7 @@ from django.utils.functional import cached_property
import debug # pyflakes:ignore import debug # pyflakes:ignore
from ietf.doc.models import Document, DocAlias, State, NewRevisionDocEvent from ietf.doc.models import Document, State, NewRevisionDocEvent
from ietf.group.models import Group from ietf.group.models import Group
from ietf.group.utils import groups_managed_by from ietf.group.utils import groups_managed_by
from ietf.meeting.models import Session, Meeting, Schedule, countries, timezones, TimeSlot, Room from ietf.meeting.models import Session, Meeting, Schedule, countries, timezones, TimeSlot, Room
@ -341,7 +341,6 @@ class InterimSessionModelForm(forms.ModelForm):
# FIXME: What about agendas in html or markdown format? # FIXME: What about agendas in html or markdown format?
uploaded_filename='{}-00.txt'.format(filename)) uploaded_filename='{}-00.txt'.format(filename))
doc.set_state(State.objects.get(type__slug=doc.type.slug, slug='active')) doc.set_state(State.objects.get(type__slug=doc.type.slug, slug='active'))
DocAlias.objects.create(name=doc.name).docs.add(doc)
self.instance.sessionpresentation_set.create(document=doc, rev=doc.rev) self.instance.sessionpresentation_set.create(document=doc, rev=doc.rev)
NewRevisionDocEvent.objects.create( NewRevisionDocEvent.objects.create(
type='new_revision', type='new_revision',

View file

@ -22,7 +22,7 @@ import debug # pyflakes:ignore
from ietf.dbtemplate.models import DBTemplate from ietf.dbtemplate.models import DBTemplate
from ietf.meeting.models import (Session, SchedulingEvent, TimeSlot, from ietf.meeting.models import (Session, SchedulingEvent, TimeSlot,
Constraint, SchedTimeSessAssignment, SessionPresentation) Constraint, SchedTimeSessAssignment, SessionPresentation)
from ietf.doc.models import Document, DocAlias, State, NewRevisionDocEvent from ietf.doc.models import Document, State, NewRevisionDocEvent
from ietf.doc.models import DocEvent from ietf.doc.models import DocEvent
from ietf.group.models import Group from ietf.group.models import Group
from ietf.group.utils import can_manage_materials from ietf.group.utils import can_manage_materials
@ -622,7 +622,6 @@ def save_session_minutes_revision(session, file, ext, request, encoding=None, ap
group = session.group, group = session.group,
rev = '00', rev = '00',
) )
DocAlias.objects.create(name=doc.name).docs.add(doc)
doc.states.add(State.objects.get(type_id='minutes',slug='active')) doc.states.add(State.objects.get(type_id='minutes',slug='active'))
if session.sessionpresentation_set.filter(document=doc).exists(): if session.sessionpresentation_set.filter(document=doc).exists():
sp = session.sessionpresentation_set.get(document=doc) sp = session.sessionpresentation_set.get(document=doc)
@ -746,7 +745,6 @@ def new_doc_for_session(type_id, session):
rev = '00', rev = '00',
) )
doc.states.add(State.objects.get(type_id=type_id, slug='active')) doc.states.add(State.objects.get(type_id=type_id, slug='active'))
DocAlias.objects.create(name=doc.name).docs.add(doc)
session.sessionpresentation_set.create(document=doc,rev='00') session.sessionpresentation_set.create(document=doc,rev='00')
return doc return doc
@ -779,8 +777,6 @@ def create_recording(session, url, title=None, user=None):
rev='00', rev='00',
type_id='recording') type_id='recording')
doc.set_state(State.objects.get(type='recording', slug='active')) doc.set_state(State.objects.get(type='recording', slug='active'))
DocAlias.objects.create(name=doc.name).docs.add(doc)
# create DocEvent # create DocEvent
NewRevisionDocEvent.objects.create(type='new_revision', NewRevisionDocEvent.objects.create(type='new_revision',
@ -799,11 +795,11 @@ def get_next_sequence(group, meeting, type):
Returns the next sequence number to use for a document of type = type. Returns the next sequence number to use for a document of type = type.
Takes a group=Group object, meeting=Meeting object, type = string Takes a group=Group object, meeting=Meeting object, type = string
''' '''
aliases = DocAlias.objects.filter(name__startswith='{}-{}-{}-'.format(type, meeting.number, group.acronym)) docs = Document.objects.filter(name__startswith='{}-{}-{}-'.format(type, meeting.number, group.acronym))
if not aliases: if not docs:
return 1 return 1
aliases = aliases.order_by('name') docs = docs.order_by('name')
sequence = int(aliases.last().name.split('-')[-1]) + 1 sequence = int(docs.last().name.split('-')[-1]) + 1
return sequence return sequence
def get_activity_stats(sdate, edate): def get_activity_stats(sdate, edate):

View file

@ -47,7 +47,7 @@ from django.views.generic import RedirectView
import debug # pyflakes:ignore import debug # pyflakes:ignore
from ietf.doc.fields import SearchableDocumentsField from ietf.doc.fields import SearchableDocumentsField
from ietf.doc.models import Document, State, DocEvent, NewRevisionDocEvent, DocAlias from ietf.doc.models import Document, State, DocEvent, NewRevisionDocEvent
from ietf.group.models import Group from ietf.group.models import Group
from ietf.group.utils import can_manage_session_materials, can_manage_some_groups, can_manage_group from ietf.group.utils import can_manage_session_materials, can_manage_some_groups, can_manage_group
from ietf.person.models import Person, User from ietf.person.models import Person, User
@ -245,7 +245,6 @@ def _get_materials_doc(meeting, name):
def materials_document(request, document, num=None, ext=None): def materials_document(request, document, num=None, ext=None):
meeting=get_meeting(num,type_in=['ietf','interim']) meeting=get_meeting(num,type_in=['ietf','interim'])
num = meeting.number num = meeting.number
# This view does not allow the use of DocAliases. Right now we are probably only creating one (identity) alias, but that may not hold in the future.
try: try:
doc, rev = _get_materials_doc(meeting=meeting, name=document) doc, rev = _get_materials_doc(meeting=meeting, name=document)
except Document.DoesNotExist: except Document.DoesNotExist:
@ -2585,7 +2584,6 @@ def save_bluesheet(request, session, file, encoding='utf-8'):
rev = '00', rev = '00',
) )
doc.states.add(State.objects.get(type_id='bluesheets',slug='active')) doc.states.add(State.objects.get(type_id='bluesheets',slug='active'))
DocAlias.objects.create(name=doc.name).docs.add(doc)
session.sessionpresentation_set.create(document=doc,rev='00') session.sessionpresentation_set.create(document=doc,rev='00')
filename = '%s-%s%s'% ( doc.name, doc.rev, ext) filename = '%s-%s%s'% ( doc.name, doc.rev, ext)
doc.uploaded_filename = filename doc.uploaded_filename = filename
@ -2714,7 +2712,6 @@ def upload_session_agenda(request, session_id, num):
group = session.group, group = session.group,
rev = '00', rev = '00',
) )
DocAlias.objects.create(name=doc.name).docs.add(doc)
doc.states.add(State.objects.get(type_id='agenda',slug='active')) doc.states.add(State.objects.get(type_id='agenda',slug='active'))
if session.sessionpresentation_set.filter(document=doc).exists(): if session.sessionpresentation_set.filter(document=doc).exists():
sp = session.sessionpresentation_set.get(document=doc) sp = session.sessionpresentation_set.get(document=doc)
@ -2807,7 +2804,6 @@ def upload_session_slides(request, session_id, num, name=None):
group = session.group, group = session.group,
rev = '00', rev = '00',
) )
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='slides',slug='active'))
doc.states.add(State.objects.get(type_id='reuse_policy',slug='single')) doc.states.add(State.objects.get(type_id='reuse_policy',slug='single'))
if session.sessionpresentation_set.filter(document=doc).exists(): if session.sessionpresentation_set.filter(document=doc).exists():
@ -4525,7 +4521,6 @@ def approve_proposed_slides(request, slidesubmission_id, num):
group = submission.session.group, group = submission.session.group,
rev = '00', rev = '00',
) )
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='slides',slug='active'))
doc.states.add(State.objects.get(type_id='reuse_policy',slug='single')) doc.states.add(State.objects.get(type_id='reuse_policy',slug='single'))
if submission.session.sessionpresentation_set.filter(document=doc).exists(): if submission.session.sessionpresentation_set.filter(document=doc).exists():

View file

@ -8,7 +8,7 @@ from django.shortcuts import render, redirect, get_object_or_404
import debug # pyflakes:ignore import debug # pyflakes:ignore
from ietf.doc.utils import add_state_change_event from ietf.doc.utils import add_state_change_event
from ietf.doc.models import DocAlias, DocEvent, Document, NewRevisionDocEvent, State from ietf.doc.models import DocEvent, Document, NewRevisionDocEvent, State
from ietf.ietfauth.utils import role_required from ietf.ietfauth.utils import role_required
from ietf.meeting.forms import FileUploadForm from ietf.meeting.forms import FileUploadForm
from ietf.meeting.models import Meeting, MeetingHost from ietf.meeting.models import Meeting, MeetingHost
@ -98,10 +98,6 @@ def save_proceedings_material_doc(meeting, material_type, title, request, file=N
) )
created = True created = True
# do this even if we did not create the document, just to be sure the alias exists
alias, _ = DocAlias.objects.get_or_create(name=doc.name)
alias.docs.add(doc)
if file: if file:
if not created: if not created:
doc.rev = '{:02}'.format(int(doc.rev) + 1) doc.rev = '{:02}'.format(int(doc.rev) + 1)

View file

@ -7,7 +7,7 @@ from django.db.models.aggregates import Max
from django.utils import timezone from django.utils import timezone
from simple_history.utils import bulk_update_with_history from simple_history.utils import bulk_update_with_history
from ietf.doc.models import DocumentAuthor, DocAlias from ietf.doc.models import DocumentAuthor
from ietf.doc.utils import extract_complete_replaces_ancestor_mapping_for_docs from ietf.doc.utils import extract_complete_replaces_ancestor_mapping_for_docs
from ietf.group.models import Role from ietf.group.models import Role
from ietf.person.models import Person from ietf.person.models import Person

View file

@ -4,10 +4,10 @@
{% block pagehead %} {% block pagehead %}
<link rel="stylesheet" href="{% static "ietf/css/list.css" %}"> <link rel="stylesheet" href="{% static "ietf/css/list.css" %}">
{% endblock %} {% endblock %}
{% block title %}References to {{ alias_name }}{% endblock %} {% block title %}References to {{ name }}{% endblock %}
{% block content %} {% block content %}
{% origin %} {% origin %}
<h1>References to {{ alias_name }}</h1> <h1>References to {{ name }}</h1>
<p class="alert alert-info my-3"> <p class="alert alert-info my-3">
These dependencies are extracted using heuristics looking for strings with particular prefixes. Notably, this means that references to I-Ds by title only are not reflected here. If it's really important, please inspect the documents' references sections directly. These dependencies are extracted using heuristics looking for strings with particular prefixes. Notably, this means that references to I-Ds by title only are not reflected here. If it's really important, please inspect the documents' references sections directly.
</p> </p>
@ -42,7 +42,7 @@
<tr> <tr>
<td> <td>
<a href="{% url 'ietf.doc.views_doc.document_main' name=name %}">{{ name|prettystdname }}</a> <a href="{% url 'ietf.doc.views_doc.document_main' name=name %}">{{ name|prettystdname }}</a>
{% if ref.target.name != alias_name %} {% if ref.target.name != name %}
<br> <br>
<span class="badge rounded-pill bg-info">As {{ ref.target.name }}</span> <span class="badge rounded-pill bg-info">As {{ ref.target.name }}</span>
{% endif %} {% endif %}