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":
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):
for r in SearchRule.objects.filter(rule_type="name_contains"):
@ -182,7 +182,7 @@ def docs_tracked_by_community_list(clist):
doc_ids = set()
for doc in clist.added_docs.all():
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():
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
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":
clist = lookup_community_list(username, acronym)
@ -153,7 +153,7 @@ def track_document(request, name, username=None, acronym=None):
@login_required
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)
if not can_manage_community_list(request.user, clist):
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')
@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
def states(obj, create, extracted, **kwargs): # pylint: disable=no-self-argument
if create and extracted:

View file

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

View file

@ -13,7 +13,7 @@ from django.urls import reverse as urlreverse
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.utils.fields import SearchableField
@ -69,19 +69,3 @@ class SearchableDocumentsField(SearchableField):
class SearchableDocumentField(SearchableDocumentsField):
"""Specialized to only return one Document"""
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.mail import send_mail, send_mail_text
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_bofreq import bofreq_editors, bofreq_responsible
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)
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:
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 ]
@ -670,7 +670,7 @@ def send_review_possibly_replaces_request(request, doc, submitter_info):
to = set(addrs.to)
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:
(other_to, other_cc) = gather_address_lists('doc_replacement_suggested',doc=other_doc)
to.update(other_to)

View file

@ -355,7 +355,7 @@ class DocumentInfo(models.Model):
elif state.slug == "repl":
rs = self.related_that("replaces")
if rs:
return mark_safe("Replaced by " + ", ".join("<a href=\"%s\">%s</a>" % (urlreverse('ietf.doc.views_doc.document_main', kwargs=dict(name=alias.document.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:
return "Replaced"
elif state.slug == "active":
@ -493,10 +493,10 @@ class DocumentInfo(models.Model):
return related
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):
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):
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()
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):
name = self.canonical_name()
if name.startswith('rfc'):
@ -963,8 +949,8 @@ class Document(DocumentInfo):
from ietf.ipr.models import IprDocRel
iprs = (
IprDocRel.objects.filter(
document__in=list(self.docalias.all())
+ [x.docalias.first() for x in self.all_related_that_doc(("obs", "replaces"))] # this really is docalias until IprDocRel changes
document__in=list(self)
+ self.all_related_that_doc(("obs", "replaces"))
)
.filter(disclosure__state__in=("posted", "removed"))
.values_list("disclosure", flat=True)
@ -1157,10 +1143,6 @@ class DocHistory(DocumentInfo):
def groupmilestone_set(self):
return self.doc.groupmilestone_set
@property
def docalias(self):
return self.doc.docalias
def is_dochistory(self):
return True

View file

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

View file

@ -22,7 +22,7 @@ from django.utils import timezone
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.ietfauth.utils import can_request_rfc_publication as utils_can_request_rfc_publication
from ietf.utils.html import sanitize_fragment
@ -146,8 +146,9 @@ def doc_canonical_name(name):
key = hash(n)
found = cache.get(key)
if not found:
exact = DocAlias.objects.filter(name=n).first()
exact = Document.objects.filter(name=n)
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
return None if found == "_" else found

View file

@ -8,7 +8,7 @@ from ietf.doc.factories import (
CharterFactory,
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.person.models import Person
from ietf.utils.test_utils import TestCase
@ -25,23 +25,21 @@ class IetfFiltersTests(TestCase):
self.assertEqual(is_valid_url(url), result)
def test_urlize_ietf_docs(self):
wg_id = WgDraftFactory()
wg_id.set_state(State.objects.get(type="draft", slug="rfc"))
wg_id.std_level_id = "bcp"
wg_id.save_with_history(
rfc = WgDraftFactory(rfc_number=123456,std_level_id="bcp")
rfc.save_with_history(
[
DocEvent.objects.create(
doc=wg_id,
rev=wg_id.rev,
doc=rfc,
rev=rfc.rev,
type="published_rfc",
by=Person.objects.get(name="(System)"),
)
]
)
DocAlias.objects.create(name="rfc123456").docs.add(wg_id)
DocAlias.objects.create(name="bcp123456").docs.add(wg_id)
DocAlias.objects.create(name="std123456").docs.add(wg_id)
DocAlias.objects.create(name="fyi123456").docs.add(wg_id)
# TODO - bring these into existance when subseries are well modeled
# DocAlias.objects.create(name="bcp123456").docs.add(rfc)
# DocAlias.objects.create(name="std123456").docs.add(rfc)
# DocAlias.objects.create(name="fyi123456").docs.add(rfc)
id = IndividualDraftFactory(name="draft-me-rfc123456bis")
id_num = IndividualDraftFactory(name="draft-rosen-rfcefdp-update-2026")
@ -67,7 +65,7 @@ class IetfFiltersTests(TestCase):
),
("rfc123456", '<a href="/doc/rfc123456/">rfc123456</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'<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
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,
EditedAuthorsDocEvent )
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'))
rfc = IndividualDraftFactory(ad=ad)
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.set_state(State.objects.get(type='conflrev', slug='iesgeval'))
statchg = DocumentFactory(type_id='statchg',ad=ad)
@ -415,19 +414,6 @@ class SearchTests(TestCase):
data = r.json()
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):
# Three drafts to show with various warnings
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.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.ietfauth.utils import has_role
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(' ','-')
bofreq = Document.objects.filter(name=name,type_id='bofreq').first()
self.assertIsNotNone(bofreq)
self.assertIsNotNone(DocAlias.objects.filter(name=name).first())
self.assertEqual(bofreq.title, postdict['title'])
self.assertEqual(bofreq.rev, '00')
self.assertEqual(bofreq.get_state_slug(), 'proposed')

View file

@ -19,11 +19,8 @@ class Downref(TestCase):
super().setUp()
PersonFactory(name='Plain Man',user__username='plain')
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.docalias = self.doc.docalias.get(name='draft-ietf-mars-approved-document')
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')
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.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.models import Group
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.set_state(State.objects.get(type="slides", slug="active"))
doc.set_state(State.objects.get(type="reuse_policy", slug="multiple"))
DocAlias.objects.create(name=doc.name).docs.add(doc)
NewRevisionDocEvent.objects.create(doc=doc,by=Person.objects.get(name="(System)"),rev='00',type='new_revision',desc='New revision available')
NewRevisionDocEvent.objects.create(doc=doc,by=Person.objects.get(name="(System)"),rev='01',type='new_revision',desc='New revision available')

View file

@ -12,7 +12,7 @@ from django.template.loader import render_to_string
from django.urls import reverse as urlreverse
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.person.factories import PersonFactory
from ietf.utils.mail import outbox, empty_outbox
@ -241,7 +241,6 @@ This test section has some text.
name=name, type_id="statement"
).first()
self.assertIsNotNone(statement)
self.assertIsNotNone(DocAlias.objects.filter(name=name).first())
self.assertEqual(statement.title, postdict["title"])
self.assertEqual(statement.rev, "00")
self.assertEqual(statement.get_state_slug(), "active")

View file

@ -90,7 +90,7 @@ urlpatterns = [
url(r'^all/?$', views_search.index_all_drafts),
url(r'^active/?$', views_search.index_active_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/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):
refdoc = Document.objects.filter(name=ref[:-3])
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:
unfound.add( "%s" % ref )
continue
@ -933,8 +932,7 @@ def make_rev_history(doc):
if predecessors is None:
predecessors = []
if hasattr(doc, 'relateddocument_set'):
for alias in doc.related_that_doc('replaces'):
for document in alias.docs.all():
for document in in doc.related_that_doc('replaces'):
if document not in predecessors:
predecessors.append(document)
predecessors.extend(get_predecessors(document, predecessors))
@ -944,8 +942,7 @@ def make_rev_history(doc):
if ancestors is None:
ancestors = []
if hasattr(doc, 'relateddocument_set'):
for alias in doc.related_that('replaces'):
for document in alias.docs.all():
for document in doc.related_that('replaces'):
if document not in ancestors:
ancestors.append(document)
ancestors.extend(get_ancestors(document, ancestors))
@ -1120,6 +1117,9 @@ def generate_idnits2_rfc_status():
# 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
# 6312 was published with the wrong rfc number in it
# weird workaround in the datatracker - there are two
@ -1177,12 +1177,12 @@ def fuzzy_find_documents(name, rev=None):
sought_type = "draft"
# 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():
# No document found, see if the name/rev split has been misidentified.
# Handles some special cases, like draft-ietf-tsvwg-ieee-802-11.
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():
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 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.utils import augment_docs_and_user_with_user_info
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):
# fill in some attributes for the document table results to save
# 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_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
event_types = ("published_rfc",
@ -90,8 +91,6 @@ def fill_in_document_table_attributes(docs, have_telechat_date=False):
# misc
expirable_pks = expirable_drafts(Document.objects.filter(pk__in=doc_ids)).values_list('pk', flat=True)
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"]:
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
# errata
erratas = set(Document.objects.filter(tags="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(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(rfcs.keys())).distinct().values_list("name", flat=True))
for d in docs:
d.has_errata = d.name in erratas
d.has_verified_errata = d.name in verified_erratas
# obsoleted/updated by
for a in rfc_aliases:
d = doc_dict[a]
for rfc in rfcs:
d = doc_dict[rfc]
d.obsoleted_by_list = []
d.updated_by_list = []
# Revisit this block after RFCs become first-class Document objects
xed_by = list(
RelatedDocument.objects.filter(
target__name__in=list(rfc_aliases.values()),
target__name__in=list(rfcs.values()),
relationship__in=("obs", "updates"),
).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)
for a in DocAlias.objects.filter(
name__startswith="rfc", docs__id__in=[rel.source_id for rel in xed_by]
for a in Document.objects.filter(
type_id="rfc", docs__id__in=[rel.source_id for rel in xed_by]
)
}
xed_by.sort(
@ -158,7 +158,7 @@ def fill_in_document_table_attributes(docs, have_telechat_date=False):
re.sub(
r"rfc\s*(\d+)",
r"\1",
rel_rfc_aliases[rel.source_id],
rel_rfcs[rel.source_id],
flags=re.IGNORECASE,
)
)
@ -192,7 +192,7 @@ def prepare_document_table(request, docs, query=None, max_results=200):
# the number of queries
docs = docs.select_related("ad", "std_level", "intended_std_level", "group", "stream", "shepherd", )
docs = docs.prefetch_related("states__type", "tags", "groupmilestone_set__group", "reviewrequest_set__team",
"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 = list(docs)
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")
def edit_position(request, name, ballot_id):
"""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)
balloter = login = request.user.person
@ -256,7 +256,7 @@ def api_set_position(request):
if not name:
return err(400, "Missing document name")
try:
doc = Document.objects.get(docalias__name=name)
doc = Document.objects.get(name=name)
except Document.DoesNotExist:
return err(400, "Document not found")
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')
def send_ballot_comment(request, name, ballot_id):
"""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)
if not has_role(request.user, 'Secretariat'):
@ -413,7 +413,7 @@ def clear_ballot(request, name, ballot_type_slug):
@role_required('Area Director','Secretariat')
def defer_ballot(request, name):
"""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'):
raise Http404
interesting_state = dict(draft='draft-iesg',conflrev='conflrev',statchg='statchg')
@ -467,7 +467,7 @@ def defer_ballot(request, name):
@role_required('Area Director','Secretariat')
def undefer_ballot(request, name):
"""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'):
raise Http404
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')
def lastcalltext(request, name):
"""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"):
raise Http404
@ -589,7 +589,7 @@ class BallotWriteupForm(forms.Form):
@role_required('Area Director','Secretariat')
def ballot_writeupnotes(request, name):
"""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")
login = request.user.person
@ -700,7 +700,7 @@ class BallotRfcEditorNoteForm(forms.Form):
@role_required('Area Director','Secretariat','IAB Chair','IRTF Chair','ISE')
def ballot_rfceditornote(request, name):
"""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):
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')
def ballot_approvaltext(request, name):
"""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"):
raise Http404
@ -816,7 +816,7 @@ def ballot_approvaltext(request, name):
@role_required('Secretariat')
def approve_ballot(request, name):
"""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"):
raise Http404
@ -947,7 +947,7 @@ class ApproveDownrefsForm(forms.Form):
@role_required('Secretariat')
def approve_downrefs(request, name):
"""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"):
raise Http404
@ -1001,7 +1001,7 @@ class MakeLastCallForm(forms.Form):
@role_required('Secretariat')
def make_last_call(request, name):
"""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")):
raise Http404
@ -1109,7 +1109,7 @@ def make_last_call(request, name):
@role_required('Secretariat', 'IRTF Chair')
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"):
raise Http404
@ -1164,7 +1164,7 @@ def issue_irsg_ballot(request, name):
@role_required('Secretariat', 'IRTF Chair')
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"):
raise Http404
@ -1205,7 +1205,7 @@ def irsg_ballot_status(request):
@role_required('Secretariat', 'RSAB Chair')
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"):
raise Http404
@ -1254,7 +1254,7 @@ def issue_rsab_ballot(request, name):
@role_required('Secretariat', 'RSAB Chair')
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":
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,
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)
from ietf.doc.utils import add_state_change_event
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])
bofreq.save_with_history([e1,e2])
alias = DocAlias.objects.create(name=name)
alias.docs.set([bofreq])
bofreq_submission = form.cleaned_data['bofreq_submission']
if bofreq_submission == "upload":
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
from ietf.doc.models import ( Document, DocAlias, DocHistory, State, DocEvent,
from ietf.doc.models import ( Document, DocHistory, State, DocEvent,
BallotDocEvent, BallotPositionDocEvent, InitialReviewDocEvent, NewRevisionDocEvent,
WriteupDocEvent, TelechatDocEvent )
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,
rev=next_rev,
)
DocAlias.objects.create(name=name).docs.add(charter)
charter.set_state(
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
from ietf.doc.models import ( BallotDocEvent, BallotPositionDocEvent, DocAlias, DocEvent,
from ietf.doc.models import ( BallotDocEvent, BallotPositionDocEvent, DocEvent,
Document, NewRevisionDocEvent, State )
from ietf.doc.utils import ( add_state_change_event, close_open_ballots,
create_ballot_if_not_open, update_telechat )
@ -449,9 +449,6 @@ def build_conflict_review_document(login, doc_to_review, ad, notify, create_in_s
)
conflict_review.set_state(create_in_state)
DocAlias.objects.create( name=review_name).docs.add( conflict_review )
conflict_review.relateddocument_set.create(target=doc_to_review, relationship_id='conflrev')
c = DocEvent(type="added_comment", doc=conflict_review, rev=conflict_review.rev, by=login)

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:
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
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:
css += Path(finders.find("ietf/css/document_html_txt.css")).read_text()
draft_that_became_rfc = None
became_rfc_alias = next(iter(doc.related_that("became_rfc")), None)
if became_rfc_alias:
draft_that_became_rfc = became_rfc_alias.document
became_rfc = next(iter(doc.related_that("became_rfc")), None)
if became_rfc:
draft_that_became_rfc = became_rfc
# submission
submission = ""
if group is None:
@ -1124,7 +1124,7 @@ def get_doc_email_aliases(name):
return aliases
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)
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",
)
)
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")
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))
seen = set()
@ -1209,7 +1212,7 @@ def get_diff_revisions(request, name, doc):
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)
diff_revisions = get_diff_revisions(request, name, doc)
@ -1276,7 +1279,7 @@ def document_bibtex(request, name, rev=None):
name = name+"-"+rev
rev = None
doc = get_object_or_404(Document, docalias__name=name)
doc = get_object_or_404(Document, name=name)
doi = None
draft_became_rfc = None
@ -1285,7 +1288,7 @@ def document_bibtex(request, name, rev=None):
if doc.type_id == "draft":
latest_revision = doc.latest_event(NewRevisionDocEvent, type="new_revision")
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:
# find the entry in the history
@ -1294,13 +1297,9 @@ def document_bibtex(request, name, rev=None):
doc = h
break
if draft_became_rfc_alias:
draft_became_rfc = draft_became_rfc_alias.document
elif doc.type_id == "rfc":
# 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
# as a DocAlias, and use a method on Document to retrieve it.
# over time.
doi = f"10.17487/RFC{doc.rfc_number:04d}"
if doc.is_dochistory():
@ -1348,7 +1347,7 @@ def document_bibxml(request, name, rev=None):
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)
def text_from_writeup(event_type):
@ -1412,7 +1411,7 @@ def document_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")
if lastwriteup:
writeup_text = lastwriteup.text
@ -1449,12 +1448,12 @@ def document_shepherd_writeup_template(request, type):
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()
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):
doc = get_object_or_404(Document,docalias__name=name)
doc = get_object_or_404(Document,name=name)
refs = doc.referenced_by()
full = ( request.GET.get('full') != None )
numdocs = refs.count()
@ -1464,7 +1463,7 @@ def document_referenced_by(request, name):
numdocs=None
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",
dict(alias_name=name,
dict(name=name,
doc=doc,
numdocs=numdocs,
refs=refs,
@ -1538,7 +1537,7 @@ def document_ballot_content(request, doc, ballot_id, editable=True):
request=request)
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"))
if not ballot_id:
if all_ballots:
@ -1574,7 +1573,7 @@ def document_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)
if not ballot_id:
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):
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)
if not ballot_id:
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):
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)
ballot = get_object_or_404(BallotDocEvent,id=ballot_id)
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):
doc = get_object_or_404(Document, docalias__name=name)
doc = get_object_or_404(Document, name=name)
def extract_name(s):
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["title"] = doc.title
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["intended_std_level"] = extract_name(doc.intended_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')
def add_comment(request, name):
"""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
@ -2173,14 +2173,13 @@ def idnits2_rfc_status(request):
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"]:
raise Http404
zero_revision = None
if doc.type_id == "rfc":
draft_alias = next(iter(doc.related_that('became_rfc')), None)
if draft_alias:
draft = draft_alias.document
draft = next(iter(doc.related_that('became_rfc')), None)
if draft:
zero_revision = NewRevisionDocEvent.objects.filter(doc=draft,rev='00').first()
else:
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)')
tag = self.cleaned_data.get('substate','')
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")
# tag handling is a bit awkward since the UI still works
@ -86,7 +86,7 @@ class ChangeStateForm(forms.Form):
def change_state(request, name):
"""Change IESG state of Internet-Draft, notifying parties 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 (not doc.latest_event(type="started_iesg_process")) or doc.get_state_slug() == "expired":
raise Http404
@ -205,7 +205,7 @@ class AddIanaExpertsCommentForm(forms.Form):
@role_required('Secretariat', 'IANA')
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':
form = AddIanaExpertsCommentForm(request.POST)
if form.is_valid():
@ -231,7 +231,7 @@ class ChangeIanaStateForm(forms.Form):
def change_iana_state(request, name, state_type):
"""Change IANA review state of Internet-Draft. Normally, this is done via
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
@ -271,7 +271,7 @@ class ChangeStreamForm(forms.Form):
def change_stream(request, name):
"""Change the stream of a Document of type 'draft', notifying parties 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 not doc.type_id=='draft':
raise Http404
@ -352,7 +352,7 @@ class ReplacesForm(forms.Form):
def replaces(request, name):
"""Change 'replaces' set of a Document of type 'draft' , notifying parties
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':
raise Http404
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]
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':
raise Http404
if not (has_role(request.user, ("Secretariat", "Area Director"))
@ -451,7 +451,7 @@ class ChangeIntentionForm(forms.Form):
def change_intention(request, name):
"""Change the intended publication status of a Document of type 'draft' , notifying parties
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':
raise Http404
@ -520,7 +520,7 @@ class EditInfoForm(forms.Form):
def to_iesg(request,name):
""" 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' :
raise Http404
@ -633,7 +633,7 @@ def to_iesg(request,name):
def edit_info(request, name):
"""Edit various Internet-Draft attributes, notifying parties as
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":
raise Http404
@ -791,7 +791,7 @@ def edit_info(request, name):
@role_required('Area Director','Secretariat')
def request_resurrect(request, name):
"""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":
raise Http404
@ -814,7 +814,7 @@ def request_resurrect(request, name):
@role_required('Secretariat')
def resurrect(request, name):
"""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":
raise Http404

View file

@ -16,7 +16,7 @@ from django.urls import reverse as urlreverse
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.utils import add_state_change_event, check_common_doc_name_rules
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():
dest.write(chunk)
if action == "new":
alias, __ = DocAlias.objects.get_or_create(name=doc.name)
alias.docs.add(doc)
if prev_rev != doc.rev:
e = NewRevisionDocEvent(type="new_revision", doc=doc, rev=doc.rev)
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.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)
from ietf.name.models import (ReviewRequestStateName, ReviewAssignmentStateName, ReviewResultName,
ReviewTypeName)
@ -715,9 +715,7 @@ def complete_review(request, name, assignment_id=None, acronym=None):
name=review_name,
defaults={'type_id': 'review', 'group': team},
)
if created:
DocAlias.objects.create(name=review_name).docs.add(review)
else:
if not created:
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)
@ -1055,7 +1053,7 @@ class ReviewWishAddForm(forms.Form):
@login_required
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":
form = ReviewWishAddForm(request.user, doc, request.POST)
@ -1072,7 +1070,7 @@ def review_wish_add(request, name):
@login_required
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)
if request.method == "POST":

View file

@ -53,7 +53,7 @@ from django.utils.cache import _generate_cache_key # type: 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,
IESG_BALLOT_ACTIVE_STATES, IESG_STATCHG_CONFLREV_ACTIVE_STATES,
IESG_CHARTER_ACTIVE_STATES )
@ -166,7 +166,7 @@ def retrieve_search_results(form, all_types=False):
# 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()
# rfc/active/old check buttons
@ -248,17 +248,17 @@ def frontpage(request):
def search_for_name(request, name):
def find_unique(n):
exact = DocAlias.objects.filter(name__iexact=n).first()
exact = Document.objects.filter(name__iexact=n).first()
if exact:
return exact.name
aliases = DocAlias.objects.filter(name__istartswith=n)[:2]
if len(aliases) == 1:
return aliases[0].name
startswith = Document.objects.filter(name__istartswith=n)[:2]
if len(startswith) == 1:
return startswith.name
aliases = DocAlias.objects.filter(name__icontains=n)[:2]
if len(aliases) == 1:
return aliases[0].name
contains = Document.objects.filter(name__icontains=n)[:2]
if len(contains) == 1:
return contains[0].name
return None
@ -291,7 +291,7 @@ def search_for_name(request, name):
if redirect_to:
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
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 }))
else:
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:
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_to_skip = set()
for name, doc in draft_names:
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]
names = [
f'<a href=\"{urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=doc.name))}\">{doc.name}</a>'
for doc in drafts
]
categories.append((state,
heading,
@ -843,24 +832,11 @@ def index_all_drafts(request): # Should we rename this
))
# gather RFCs
rfc_names = DocAlias.objects.filter(docs__type_id="rfc").values_list("name", "docs__name")
names = []
names_to_skip = set()
for name, doc in rfc_names:
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]
rfcs = Document.objects.filter(docs__type_id="rfc").order_by('-rfc_number')
names = [
f'<a href=\"{urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=rfc.name))}\">{rfc.name}</a>'
for rfc in rfcs
]
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)
return render(request, "doc/index_active_drafts.html", { 'groups': groups })
def ajax_select2_search_docs(request, model_name, doc_type):
if model_name == "docalias":
model = DocAlias
else:
model = Document
def ajax_select2_search_docs(request, model_name, doc_type): # TODO - remove model_name argument...
model = Document # Earlier versions allowed searching over DocAlias which no longer exists
q = [w.strip() for w in request.GET.get('q', '').split() if w.strip()]
if not q:
objs = model.objects.none()
else:
qs = model.objects.all()
if model == Document:
qs = qs.filter(type=doc_type)
elif model == DocAlias:
qs = qs.filter(docs__type=doc_type)
qs = model.objects.filter(type=doc_type)
for t in q:
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 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.ietfauth.utils import role_required
from ietf.utils.text import xslugify
@ -241,8 +241,6 @@ def new_statement(request):
desc="Statement published",
)
statement.save_with_history([e1, e2])
alias = DocAlias.objects.create(name=name)
alias.docs.set([statement])
markdown_content = ""
if statement_submission == "upload":
if not writing_pdf:

View file

@ -21,7 +21,7 @@ from django.utils.html import escape
import debug # pyflakes:ignore
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 )
from ietf.doc.forms import AdForm
from ietf.doc.lastcall import request_last_call
@ -537,7 +537,7 @@ def start_rfc_status_change(request, name=None):
if name:
if not re.match("(?i)rfc[0-9]{1,4}",name):
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
@ -561,8 +561,6 @@ def start_rfc_status_change(request, name=None):
)
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']:
status_change.relateddocument_set.create(target=Document.objects.get(name=key),
relationship_id=form.cleaned_data['relations'][key])

View file

@ -27,7 +27,7 @@ from django.utils.html import escape
from ietf.community.models import CommunityList
from ietf.community.utils import reset_name_contains_index_for_rule
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.group.admin import GroupForm as AdminGroupForm
from ietf.group.factories import (GroupFactory, RoleFactory, GroupEventFactory,
@ -387,7 +387,6 @@ class GroupPagesTests(TestCase):
type_id="slides",
)
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'):
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.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.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
@ -186,17 +186,12 @@ def fill_in_wg_roles(group):
group.secretaries = get_roles("secr", [])
def fill_in_wg_drafts(group):
aliases = DocAlias.objects.filter(docs__type="draft", docs__group=group).prefetch_related('docs').order_by("name")
group.drafts = []
group.rfcs = []
for a in aliases:
if a.name.startswith("draft"):
group.drafts.append(a)
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()
group.drafts = Document.objects.filter(type_id="draft", group=group).order_by("name")
group.rfcs = Document.objects.filter(type_id="rfc", group=group).order_by("rfc_number")
for rfc in group.rfcs:
# TODO: remote_field?
rfc.remote_field = RelatedDocument.objects.filter(source=rfc,relationship_id__in=['obs','updates']).distinct()
rfc.invrel = RelatedDocument.objects.filter(target=rfc,relationship_id__in=['obs','updates']).distinct()
def check_group_email_aliases():
pattern = re.compile(r'expand-(.*?)(-\w+)@.*? +(.*)$')

View file

@ -14,7 +14,7 @@ from django.utils import timezone
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 IESG_SUBSTATE_TAGS
from ietf.doc.templatetags.ietf_filters import clean_whitespace
@ -31,15 +31,17 @@ def all_id_txt():
t = revision_time.get(name)
return t.strftime("%Y-%m-%d") if t else ""
rfc_aliases = dict(DocAlias.objects.filter(name__startswith="rfc",
docs__states=State.objects.get(type="draft", slug="rfc")).values_list("docs__name", "name"))
rfcs = dict()
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"),
relationship="replaces").values_list("target__name", "source__name"))
# 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"]
@ -77,9 +79,9 @@ def all_id_txt():
last_field = ""
if s.slug == "rfc":
a = rfc_aliases.get(name)
if a:
last_field = a[3:]
rfc = rfcs.get(name)
if rfc:
last_field = rfc[3:] # Rework this to take advantage of having the number at hand already.
elif s.slug == "repl":
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.prefetch_related("states")
rfc_aliases = dict(DocAlias.objects.filter(name__startswith="rfc",
docs__states=State.objects.get(type="draft", slug="rfc")).values_list("docs__name", "name"))
rfcs = dict()
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"),
relationship="replaces").values_list("target__name", "source__name"))
@ -164,9 +168,9 @@ def all_id2_txt():
# 4
rfc_number = ""
if state == "rfc":
a = rfc_aliases.get(d.name)
if a:
rfc_number = a[3:]
rfc = rfcs.get(d.name)
if rfc:
rfc_number = rfc[3:]
fields.append(rfc_number)
# 5
repl = ""

View file

@ -11,8 +11,8 @@ from django.utils import timezone
import debug # pyflakes:ignore
from ietf.doc.factories import WgDraftFactory
from ietf.doc.models import Document, DocAlias, RelatedDocument, State, LastCallDocEvent, NewRevisionDocEvent
from ietf.doc.factories import WgDraftFactory, RfcFactory
from ietf.doc.models import Document, RelatedDocument, State, LastCallDocEvent, NewRevisionDocEvent
from ietf.group.factories import GroupFactory
from ietf.name.models import DocRelationshipName
from ietf.idindex.index import all_id_txt, all_id2_txt, id_index_txt
@ -41,7 +41,8 @@ class IndexTests(TestCase):
# published
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()
self.assertTrue(draft.name + "-" + draft.rev in txt)
@ -108,7 +109,8 @@ class IndexTests(TestCase):
# test 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())
self.assertEqual(t[4], "1234")

View file

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

View file

@ -14,7 +14,7 @@ from django.utils.encoding import force_str
import debug # pyflakes:ignore
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.fields import SearchableIprDisclosuresField
from ietf.ipr.models import (IprDocRel, IprDisclosureBase, HolderIprDisclosure,
@ -95,7 +95,7 @@ class AddEmailForm(forms.Form):
return self.cleaned_data
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:
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.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.person.models import Person
from ietf.message.models import Message
@ -16,7 +16,7 @@ from ietf.utils.models import ForeignKey
class IprDisclosureBase(models.Model):
by = ForeignKey(Person) # who was logged in, or System if nobody was logged in
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)
notes = models.TextField("Additional notes", blank=True)
other_designations = models.CharField("Designations for other contributions", blank=True, max_length=255)
@ -160,7 +160,7 @@ class GenericIprDisclosure(IprDisclosureBase):
class IprDocRel(models.Model):
disclosure = ForeignKey(IprDisclosureBase)
document = ForeignKey(DocAlias)
document = ForeignKey(Document)
sections = models.TextField(blank=True)
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',
}
if self.type_id in event_type_map:
related_docs = set() # related docs, no duplicates
for alias in self.disclosure.docs.all():
related_docs.update(alias.docs.all())
for doc in related_docs:
for doc in self.disclosure.docs.distinct():
DocEvent.objects.create(
type=event_type_map[self.type_id],
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.name.resources import IprDisclosureStateNameResource
from ietf.doc.resources import DocAliasResource
from ietf.doc.resources import DocumentResource
class IprDisclosureBaseResource(ModelResource):
by = ToOneField(PersonResource, 'by')
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)
class Meta:
queryset = IprDisclosureBase.objects.all()
@ -45,10 +45,9 @@ class IprDisclosureBaseResource(ModelResource):
}
api.ipr.register(IprDisclosureBaseResource())
from ietf.doc.resources import DocAliasResource
class IprDocRelResource(ModelResource):
disclosure = ToOneField(IprDisclosureBaseResource, 'disclosure')
document = ToOneField(DocAliasResource, 'document')
document = ToOneField(DocumentResource, 'document')
class Meta:
cache = SimpleCache()
queryset = IprDocRel.objects.all()
@ -66,13 +65,12 @@ api.ipr.register(IprDocRelResource())
from ietf.person.resources import PersonResource
from ietf.name.resources import IprDisclosureStateNameResource, IprLicenseTypeNameResource
from ietf.doc.resources import DocAliasResource
class HolderIprDisclosureResource(ModelResource):
by = ToOneField(PersonResource, 'by')
state = ToOneField(IprDisclosureStateNameResource, 'state')
iprdisclosurebase_ptr = ToOneField(IprDisclosureBaseResource, 'iprdisclosurebase_ptr')
licensing = ToOneField(IprLicenseTypeNameResource, 'licensing')
docs = ToManyField(DocAliasResource, 'docs', null=True)
docs = ToManyField(DocumentResource, 'docs', null=True)
rel = ToManyField(IprDisclosureBaseResource, 'rel', null=True)
class Meta:
cache = SimpleCache()
@ -111,12 +109,11 @@ api.ipr.register(HolderIprDisclosureResource())
from ietf.person.resources import PersonResource
from ietf.name.resources import IprDisclosureStateNameResource
from ietf.doc.resources import DocAliasResource
class ThirdPartyIprDisclosureResource(ModelResource):
by = ToOneField(PersonResource, 'by')
state = ToOneField(IprDisclosureStateNameResource, 'state')
iprdisclosurebase_ptr = ToOneField(IprDisclosureBaseResource, 'iprdisclosurebase_ptr')
docs = ToManyField(DocAliasResource, 'docs', null=True)
docs = ToManyField(DocumentResource, 'docs', null=True)
rel = ToManyField(IprDisclosureBaseResource, 'rel', null=True)
class Meta:
cache = SimpleCache()
@ -168,12 +165,11 @@ api.ipr.register(RelatedIprResource())
from ietf.person.resources import PersonResource
from ietf.name.resources import IprDisclosureStateNameResource
from ietf.doc.resources import DocAliasResource
class NonDocSpecificIprDisclosureResource(ModelResource):
by = ToOneField(PersonResource, 'by')
state = ToOneField(IprDisclosureStateNameResource, 'state')
iprdisclosurebase_ptr = ToOneField(IprDisclosureBaseResource, 'iprdisclosurebase_ptr')
docs = ToManyField(DocAliasResource, 'docs', null=True)
docs = ToManyField(DocumentResource, 'docs', null=True)
rel = ToManyField(IprDisclosureBaseResource, 'rel', null=True)
class Meta:
cache = SimpleCache()
@ -207,12 +203,11 @@ api.ipr.register(NonDocSpecificIprDisclosureResource())
from ietf.person.resources import PersonResource
from ietf.name.resources import IprDisclosureStateNameResource
from ietf.doc.resources import DocAliasResource
class GenericIprDisclosureResource(ModelResource):
by = ToOneField(PersonResource, 'by')
state = ToOneField(IprDisclosureStateNameResource, 'state')
iprdisclosurebase_ptr = ToOneField(IprDisclosureBaseResource, 'iprdisclosurebase_ptr')
docs = ToManyField(DocAliasResource, 'docs', null=True)
docs = ToManyField(DocumentResource, 'docs', null=True)
rel = ToManyField(IprDisclosureBaseResource, 'rel', null=True)
class Meta:
cache = SimpleCache()

View file

@ -15,8 +15,7 @@ from django.utils import timezone
import debug # pyflakes:ignore
from ietf.doc.models import DocAlias
from ietf.doc.factories import DocumentFactory, WgDraftFactory, WgRfcFactory
from ietf.doc.factories import DocumentFactory, WgDraftFactory, WgRfcFactory. RfcFactory
from ietf.group.factories import RoleFactory
from ietf.ipr.factories import HolderIprDisclosureFactory, GenericIprDisclosureFactory, IprEventFactory
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.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
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.
"""
draft = WgDraftFactory()
WgRfcFactory()
rfc = WgRfcFactory()
url = urlreverse("ietf.ipr.views.new", kwargs={ "type": "specific" })
# successful post
@ -265,9 +265,9 @@ class IprTests(TestCase):
"ietfer_contact_info": "555-555-0101",
"iprdocrel_set-TOTAL_FORMS": 2,
"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-1-document": DocAlias.objects.filter(name__startswith="rfc").first().pk,
"iprdocrel_set-1-document": rfc.pk,
"patent_number": "SE12345678901",
"patent_inventor": "A. Nonymous",
"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.
"""
draft = WgDraftFactory()
WgRfcFactory()
rfc = WgRfcFactory()
url = urlreverse("ietf.ipr.views.new", kwargs={ "type": "third-party" })
# successful post
@ -321,9 +321,9 @@ class IprTests(TestCase):
"ietfer_contact_info": "555-555-0101",
"iprdocrel_set-TOTAL_FORMS": 2,
"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-1-document": DocAlias.objects.filter(name__startswith="rfc").first().pk,
"iprdocrel_set-1-document": rfc.pk,
"patent_number": "SE12345678901",
"patent_inventor": "A. Nonymous",
"patent_title": "A method of transferring bits",
@ -368,7 +368,7 @@ class IprTests(TestCase):
"holder_legal_name": "Test Legal",
"ietfer_contact_info": "555-555-0101",
"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-INITIAL_FORMS": 0,
"iprdocrel_set-TOTAL_FORMS": 1,
@ -396,7 +396,7 @@ class IprTests(TestCase):
def test_update(self):
draft = WgDraftFactory()
WgRfcFactory()
rfc = WgRfcFactory()
original_ipr = HolderIprDisclosureFactory(docs=[draft,])
# get
@ -417,9 +417,9 @@ class IprTests(TestCase):
"ietfer_contact_info": "555-555-0101",
"iprdocrel_set-TOTAL_FORMS": 2,
"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-1-document": DocAlias.objects.filter(name__startswith="rfc").first().pk,
"iprdocrel_set-1-document": rfc.pk,
"patent_number": "SE12345678901",
"patent_inventor": "A. Nonymous",
"patent_title": "A method of transferring bits",
@ -454,7 +454,7 @@ class IprTests(TestCase):
"holder_contact_email": "test@holder.com",
"iprdocrel_set-TOTAL_FORMS": 1,
"iprdocrel_set-INITIAL_FORMS": 0,
"iprdocrel_set-0-document": draft.docalias.first().pk,
"iprdocrel_set-0-document": draft.pk,
"iprdocrel_set-0-revisions": '00',
"patent_number": "SE12345678901",
"patent_inventor": "A. Nonymous",

View file

@ -32,11 +32,10 @@ def get_ipr_summary(disclosure):
return summary if len(summary) <= 128 else summary[:125]+'...'
def iprs_from_docs(aliases,**kwargs):
"""Returns a list of IPRs related to doc aliases"""
def iprs_from_docs(docs,**kwargs):
"""Returns a list of IPRs related to docs"""
iprdocrels = []
for alias in aliases:
for document in alias.docs.all():
for document in docs:
if document.ipr(**kwargs):
iprdocrels += document.ipr(**kwargs)
return list(set([i.disclosure for i in iprdocrels]))
@ -60,12 +59,11 @@ def generate_draft_recursive_txt():
docipr = {}
for o in IprDocRel.objects.filter(disclosure__state='posted').select_related('document'):
alias = o.document
name = alias.name
for document in alias.docs.all():
related = set(document.docalias.all()) | set(document.all_related_that_doc(('obs', 'replaces')))
for alias in related:
name = alias.name
doc = o.document
name = doc.name
related_set = set(doc) | set(doc.all_related_that_doc(('obs', 'replaces')))
for related in related_set:
name = related.name
if name.startswith("rfc"):
name = name.upper()
if not name in docipr:

View file

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

View file

@ -31,7 +31,7 @@ from ietf.liaisons.fields import SearchableLiaisonStatementsField
from ietf.group.models import Group
from ietf.person.models import Email
from ietf.person.fields import SearchableEmailField
from ietf.doc.models import Document, DocAlias
from ietf.doc.models import Document
from ietf.utils.fields import DatepickerDateField
from ietf.utils.timezone import date_today, datetime_from_date, DEADLINE_TZINFO
from functools import reduce
@ -375,8 +375,6 @@ class LiaisonModelForm(forms.ModelForm):
uploaded_filename = name + extension,
)
)
if created:
DocAlias.objects.create(name=attach.name).docs.add(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.write(attached_file.read())

View file

@ -19,7 +19,7 @@ from django.utils.functional import cached_property
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.utils import groups_managed_by
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?
uploaded_filename='{}-00.txt'.format(filename))
doc.set_state(State.objects.get(type__slug=doc.type.slug, slug='active'))
DocAlias.objects.create(name=doc.name).docs.add(doc)
self.instance.sessionpresentation_set.create(document=doc, rev=doc.rev)
NewRevisionDocEvent.objects.create(
type='new_revision',

View file

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

View file

@ -47,7 +47,7 @@ from django.views.generic import RedirectView
import debug # pyflakes:ignore
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.utils import can_manage_session_materials, can_manage_some_groups, can_manage_group
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):
meeting=get_meeting(num,type_in=['ietf','interim'])
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:
doc, rev = _get_materials_doc(meeting=meeting, name=document)
except Document.DoesNotExist:
@ -2585,7 +2584,6 @@ def save_bluesheet(request, session, file, encoding='utf-8'):
rev = '00',
)
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')
filename = '%s-%s%s'% ( doc.name, doc.rev, ext)
doc.uploaded_filename = filename
@ -2714,7 +2712,6 @@ def upload_session_agenda(request, session_id, num):
group = session.group,
rev = '00',
)
DocAlias.objects.create(name=doc.name).docs.add(doc)
doc.states.add(State.objects.get(type_id='agenda',slug='active'))
if session.sessionpresentation_set.filter(document=doc).exists():
sp = session.sessionpresentation_set.get(document=doc)
@ -2807,7 +2804,6 @@ def upload_session_slides(request, session_id, num, name=None):
group = session.group,
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='reuse_policy',slug='single'))
if session.sessionpresentation_set.filter(document=doc).exists():
@ -4525,7 +4521,6 @@ def approve_proposed_slides(request, slidesubmission_id, num):
group = submission.session.group,
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='reuse_policy',slug='single'))
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
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.meeting.forms import FileUploadForm
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
# 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 not created:
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 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.group.models import Role
from ietf.person.models import Person

View file

@ -4,10 +4,10 @@
{% block pagehead %}
<link rel="stylesheet" href="{% static "ietf/css/list.css" %}">
{% endblock %}
{% block title %}References to {{ alias_name }}{% endblock %}
{% block title %}References to {{ name }}{% endblock %}
{% block content %}
{% origin %}
<h1>References to {{ alias_name }}</h1>
<h1>References to {{ name }}</h1>
<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.
</p>
@ -42,7 +42,7 @@
<tr>
<td>
<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>
<span class="badge rounded-pill bg-info">As {{ ref.target.name }}</span>
{% endif %}