Merge pull request #6153 from rjsparks/nomoredocalias
feat: remove DocAlias
This commit is contained in:
commit
c085f0f8ec
1
.github/workflows/ci-run-tests.yml
vendored
1
.github/workflows/ci-run-tests.yml
vendored
|
@ -131,6 +131,7 @@ jobs:
|
|||
run: |
|
||||
echo "Running checks..."
|
||||
./ietf/manage.py check
|
||||
./ietf/manage.py migrate --fake-initial
|
||||
echo "Starting datatracker..."
|
||||
./ietf/manage.py runserver 0.0.0.0:8000 --settings=settings_local &
|
||||
echo "Waiting for datatracker to be ready..."
|
||||
|
|
|
@ -1,151 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# Copyright The IETF Trust 2017-2019, All Rights Reserved
|
||||
|
||||
import datetime
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from contextlib import closing
|
||||
|
||||
os.environ["DJANGO_SETTINGS_MODULE"] = "ietf.settings"
|
||||
|
||||
import django
|
||||
django.setup()
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.validators import validate_email, ValidationError
|
||||
from ietf.utils.draft import PlaintextDraft
|
||||
from ietf.submit.utils import update_authors
|
||||
from ietf.utils.timezone import date_today
|
||||
|
||||
import debug # pyflakes:ignore
|
||||
|
||||
from ietf.doc.models import Document, NewRevisionDocEvent, DocEvent, State
|
||||
from ietf.person.models import Person
|
||||
|
||||
system = Person.objects.get(name="(System)")
|
||||
expired = State.objects.get(type='draft',slug='expired')
|
||||
|
||||
names = set()
|
||||
print 'collecting draft names ...'
|
||||
versions = 0
|
||||
for p in Path(settings.INTERNET_DRAFT_PATH).glob('draft*.txt'):
|
||||
n = str(p).split('/')[-1].split('-')
|
||||
if n[-1][:2].isdigit():
|
||||
name = '-'.join(n[:-1])
|
||||
if '--' in name or '.txt' in name or '[' in name or '=' in name or '&' in name:
|
||||
continue
|
||||
if name.startswith('draft-draft-'):
|
||||
continue
|
||||
if name == 'draft-ietf-trade-iotp-v1_0-dsig':
|
||||
continue
|
||||
if len(n[-1]) != 6:
|
||||
continue
|
||||
if name.startswith('draft-mlee-'):
|
||||
continue
|
||||
names.add('-'.join(n[:-1]))
|
||||
|
||||
count=0
|
||||
print 'iterating through names ...'
|
||||
for name in sorted(names):
|
||||
if not Document.objects.filter(name=name).exists():
|
||||
paths = list(Path(settings.INTERNET_DRAFT_PATH).glob('%s-??.txt'%name))
|
||||
paths.sort()
|
||||
doc = None
|
||||
for p in paths:
|
||||
n = str(p).split('/')[-1].split('-')
|
||||
rev = n[-1][:2]
|
||||
with open(str(p)) as txt_file:
|
||||
raw = txt_file.read()
|
||||
try:
|
||||
text = raw.decode('utf8')
|
||||
except UnicodeDecodeError:
|
||||
text = raw.decode('latin1')
|
||||
try:
|
||||
draft = PlaintextDraft(text, txt_file.name, name_from_source=True)
|
||||
except Exception as e:
|
||||
print name, rev, "Can't parse", p,":",e
|
||||
continue
|
||||
if draft.errors and draft.errors.keys()!=['draftname',]:
|
||||
print "Errors - could not process", name, rev, datetime.datetime.fromtimestamp(p.stat().st_mtime, datetime.timezone.utc), draft.errors, draft.get_title().encode('utf8')
|
||||
else:
|
||||
time = datetime.datetime.fromtimestamp(p.stat().st_mtime, datetime.timezone.utc)
|
||||
if not doc:
|
||||
doc = Document.objects.create(name=name,
|
||||
time=time,
|
||||
type_id='draft',
|
||||
title=draft.get_title(),
|
||||
abstract=draft.get_abstract(),
|
||||
rev = rev,
|
||||
pages=draft.get_pagecount(),
|
||||
words=draft.get_wordcount(),
|
||||
expires=time+datetime.timedelta(settings.INTERNET_DRAFT_DAYS_TO_EXPIRE),
|
||||
)
|
||||
DocAlias.objects.create(name=doc.name).docs.add(doc)
|
||||
doc.states.add(expired)
|
||||
# update authors
|
||||
authors = []
|
||||
for author in draft.get_author_list():
|
||||
full_name, first_name, middle_initial, last_name, name_suffix, email, country, company = author
|
||||
|
||||
author_name = full_name.replace("\n", "").replace("\r", "").replace("<", "").replace(">", "").strip()
|
||||
|
||||
if email:
|
||||
try:
|
||||
validate_email(email)
|
||||
except ValidationError:
|
||||
email = ""
|
||||
|
||||
def turn_into_unicode(s):
|
||||
if s is None:
|
||||
return u""
|
||||
|
||||
if isinstance(s, unicode):
|
||||
return s
|
||||
else:
|
||||
try:
|
||||
return s.decode("utf-8")
|
||||
except UnicodeDecodeError:
|
||||
try:
|
||||
return s.decode("latin-1")
|
||||
except UnicodeDecodeError:
|
||||
return ""
|
||||
|
||||
author_name = turn_into_unicode(author_name)
|
||||
email = turn_into_unicode(email)
|
||||
company = turn_into_unicode(company)
|
||||
|
||||
authors.append({
|
||||
"name": author_name,
|
||||
"email": email,
|
||||
"affiliation": company,
|
||||
"country": country
|
||||
})
|
||||
dummysubmission=type('', (), {})() #https://stackoverflow.com/questions/19476816/creating-an-empty-object-in-python
|
||||
dummysubmission.authors = authors
|
||||
update_authors(doc,dummysubmission)
|
||||
|
||||
# add a docevent with words explaining where this came from
|
||||
events = []
|
||||
e = NewRevisionDocEvent.objects.create(
|
||||
type="new_revision",
|
||||
doc=doc,
|
||||
rev=rev,
|
||||
by=system,
|
||||
desc="New version available: <b>%s-%s.txt</b>" % (doc.name, doc.rev),
|
||||
time=time,
|
||||
)
|
||||
events.append(e)
|
||||
e = DocEvent.objects.create(
|
||||
type="comment",
|
||||
doc = doc,
|
||||
rev = rev,
|
||||
by = system,
|
||||
desc = "Revision added from id-archive on %s by %s"%(date_today(),sys.argv[0]),
|
||||
time=time,
|
||||
)
|
||||
events.append(e)
|
||||
doc.time = time
|
||||
doc.rev = rev
|
||||
doc.save_with_history(events)
|
||||
print "Added",name, rev
|
155
dev/legacy/add-old-drafts-from-archive.py
Executable file
155
dev/legacy/add-old-drafts-from-archive.py
Executable file
|
@ -0,0 +1,155 @@
|
|||
#!/usr/bin/env python
|
||||
# Copyright The IETF Trust 2017-2019, All Rights Reserved
|
||||
|
||||
## Holding on to this as documentation - it was originally in bin
|
||||
## If resuscitated, it will need to bemake python3, learn about the "rfc" document type
|
||||
## and made into a management command
|
||||
|
||||
# import datetime
|
||||
# import os
|
||||
# import sys
|
||||
# from pathlib import Path
|
||||
# from contextlib import closing
|
||||
|
||||
# os.environ["DJANGO_SETTINGS_MODULE"] = "ietf.settings"
|
||||
|
||||
# import django
|
||||
# django.setup()
|
||||
|
||||
# from django.conf import settings
|
||||
# from django.core.validators import validate_email, ValidationError
|
||||
# from ietf.utils.draft import PlaintextDraft
|
||||
# from ietf.submit.utils import update_authors
|
||||
# from ietf.utils.timezone import date_today
|
||||
|
||||
# import debug # pyflakes:ignore
|
||||
|
||||
# from ietf.doc.models import Document, NewRevisionDocEvent, DocEvent, State
|
||||
# from ietf.person.models import Person
|
||||
|
||||
# system = Person.objects.get(name="(System)")
|
||||
# expired = State.objects.get(type='draft',slug='expired')
|
||||
|
||||
# names = set()
|
||||
# print 'collecting draft names ...'
|
||||
# versions = 0
|
||||
# for p in Path(settings.INTERNET_DRAFT_PATH).glob('draft*.txt'):
|
||||
# n = str(p).split('/')[-1].split('-')
|
||||
# if n[-1][:2].isdigit():
|
||||
# name = '-'.join(n[:-1])
|
||||
# if '--' in name or '.txt' in name or '[' in name or '=' in name or '&' in name:
|
||||
# continue
|
||||
# if name.startswith('draft-draft-'):
|
||||
# continue
|
||||
# if name == 'draft-ietf-trade-iotp-v1_0-dsig':
|
||||
# continue
|
||||
# if len(n[-1]) != 6:
|
||||
# continue
|
||||
# if name.startswith('draft-mlee-'):
|
||||
# continue
|
||||
# names.add('-'.join(n[:-1]))
|
||||
|
||||
# count=0
|
||||
# print 'iterating through names ...'
|
||||
# for name in sorted(names):
|
||||
# if not Document.objects.filter(name=name).exists():
|
||||
# paths = list(Path(settings.INTERNET_DRAFT_PATH).glob('%s-??.txt'%name))
|
||||
# paths.sort()
|
||||
# doc = None
|
||||
# for p in paths:
|
||||
# n = str(p).split('/')[-1].split('-')
|
||||
# rev = n[-1][:2]
|
||||
# with open(str(p)) as txt_file:
|
||||
# raw = txt_file.read()
|
||||
# try:
|
||||
# text = raw.decode('utf8')
|
||||
# except UnicodeDecodeError:
|
||||
# text = raw.decode('latin1')
|
||||
# try:
|
||||
# draft = PlaintextDraft(text, txt_file.name, name_from_source=True)
|
||||
# except Exception as e:
|
||||
# print name, rev, "Can't parse", p,":",e
|
||||
# continue
|
||||
# if draft.errors and draft.errors.keys()!=['draftname',]:
|
||||
# print "Errors - could not process", name, rev, datetime.datetime.fromtimestamp(p.stat().st_mtime, datetime.timezone.utc), draft.errors, draft.get_title().encode('utf8')
|
||||
# else:
|
||||
# time = datetime.datetime.fromtimestamp(p.stat().st_mtime, datetime.timezone.utc)
|
||||
# if not doc:
|
||||
# doc = Document.objects.create(name=name,
|
||||
# time=time,
|
||||
# type_id='draft',
|
||||
# title=draft.get_title(),
|
||||
# abstract=draft.get_abstract(),
|
||||
# rev = rev,
|
||||
# pages=draft.get_pagecount(),
|
||||
# words=draft.get_wordcount(),
|
||||
# expires=time+datetime.timedelta(settings.INTERNET_DRAFT_DAYS_TO_EXPIRE),
|
||||
# )
|
||||
# DocAlias.objects.create(name=doc.name).docs.add(doc)
|
||||
# doc.states.add(expired)
|
||||
# # update authors
|
||||
# authors = []
|
||||
# for author in draft.get_author_list():
|
||||
# full_name, first_name, middle_initial, last_name, name_suffix, email, country, company = author
|
||||
|
||||
# author_name = full_name.replace("\n", "").replace("\r", "").replace("<", "").replace(">", "").strip()
|
||||
|
||||
# if email:
|
||||
# try:
|
||||
# validate_email(email)
|
||||
# except ValidationError:
|
||||
# email = ""
|
||||
|
||||
# def turn_into_unicode(s):
|
||||
# if s is None:
|
||||
# return u""
|
||||
|
||||
# if isinstance(s, unicode):
|
||||
# return s
|
||||
# else:
|
||||
# try:
|
||||
# return s.decode("utf-8")
|
||||
# except UnicodeDecodeError:
|
||||
# try:
|
||||
# return s.decode("latin-1")
|
||||
# except UnicodeDecodeError:
|
||||
# return ""
|
||||
|
||||
# author_name = turn_into_unicode(author_name)
|
||||
# email = turn_into_unicode(email)
|
||||
# company = turn_into_unicode(company)
|
||||
|
||||
# authors.append({
|
||||
# "name": author_name,
|
||||
# "email": email,
|
||||
# "affiliation": company,
|
||||
# "country": country
|
||||
# })
|
||||
# dummysubmission=type('', (), {})() #https://stackoverflow.com/questions/19476816/creating-an-empty-object-in-python
|
||||
# dummysubmission.authors = authors
|
||||
# update_authors(doc,dummysubmission)
|
||||
|
||||
# # add a docevent with words explaining where this came from
|
||||
# events = []
|
||||
# e = NewRevisionDocEvent.objects.create(
|
||||
# type="new_revision",
|
||||
# doc=doc,
|
||||
# rev=rev,
|
||||
# by=system,
|
||||
# desc="New version available: <b>%s-%s.txt</b>" % (doc.name, doc.rev),
|
||||
# time=time,
|
||||
# )
|
||||
# events.append(e)
|
||||
# e = DocEvent.objects.create(
|
||||
# type="comment",
|
||||
# doc = doc,
|
||||
# rev = rev,
|
||||
# by = system,
|
||||
# desc = "Revision added from id-archive on %s by %s"%(date_today(),sys.argv[0]),
|
||||
# time=time,
|
||||
# )
|
||||
# events.append(e)
|
||||
# doc.time = time
|
||||
# doc.rev = rev
|
||||
# doc.save_with_history(events)
|
||||
# print "Added",name, rev
|
8343
dev/legacy/recalculate-rfc-authors-snapshot
Normal file
8343
dev/legacy/recalculate-rfc-authors-snapshot
Normal file
File diff suppressed because it is too large
Load diff
|
@ -993,7 +993,7 @@ class RfcdiffSupportTests(TestCase):
|
|||
)
|
||||
|
||||
num_received = received
|
||||
received = self.getJson(dict(name=rfc.canonical_name()))
|
||||
received = self.getJson(dict(name=rfc.name))
|
||||
self.assertEqual(num_received, received, 'RFC by canonical name gives same result as by number')
|
||||
|
||||
received = self.getJson(dict(name=f'RfC {number}'))
|
||||
|
@ -1032,7 +1032,7 @@ class RfcdiffSupportTests(TestCase):
|
|||
draft = reload_db_objects(draft)
|
||||
|
||||
# Some old rfcs had tombstones that shouldn't be used for comparisons
|
||||
received = self.getJson(dict(name=rfc.canonical_name()))
|
||||
received = self.getJson(dict(name=rfc.name))
|
||||
self.assertTrue(received['previous'].endswith('00'))
|
||||
|
||||
def do_rfc_with_broken_history_test(self, draft_name):
|
||||
|
@ -1048,7 +1048,7 @@ class RfcdiffSupportTests(TestCase):
|
|||
received,
|
||||
dict(
|
||||
content_url=rfc.get_href(),
|
||||
name=rfc.canonical_name(),
|
||||
name=rfc.name,
|
||||
previous=f'{draft.name}-10',
|
||||
previous_url= f'{settings.IETF_ID_ARCHIVE_URL}{draft.name}-10.txt',
|
||||
),
|
||||
|
|
|
@ -328,7 +328,7 @@ def rfcdiff_latest_json(request, name, rev=None):
|
|||
response = dict()
|
||||
condition, document, history, found_rev = find_doc_for_rfcdiff(name, rev)
|
||||
if document.type_id == "rfc":
|
||||
draft_alias = next(iter(document.related_that('became_rfc')), None)
|
||||
draft = next(iter(document.related_that('became_rfc')), None)
|
||||
if condition == 'no such document':
|
||||
raise Http404
|
||||
elif condition in ('historic version', 'current version'):
|
||||
|
@ -336,8 +336,7 @@ def rfcdiff_latest_json(request, name, rev=None):
|
|||
if doc.type_id == "rfc":
|
||||
response['content_url'] = doc.get_href()
|
||||
response['name']=doc.name
|
||||
if draft_alias:
|
||||
draft = draft_alias.document
|
||||
if draft:
|
||||
prev_rev = draft.rev
|
||||
if doc.rfc_number in HAS_TOMBSTONE and prev_rev != '00':
|
||||
prev_rev = f'{(int(draft.rev)-1):02d}'
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -99,7 +99,7 @@ if newpid == 0:
|
|||
pipe("%s -a %s %s" % (settings.RSYNC_BINARY,settings.RFC_TEXT_RSYNC_SOURCE,settings.RFC_PATH))
|
||||
for rfc in new_rfcs:
|
||||
rebuild_reference_relations(rfc)
|
||||
log("Updated references for %s"%rfc.canonical_name())
|
||||
log("Updated references for %s"%rfc.name)
|
||||
except:
|
||||
subject = "Exception in updating references for new rfcs: %s : %s" % (sys.exc_info()[0],sys.exc_info()[1])
|
||||
msg = "%s\n%s\n----\n%s"%(sys.exc_info()[0],sys.exc_info()[1],traceback.format_tb(sys.exc_info()[2]))
|
||||
|
|
|
@ -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"):
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -7,7 +7,7 @@ from django.db import models
|
|||
from django import forms
|
||||
|
||||
from .models import (StateType, State, RelatedDocument, DocumentAuthor, Document, RelatedDocHistory,
|
||||
DocHistoryAuthor, DocHistory, DocAlias, DocReminder, DocEvent, NewRevisionDocEvent,
|
||||
DocHistoryAuthor, DocHistory, DocReminder, DocEvent, NewRevisionDocEvent,
|
||||
StateDocEvent, ConsensusDocEvent, BallotType, BallotDocEvent, WriteupDocEvent, LastCallDocEvent,
|
||||
TelechatDocEvent, BallotPositionDocEvent, ReviewRequestDocEvent, InitialReviewDocEvent,
|
||||
AddedMessageEvent, SubmissionDocEvent, DeletedEvent, EditedAuthorsDocEvent, DocumentURL,
|
||||
|
@ -27,10 +27,6 @@ class StateAdmin(admin.ModelAdmin):
|
|||
filter_horizontal = ["next_states"]
|
||||
admin.site.register(State, StateAdmin)
|
||||
|
||||
# class DocAliasInline(admin.TabularInline):
|
||||
# model = DocAlias
|
||||
# extra = 1
|
||||
|
||||
class DocAuthorInline(admin.TabularInline):
|
||||
model = DocumentAuthor
|
||||
raw_id_fields = ['person', 'email']
|
||||
|
@ -45,7 +41,7 @@ class RelatedDocumentInline(admin.TabularInline):
|
|||
model = RelatedDocument
|
||||
fk_name= 'source'
|
||||
def this(self, instance):
|
||||
return instance.source.canonical_name()
|
||||
return instance.source.name
|
||||
readonly_fields = ['this', ]
|
||||
fields = ['this', 'relationship', 'target', ]
|
||||
raw_id_fields = ['target']
|
||||
|
@ -71,7 +67,7 @@ class DocumentForm(forms.ModelForm):
|
|||
|
||||
class DocumentAuthorAdmin(admin.ModelAdmin):
|
||||
list_display = ['id', 'document', 'person', 'email', 'affiliation', 'country', 'order']
|
||||
search_fields = ['document__docalias__name', 'person__name', 'email__address', 'affiliation', 'country']
|
||||
search_fields = ['document__name', 'person__name', 'email__address', 'affiliation', 'country']
|
||||
raw_id_fields = ["document", "person", "email"]
|
||||
admin.site.register(DocumentAuthor, DocumentAuthorAdmin)
|
||||
|
||||
|
@ -109,14 +105,6 @@ class DocHistoryAdmin(admin.ModelAdmin):
|
|||
|
||||
admin.site.register(DocHistory, DocHistoryAdmin)
|
||||
|
||||
class DocAliasAdmin(admin.ModelAdmin):
|
||||
list_display = ['name', 'targets']
|
||||
search_fields = ['name', 'docs__name']
|
||||
raw_id_fields = ['docs']
|
||||
def targets(self, obj):
|
||||
return ', '.join([o.name for o in obj.docs.all()])
|
||||
admin.site.register(DocAlias, DocAliasAdmin)
|
||||
|
||||
class DocReminderAdmin(admin.ModelAdmin):
|
||||
list_display = ['id', 'event', 'type', 'due', 'active']
|
||||
list_filter = ['type', 'due', 'active']
|
||||
|
|
|
@ -12,7 +12,7 @@ from typing import Optional # pyflakes:ignore
|
|||
from django.conf import settings
|
||||
from django.utils import timezone
|
||||
|
||||
from ietf.doc.models import ( Document, DocEvent, NewRevisionDocEvent, DocAlias, State, DocumentAuthor,
|
||||
from ietf.doc.models import ( Document, DocEvent, NewRevisionDocEvent, State, DocumentAuthor,
|
||||
StateDocEvent, BallotPositionDocEvent, BallotDocEvent, BallotType, IRSGBallotDocEvent, TelechatDocEvent,
|
||||
DocumentActionHolder, BofreqEditorDocEvent, BofreqResponsibleDocEvent, DocExtResource )
|
||||
from ietf.group.models import Group
|
||||
|
@ -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:
|
||||
|
@ -128,12 +119,6 @@ class RfcFactory(BaseDocumentFactory):
|
|||
else:
|
||||
obj.set_state(State.objects.get(type_id='rfc',slug='published'))
|
||||
|
||||
@factory.post_generation
|
||||
def reset_canonical_name(obj, create, extracted, **kwargs):
|
||||
if hasattr(obj, '_canonical_name'):
|
||||
del obj._canonical_name
|
||||
return None
|
||||
|
||||
|
||||
class IndividualDraftFactory(BaseDocumentFactory):
|
||||
|
||||
|
@ -285,23 +270,6 @@ class ReviewFactory(BaseDocumentFactory):
|
|||
name = factory.LazyAttribute(lambda o: 'review-doesnotexist-00-%s-%s'%(o.group.acronym,date_today().isoformat()))
|
||||
group = factory.SubFactory('ietf.group.factories.GroupFactory',type_id='review')
|
||||
|
||||
class DocAliasFactory(factory.django.DjangoModelFactory):
|
||||
class Meta:
|
||||
model = DocAlias
|
||||
|
||||
@factory.post_generation
|
||||
def document(self, create, extracted, **kwargs):
|
||||
if create and extracted:
|
||||
self.docs.add(extracted)
|
||||
|
||||
@factory.post_generation
|
||||
def docs(self, create, extracted, **kwargs):
|
||||
if create and extracted:
|
||||
for doc in extracted:
|
||||
if not doc in self.docs.all():
|
||||
self.docs.add(doc)
|
||||
|
||||
|
||||
class DocEventFactory(factory.django.DjangoModelFactory):
|
||||
class Meta:
|
||||
model = DocEvent
|
||||
|
|
|
@ -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()
|
||||
|
@ -46,7 +46,7 @@ class DocumentChangesFeed(Feed):
|
|||
raise FeedDoesNotExist
|
||||
return urlreverse(
|
||||
"ietf.doc.views_doc.document_history",
|
||||
kwargs=dict(name=obj.canonical_name()),
|
||||
kwargs=dict(name=obj.name),
|
||||
)
|
||||
|
||||
def subtitle(self, obj):
|
||||
|
@ -86,7 +86,7 @@ class DocumentChangesFeed(Feed):
|
|||
return (
|
||||
urlreverse(
|
||||
"ietf.doc.views_doc.document_history",
|
||||
kwargs=dict(name=item.doc.canonical_name()),
|
||||
kwargs=dict(name=item.doc.name),
|
||||
)
|
||||
+ "#history-%s" % item.pk
|
||||
)
|
||||
|
@ -208,13 +208,13 @@ class RfcFeed(Feed):
|
|||
return [doc for doc, time in results]
|
||||
|
||||
def item_title(self, item):
|
||||
return "%s : %s" % (item.canonical_name(), item.title)
|
||||
return "%s : %s" % (item.name, item.title)
|
||||
|
||||
def item_description(self, item):
|
||||
return item.abstract
|
||||
|
||||
def item_link(self, item):
|
||||
return "https://rfc-editor.org/info/%s" % item.canonical_name()
|
||||
return "https://rfc-editor.org/info/%s" % item.name
|
||||
|
||||
def item_pubdate(self, item):
|
||||
return item.publication_time
|
||||
|
@ -229,7 +229,7 @@ class RfcFeed(Feed):
|
|||
for fmt, media_type in [("txt", "text/plain"), ("html", "text/html")]:
|
||||
media_contents.append(
|
||||
{
|
||||
"url": f"https://rfc-editor.org/rfc/{item.canonical_name()}.{fmt}",
|
||||
"url": f"https://rfc-editor.org/rfc/{item.name}.{fmt}",
|
||||
"media_type": media_type,
|
||||
"is_format_of": self.item_link(item),
|
||||
}
|
||||
|
@ -237,7 +237,7 @@ class RfcFeed(Feed):
|
|||
if item.rfc_number not in [571, 587]:
|
||||
media_contents.append(
|
||||
{
|
||||
"url": f"https://www.rfc-editor.org/rfc/pdfrfc/{item.canonical_name()}.txt.pdf",
|
||||
"url": f"https://www.rfc-editor.org/rfc/pdfrfc/{item.name}.txt.pdf",
|
||||
"media_type": "application/pdf",
|
||||
"is_format_of": self.item_link(item),
|
||||
}
|
||||
|
@ -245,7 +245,7 @@ class RfcFeed(Feed):
|
|||
else:
|
||||
media_contents.append(
|
||||
{
|
||||
"url": f"https://www.rfc-editor.org/rfc/{item.canonical_name()}.xml",
|
||||
"url": f"https://www.rfc-editor.org/rfc/{item.name}.xml",
|
||||
"media_type": "application/rfc+xml",
|
||||
}
|
||||
)
|
||||
|
@ -256,16 +256,16 @@ class RfcFeed(Feed):
|
|||
]:
|
||||
media_contents.append(
|
||||
{
|
||||
"url": f"https://rfc-editor.org/rfc/{item.canonical_name()}.{fmt}",
|
||||
"url": f"https://rfc-editor.org/rfc/{item.name}.{fmt}",
|
||||
"media_type": media_type,
|
||||
"is_format_of": f"https://www.rfc-editor.org/rfc/{item.canonical_name()}.xml",
|
||||
"is_format_of": f"https://www.rfc-editor.org/rfc/{item.name}.xml",
|
||||
}
|
||||
)
|
||||
extra.update({"media_contents": media_contents})
|
||||
|
||||
extra.update({"doi": "10.17487/%s" % item.canonical_name().upper()})
|
||||
extra.update({"doi": "10.17487/%s" % item.name.upper()})
|
||||
extra.update(
|
||||
{"doiuri": "http://dx.doi.org/10.17487/%s" % item.canonical_name().upper()}
|
||||
{"doiuri": "http://dx.doi.org/10.17487/%s" % item.name.upper()}
|
||||
)
|
||||
|
||||
# R104 Publisher (Mandatory - but we need a string from them first)
|
||||
|
|
|
@ -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
|
|
@ -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.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)
|
||||
|
|
|
@ -16,7 +16,7 @@ from pathlib import Path
|
|||
from django.conf import settings
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
from ietf.doc.models import Document, DocAlias, DocEvent, State
|
||||
from ietf.doc.models import Document, DocEvent, State
|
||||
from ietf.utils.text import xslugify
|
||||
|
||||
|
||||
|
@ -95,7 +95,6 @@ class Command(BaseCommand):
|
|||
uploaded_filename=filename,
|
||||
)
|
||||
doc.set_state(State.objects.get(type_id="statement", slug="active"))
|
||||
DocAlias.objects.create(name=doc.name).docs.add(doc)
|
||||
year, month, day = [int(part) for part in date_string.split("-")]
|
||||
e1 = DocEvent.objects.create(
|
||||
time=datetime.datetime(
|
||||
|
|
|
@ -8,7 +8,7 @@ def forward(apps, schema_editor):
|
|||
Document = apps.get_model("doc", "Document")
|
||||
RelatedDocument = apps.get_model("doc", "RelatedDocument")
|
||||
for rfc_alias in DocAlias.objects.filter(name__startswith="rfc").exclude(
|
||||
docs__type__slug="rfc"
|
||||
docs__type_id="rfc"
|
||||
):
|
||||
# Move these over to the RFC
|
||||
RelatedDocument.objects.filter(
|
||||
|
|
16
ietf/doc/migrations/0015_delete_docalias.py
Normal file
16
ietf/doc/migrations/0015_delete_docalias.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
# Copyright The IETF Trust 2023, All Rights Reserved
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("ipr", "0002_iprdocrel_no_aliases"),
|
||||
("doc", "0014_relate_hist_no_aliases"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.DeleteModel(
|
||||
name="DocAlias",
|
||||
),
|
||||
]
|
|
@ -37,7 +37,6 @@ from ietf.name.models import ( DocTypeName, DocTagName, StreamName, IntendedStdL
|
|||
from ietf.person.models import Email, Person
|
||||
from ietf.person.utils import get_active_balloters
|
||||
from ietf.utils import log
|
||||
from ietf.utils.admin import admin_link
|
||||
from ietf.utils.decorators import memoize
|
||||
from ietf.utils.validators import validate_no_control_chars
|
||||
from ietf.utils.mail import formataddr
|
||||
|
@ -173,7 +172,7 @@ class DocumentInfo(models.Model):
|
|||
if self.uploaded_filename:
|
||||
self._cached_base_name = self.uploaded_filename
|
||||
elif self.type_id == 'rfc':
|
||||
self._cached_base_name = "%s.txt" % self.canonical_name()
|
||||
self._cached_base_name = "%s.txt" % self.name
|
||||
elif self.type_id == 'draft':
|
||||
if self.is_dochistory():
|
||||
self._cached_base_name = "%s-%s.txt" % (self.doc.name, self.rev)
|
||||
|
@ -181,7 +180,7 @@ class DocumentInfo(models.Model):
|
|||
self._cached_base_name = "%s-%s.txt" % (self.name, self.rev)
|
||||
elif self.type_id in ["slides", "agenda", "minutes", "bluesheets", "procmaterials", ] and self.meeting_related():
|
||||
ext = 'pdf' if self.type_id == 'procmaterials' else 'txt'
|
||||
self._cached_base_name = f'{self.canonical_name()}-{self.rev}.{ext}'
|
||||
self._cached_base_name = f'{self.name}-{self.rev}.{ext}'
|
||||
elif self.type_id == 'review':
|
||||
# TODO: This will be wrong if a review is updated on the same day it was created (or updated more than once on the same day)
|
||||
self._cached_base_name = "%s.txt" % self.name
|
||||
|
@ -189,9 +188,9 @@ class DocumentInfo(models.Model):
|
|||
self._cached_base_name = "%s-%s.md" % (self.name, self.rev)
|
||||
else:
|
||||
if self.rev:
|
||||
self._cached_base_name = "%s-%s.txt" % (self.canonical_name(), self.rev)
|
||||
self._cached_base_name = "%s-%s.txt" % (self.name, self.rev)
|
||||
else:
|
||||
self._cached_base_name = "%s.txt" % (self.canonical_name(), )
|
||||
self._cached_base_name = "%s.txt" % (self.name, )
|
||||
return self._cached_base_name
|
||||
|
||||
def get_file_name(self):
|
||||
|
@ -355,7 +354,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 +492,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)]))
|
||||
|
@ -507,7 +506,7 @@ class DocumentInfo(models.Model):
|
|||
def replaces(self):
|
||||
return set([ d for r in self.related_that_doc("replaces") for d in r.docs.all() ])
|
||||
|
||||
def replaces_canonical_name(self):
|
||||
def replaces_name(self):
|
||||
s = set([ r.document for r in self.related_that_doc("replaces")])
|
||||
first = list(s)[0] if s else None
|
||||
return None if first is None else first.filename_with_rev()
|
||||
|
@ -540,7 +539,7 @@ class DocumentInfo(models.Model):
|
|||
if self.get_state_slug() == "rfc":
|
||||
try:
|
||||
html = Path(
|
||||
os.path.join(settings.RFC_PATH, self.canonical_name() + ".html")
|
||||
os.path.join(settings.RFC_PATH, self.name + ".html")
|
||||
).read_text()
|
||||
except (IOError, UnicodeDecodeError):
|
||||
return None
|
||||
|
@ -805,7 +804,7 @@ class Document(DocumentInfo):
|
|||
name = self.name
|
||||
url = None
|
||||
if self.type_id == "draft" and self.get_state_slug() == "rfc":
|
||||
name = self.canonical_name()
|
||||
name = self.name
|
||||
url = urlreverse('ietf.doc.views_doc.document_main', kwargs={ 'name': name }, urlconf="ietf.urls")
|
||||
elif self.type_id in ('slides','bluesheets','recording'):
|
||||
session = self.session_set.first()
|
||||
|
@ -843,22 +842,8 @@ 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()
|
||||
name = self.name
|
||||
if name.startswith('rfc'):
|
||||
name = name.upper()
|
||||
return name
|
||||
|
@ -953,8 +938,9 @@ class Document(DocumentInfo):
|
|||
|
||||
def ipr(self,states=('posted','removed')):
|
||||
"""Returns the IPR disclosures against this document (as a queryset over IprDocRel)."""
|
||||
from ietf.ipr.models import IprDocRel
|
||||
return IprDocRel.objects.filter(document__docs=self, disclosure__state__in=states)
|
||||
# from ietf.ipr.models import IprDocRel
|
||||
# return IprDocRel.objects.filter(document__docs=self, disclosure__state__in=states) # TODO - clear these comments away
|
||||
return self.iprdocrel_set.filter(disclosure__state__in=states)
|
||||
|
||||
def related_ipr(self):
|
||||
"""Returns the IPR disclosures against this document and those documents this
|
||||
|
@ -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=[self]
|
||||
+ self.all_related_that_doc(("obs", "replaces"))
|
||||
)
|
||||
.filter(disclosure__state__in=("posted", "removed"))
|
||||
.values_list("disclosure", flat=True)
|
||||
|
@ -1123,10 +1109,7 @@ class DocHistoryAuthor(DocumentAuthorInfo):
|
|||
|
||||
class DocHistory(DocumentInfo):
|
||||
doc = ForeignKey(Document, related_name="history_set")
|
||||
# the name here is used to capture the canonical name at the time
|
||||
# - it would perhaps be more elegant to simply call the attribute
|
||||
# canonical_name and replace the function on Document with a
|
||||
# property
|
||||
|
||||
name = models.CharField(max_length=255)
|
||||
|
||||
def __str__(self):
|
||||
|
@ -1138,11 +1121,6 @@ class DocHistory(DocumentInfo):
|
|||
def get_related_proceedings_material(self):
|
||||
return self.doc.get_related_proceedings_material()
|
||||
|
||||
def canonical_name(self):
|
||||
if hasattr(self, '_canonical_name'):
|
||||
return self._canonical_name
|
||||
return self.name
|
||||
|
||||
def latest_event(self, *args, **kwargs):
|
||||
kwargs["time__lte"] = self.time
|
||||
return self.doc.latest_event(*args, **kwargs)
|
||||
|
@ -1157,10 +1135,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
|
||||
|
||||
|
@ -1178,25 +1152,6 @@ class DocHistory(DocumentInfo):
|
|||
verbose_name = "document history"
|
||||
verbose_name_plural = "document histories"
|
||||
|
||||
class DocAlias(models.Model):
|
||||
"""This is used for documents that may appear under multiple names,
|
||||
and in particular for RFCs, which for continuity still keep the
|
||||
same immutable Document.name, in the tables, but will be referred
|
||||
to by RFC number, primarily, after achieving RFC status.
|
||||
"""
|
||||
name = models.CharField(max_length=255, unique=True)
|
||||
docs = models.ManyToManyField(Document, related_name='docalias')
|
||||
|
||||
@property
|
||||
def document(self):
|
||||
return self.docs.first()
|
||||
|
||||
def __str__(self):
|
||||
return u"%s-->%s" % (self.name, ','.join([force_str(d.name) for d in self.docs.all() if isinstance(d, Document) ]))
|
||||
document_link = admin_link("document")
|
||||
class Meta:
|
||||
verbose_name = "document alias"
|
||||
verbose_name_plural = "document aliases"
|
||||
|
||||
class DocReminder(models.Model):
|
||||
event = ForeignKey('DocEvent')
|
||||
|
|
|
@ -12,7 +12,7 @@ from tastypie.cache import SimpleCache
|
|||
from ietf import api
|
||||
|
||||
from ietf.doc.models import (BallotType, DeletedEvent, StateType, State, Document,
|
||||
DocumentAuthor, DocEvent, StateDocEvent, DocHistory, ConsensusDocEvent, DocAlias,
|
||||
DocumentAuthor, DocEvent, StateDocEvent, DocHistory, ConsensusDocEvent,
|
||||
TelechatDocEvent, DocReminder, LastCallDocEvent, NewRevisionDocEvent, WriteupDocEvent,
|
||||
InitialReviewDocEvent, DocHistoryAuthor, BallotDocEvent, RelatedDocument,
|
||||
RelatedDocHistory, BallotPositionDocEvent, AddedMessageEvent, SubmissionDocEvent,
|
||||
|
@ -286,21 +286,6 @@ class ConsensusDocEventResource(ModelResource):
|
|||
}
|
||||
api.doc.register(ConsensusDocEventResource())
|
||||
|
||||
class DocAliasResource(ModelResource):
|
||||
document = ToOneField(DocumentResource, 'document')
|
||||
class Meta:
|
||||
cache = SimpleCache()
|
||||
queryset = DocAlias.objects.all()
|
||||
serializer = api.Serializer()
|
||||
detail_uri_name = 'name'
|
||||
#resource_name = 'docalias'
|
||||
ordering = ['id', ]
|
||||
filtering = {
|
||||
"name": ALL,
|
||||
"document": ALL_WITH_RELATIONS,
|
||||
}
|
||||
api.doc.register(DocAliasResource())
|
||||
|
||||
from ietf.person.resources import PersonResource
|
||||
class TelechatDocEventResource(ModelResource):
|
||||
by = ToOneField(PersonResource, 'by')
|
||||
|
@ -490,7 +475,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 +494,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()
|
||||
|
|
|
@ -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
|
||||
|
@ -139,15 +139,16 @@ def rfceditor_info_url(rfcnum : str):
|
|||
return urljoin(settings.RFC_EDITOR_INFO_BASE_URL, f'rfc{rfcnum}')
|
||||
|
||||
|
||||
def doc_canonical_name(name):
|
||||
def doc_name(name):
|
||||
"""Check whether a given document exists, and return its canonical name"""
|
||||
|
||||
def find_unique(n):
|
||||
key = hash(n)
|
||||
found = cache.get(key)
|
||||
if not found:
|
||||
exact = DocAlias.objects.filter(name=n).first()
|
||||
exact = Document.objects.filter(name=n).first()
|
||||
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
|
||||
|
||||
|
@ -173,7 +174,7 @@ def doc_canonical_name(name):
|
|||
|
||||
|
||||
def link_charter_doc_match(match):
|
||||
if not doc_canonical_name(match[0]):
|
||||
if not doc_name(match[0]):
|
||||
return match[0]
|
||||
url = urlreverse(
|
||||
"ietf.doc.views_doc.document_main",
|
||||
|
@ -186,7 +187,7 @@ def link_non_charter_doc_match(match):
|
|||
name = match[0]
|
||||
# handle "I-D.*"" reference-style matches
|
||||
name = re.sub(r"^i-d\.(.*)", r"draft-\1", name, flags=re.IGNORECASE)
|
||||
cname = doc_canonical_name(name)
|
||||
cname = doc_name(name)
|
||||
if not cname:
|
||||
return match[0]
|
||||
if name == cname:
|
||||
|
@ -201,7 +202,7 @@ def link_non_charter_doc_match(match):
|
|||
url = urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=cname))
|
||||
return f'<a href="{url}">{match[0]}</a>'
|
||||
|
||||
cname = doc_canonical_name(name)
|
||||
cname = doc_name(name)
|
||||
if not cname:
|
||||
return match[0]
|
||||
if name == cname:
|
||||
|
@ -221,7 +222,7 @@ def link_non_charter_doc_match(match):
|
|||
def link_other_doc_match(match):
|
||||
doc = match[2].strip().lower()
|
||||
rev = match[3]
|
||||
if not doc_canonical_name(doc + rev):
|
||||
if not doc_name(doc + rev):
|
||||
return match[0]
|
||||
url = urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=doc + rev))
|
||||
return f'<a href="{url}">{match[1]}</a>'
|
||||
|
@ -255,6 +256,7 @@ def urlize_ietf_docs(string, autoescape=None):
|
|||
string,
|
||||
flags=re.IGNORECASE | re.ASCII,
|
||||
)
|
||||
|
||||
return mark_safe(string)
|
||||
|
||||
|
||||
|
@ -267,7 +269,7 @@ def urlize_related_source_list(related, document_html=False):
|
|||
names = set()
|
||||
titles = set()
|
||||
for rel in related:
|
||||
name=rel.source.canonical_name()
|
||||
name=rel.source.name
|
||||
title = rel.source.title
|
||||
if name in names and title in titles:
|
||||
continue
|
||||
|
@ -288,7 +290,7 @@ def urlize_related_target_list(related, document_html=False):
|
|||
"""Convert a list of RelatedDocuments into list of links using the target document's canonical name"""
|
||||
links = []
|
||||
for rel in related:
|
||||
name=rel.target.canonical_name()
|
||||
name=rel.target.name
|
||||
title = rel.target.title
|
||||
url = urlreverse('ietf.doc.views_doc.document_main' if document_html is False else 'ietf.doc.views_doc.document_html', kwargs=dict(name=name))
|
||||
name = escape(name)
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
from django.conf import settings
|
||||
|
||||
from ietf.doc.factories import (
|
||||
WgDraftFactory,
|
||||
WgRfcFactory,
|
||||
IndividualDraftFactory,
|
||||
CharterFactory,
|
||||
NewRevisionDocEventFactory,
|
||||
)
|
||||
from ietf.doc.models import State, DocEvent, DocAlias
|
||||
from ietf.doc.models import DocEvent
|
||||
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 = WgRfcFactory(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")
|
||||
|
@ -59,15 +57,17 @@ class IetfFiltersTests(TestCase):
|
|||
|
||||
cases = [
|
||||
("no change", "no change"),
|
||||
("bCp123456", '<a href="/doc/bcp123456/">bCp123456</a>'),
|
||||
("Std 00123456", '<a href="/doc/std123456/">Std 00123456</a>'),
|
||||
(
|
||||
"FyI 0123456 changes std 00123456",
|
||||
'<a href="/doc/fyi123456/">FyI 0123456</a> changes <a href="/doc/std123456/">std 00123456</a>',
|
||||
),
|
||||
|
||||
# TODO: rework subseries when we add them
|
||||
# ("bCp123456", '<a href="/doc/bcp123456/">bCp123456</a>'),
|
||||
# ("Std 00123456", '<a href="/doc/std123456/">Std 00123456</a>'),
|
||||
# (
|
||||
# "FyI 0123456 changes std 00123456",
|
||||
# '<a href="/doc/fyi123456/">FyI 0123456</a> changes <a href="/doc/std123456/">std 00123456</a>',
|
||||
# ),
|
||||
("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>',
|
||||
|
|
|
@ -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)
|
||||
|
@ -348,7 +347,7 @@ class SearchTests(TestCase):
|
|||
self.assertEqual(r.status_code, 200)
|
||||
self.assertContains(r, draft.name)
|
||||
self.assertContains(r, escape(draft.action_holders.first().name))
|
||||
self.assertContains(r, rfc.canonical_name())
|
||||
self.assertContains(r, rfc.name)
|
||||
self.assertContains(r, conflrev.name)
|
||||
self.assertContains(r, statchg.name)
|
||||
self.assertContains(r, charter.name)
|
||||
|
@ -396,7 +395,7 @@ class SearchTests(TestCase):
|
|||
r = self.client.get(urlreverse('ietf.doc.views_search.index_all_drafts'))
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertContains(r, draft.name)
|
||||
self.assertContains(r, rfc.canonical_name().upper())
|
||||
self.assertContains(r, rfc.name.upper())
|
||||
|
||||
r = self.client.get(urlreverse('ietf.doc.views_search.index_active_drafts'))
|
||||
self.assertEqual(r.status_code, 200)
|
||||
|
@ -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')])
|
||||
|
@ -656,7 +642,7 @@ Man Expires September 22, 2015 [Page 3]
|
|||
if settings.USER_PREFERENCE_DEFAULTS['full_draft'] == 'off':
|
||||
self.assertContains(r, "Show full document")
|
||||
self.assertNotContains(r, "Deimos street")
|
||||
self.assertContains(r, replaced.canonical_name())
|
||||
self.assertContains(r, replaced.name)
|
||||
self.assertContains(r, replaced.title)
|
||||
|
||||
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name)) + "?include_text=0")
|
||||
|
@ -664,7 +650,7 @@ Man Expires September 22, 2015 [Page 3]
|
|||
self.assertContains(r, "Active Internet-Draft")
|
||||
self.assertContains(r, "Show full document")
|
||||
self.assertNotContains(r, "Deimos street")
|
||||
self.assertContains(r, replaced.canonical_name())
|
||||
self.assertContains(r, replaced.name)
|
||||
self.assertContains(r, replaced.title)
|
||||
|
||||
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name)) + "?include_text=foo")
|
||||
|
@ -672,7 +658,7 @@ Man Expires September 22, 2015 [Page 3]
|
|||
self.assertContains(r, "Active Internet-Draft")
|
||||
self.assertNotContains(r, "Show full document")
|
||||
self.assertContains(r, "Deimos street")
|
||||
self.assertContains(r, replaced.canonical_name())
|
||||
self.assertContains(r, replaced.name)
|
||||
self.assertContains(r, replaced.title)
|
||||
|
||||
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name)) + "?include_text=1")
|
||||
|
@ -680,7 +666,7 @@ Man Expires September 22, 2015 [Page 3]
|
|||
self.assertContains(r, "Active Internet-Draft")
|
||||
self.assertNotContains(r, "Show full document")
|
||||
self.assertContains(r, "Deimos street")
|
||||
self.assertContains(r, replaced.canonical_name())
|
||||
self.assertContains(r, replaced.name)
|
||||
self.assertContains(r, replaced.title)
|
||||
|
||||
self.client.cookies = SimpleCookie({str('full_draft'): str('on')})
|
||||
|
@ -689,7 +675,7 @@ Man Expires September 22, 2015 [Page 3]
|
|||
self.assertContains(r, "Active Internet-Draft")
|
||||
self.assertNotContains(r, "Show full document")
|
||||
self.assertContains(r, "Deimos street")
|
||||
self.assertContains(r, replaced.canonical_name())
|
||||
self.assertContains(r, replaced.name)
|
||||
self.assertContains(r, replaced.title)
|
||||
|
||||
self.client.cookies = SimpleCookie({str('full_draft'): str('off')})
|
||||
|
@ -698,7 +684,7 @@ Man Expires September 22, 2015 [Page 3]
|
|||
self.assertContains(r, "Active Internet-Draft")
|
||||
self.assertContains(r, "Show full document")
|
||||
self.assertNotContains(r, "Deimos street")
|
||||
self.assertContains(r, replaced.canonical_name())
|
||||
self.assertContains(r, replaced.name)
|
||||
self.assertContains(r, replaced.title)
|
||||
|
||||
self.client.cookies = SimpleCookie({str('full_draft'): str('foo')})
|
||||
|
@ -708,7 +694,7 @@ Man Expires September 22, 2015 [Page 3]
|
|||
if settings.USER_PREFERENCE_DEFAULTS['full_draft'] == 'off':
|
||||
self.assertContains(r, "Show full document")
|
||||
self.assertNotContains(r, "Deimos street")
|
||||
self.assertContains(r, replaced.canonical_name())
|
||||
self.assertContains(r, replaced.name)
|
||||
self.assertContains(r, replaced.title)
|
||||
|
||||
r = self.client.get(urlreverse("ietf.doc.views_doc.document_html", kwargs=dict(name=draft.name)))
|
||||
|
@ -735,16 +721,16 @@ Man Expires September 22, 2015 [Page 3]
|
|||
rfc = WgRfcFactory()
|
||||
rfc.save_with_history([DocEventFactory(doc=rfc)])
|
||||
(Path(settings.RFC_PATH) / rfc.get_base_name()).touch()
|
||||
r = self.client.get(urlreverse("ietf.doc.views_doc.document_html", kwargs=dict(name=rfc.canonical_name())))
|
||||
r = self.client.get(urlreverse("ietf.doc.views_doc.document_html", kwargs=dict(name=rfc.name)))
|
||||
self.assertEqual(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertEqual(q('title').text(), f'RFC {rfc.rfc_number} - {rfc.title}')
|
||||
|
||||
# synonyms for the rfc should be redirected to its canonical view
|
||||
r = self.client.get(urlreverse("ietf.doc.views_doc.document_html", kwargs=dict(name=rfc.rfc_number)))
|
||||
self.assertRedirects(r, urlreverse("ietf.doc.views_doc.document_html", kwargs=dict(name=rfc.canonical_name())))
|
||||
self.assertRedirects(r, urlreverse("ietf.doc.views_doc.document_html", kwargs=dict(name=rfc.name)))
|
||||
r = self.client.get(urlreverse("ietf.doc.views_doc.document_html", kwargs=dict(name=f'RFC {rfc.rfc_number}')))
|
||||
self.assertRedirects(r, urlreverse("ietf.doc.views_doc.document_html", kwargs=dict(name=rfc.canonical_name())))
|
||||
self.assertRedirects(r, urlreverse("ietf.doc.views_doc.document_html", kwargs=dict(name=rfc.name)))
|
||||
|
||||
# expired draft
|
||||
draft.set_state(State.objects.get(type="draft", slug="expired"))
|
||||
|
@ -771,7 +757,7 @@ Man Expires September 22, 2015 [Page 3]
|
|||
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name)))
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertContains(r, "Replaced Internet-Draft")
|
||||
self.assertContains(r, replacement.canonical_name())
|
||||
self.assertContains(r, replacement.name)
|
||||
self.assertContains(r, replacement.title)
|
||||
rel.delete()
|
||||
|
||||
|
@ -801,13 +787,13 @@ Man Expires September 22, 2015 [Page 3]
|
|||
self.assertContains(r, "RFC 123456")
|
||||
self.assertContains(r, draft.name)
|
||||
# obs/updates included with RFC
|
||||
self.assertContains(r, obsoleted.canonical_name())
|
||||
self.assertContains(r, obsoleted.name)
|
||||
self.assertContains(r, obsoleted.title)
|
||||
self.assertContains(r, obsoleted_by.canonical_name())
|
||||
self.assertContains(r, obsoleted_by.name)
|
||||
self.assertContains(r, obsoleted_by.title)
|
||||
self.assertContains(r, updated.canonical_name())
|
||||
self.assertContains(r, updated.name)
|
||||
self.assertContains(r, updated.title)
|
||||
self.assertContains(r, updated_by.canonical_name())
|
||||
self.assertContains(r, updated_by.name)
|
||||
self.assertContains(r, updated_by.title)
|
||||
|
||||
# naked RFC - also weird that we test a PS from the ISE
|
||||
|
@ -859,7 +845,7 @@ Man Expires September 22, 2015 [Page 3]
|
|||
r = self.client.get(
|
||||
urlreverse(
|
||||
'ietf.doc.views_doc.document_main',
|
||||
kwargs={'name': draft.canonical_name()},
|
||||
kwargs={'name': draft.name},
|
||||
)
|
||||
)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
|
@ -2712,20 +2698,20 @@ class Idnits2SupportTests(TestCase):
|
|||
rfc = WgRfcFactory()
|
||||
draft = WgDraftFactory()
|
||||
draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc)
|
||||
url = urlreverse('ietf.doc.views_doc.idnits2_state', kwargs=dict(name=rfc.canonical_name()))
|
||||
url = urlreverse('ietf.doc.views_doc.idnits2_state', kwargs=dict(name=rfc.name))
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertContains(r,'rfcnum')
|
||||
|
||||
draft = WgDraftFactory()
|
||||
url = urlreverse('ietf.doc.views_doc.idnits2_state', kwargs=dict(name=draft.canonical_name()))
|
||||
url = urlreverse('ietf.doc.views_doc.idnits2_state', kwargs=dict(name=draft.name))
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertNotContains(r,'rfcnum')
|
||||
self.assertContains(r,'Unknown')
|
||||
|
||||
draft = WgDraftFactory(intended_std_level_id='ps')
|
||||
url = urlreverse('ietf.doc.views_doc.idnits2_state', kwargs=dict(name=draft.canonical_name()))
|
||||
url = urlreverse('ietf.doc.views_doc.idnits2_state', kwargs=dict(name=draft.name))
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertContains(r,'Proposed')
|
||||
|
|
|
@ -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
|
||||
|
@ -32,7 +32,7 @@ class BofreqTests(TestCase):
|
|||
settings_temp_path_overrides = TestCase.settings_temp_path_overrides + ['BOFREQ_PATH']
|
||||
|
||||
def write_bofreq_file(self, bofreq):
|
||||
fname = Path(settings.BOFREQ_PATH) / ("%s-%s.md" % (bofreq.canonical_name(), bofreq.rev))
|
||||
fname = Path(settings.BOFREQ_PATH) / ("%s-%s.md" % (bofreq.name, bofreq.rev))
|
||||
with fname.open("w") as f:
|
||||
f.write(f"""# This is a test bofreq.
|
||||
Version: {bofreq.rev}
|
||||
|
@ -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')
|
||||
|
|
|
@ -388,7 +388,7 @@ class ConflictReviewSubmitTests(TestCase):
|
|||
# Right now, nothing to test - we let people put whatever the web browser will let them put into that textbox
|
||||
|
||||
# sane post using textbox
|
||||
path = os.path.join(settings.CONFLICT_REVIEW_PATH, '%s-%s.txt' % (doc.canonical_name(), doc.rev))
|
||||
path = os.path.join(settings.CONFLICT_REVIEW_PATH, '%s-%s.txt' % (doc.name, doc.rev))
|
||||
self.assertEqual(doc.rev,'00')
|
||||
self.assertFalse(os.path.exists(path))
|
||||
r = self.client.post(url,dict(content="Some initial review text\n",submit_response="1"))
|
||||
|
@ -408,7 +408,7 @@ class ConflictReviewSubmitTests(TestCase):
|
|||
# A little additional setup
|
||||
# doc.rev is u'00' per the test setup - double-checking that here - if it fails, the breakage is in setUp
|
||||
self.assertEqual(doc.rev,'00')
|
||||
path = os.path.join(settings.CONFLICT_REVIEW_PATH, '%s-%s.txt' % (doc.canonical_name(), doc.rev))
|
||||
path = os.path.join(settings.CONFLICT_REVIEW_PATH, '%s-%s.txt' % (doc.name, doc.rev))
|
||||
with io.open(path,'w') as f:
|
||||
f.write('This is the old proposal.')
|
||||
f.close()
|
||||
|
@ -435,7 +435,7 @@ class ConflictReviewSubmitTests(TestCase):
|
|||
self.assertEqual(r.status_code, 302)
|
||||
doc = Document.objects.get(name='conflict-review-imaginary-irtf-submission')
|
||||
self.assertEqual(doc.rev,'01')
|
||||
path = os.path.join(settings.CONFLICT_REVIEW_PATH, '%s-%s.txt' % (doc.canonical_name(), doc.rev))
|
||||
path = os.path.join(settings.CONFLICT_REVIEW_PATH, '%s-%s.txt' % (doc.name, doc.rev))
|
||||
with io.open(path) as f:
|
||||
self.assertEqual(f.read(),"This is a new proposal.")
|
||||
f.close()
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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')
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ import ietf.review.mailarch
|
|||
|
||||
from ietf.doc.factories import ( NewRevisionDocEventFactory, IndividualDraftFactory, WgDraftFactory,
|
||||
WgRfcFactory, ReviewFactory, DocumentFactory)
|
||||
from ietf.doc.models import ( Document, DocumentAuthor, RelatedDocument, DocEvent, ReviewRequestDocEvent,
|
||||
from ietf.doc.models import ( DocumentAuthor, RelatedDocument, DocEvent, ReviewRequestDocEvent,
|
||||
ReviewAssignmentDocEvent, )
|
||||
from ietf.group.factories import RoleFactory, ReviewTeamFactory
|
||||
from ietf.group.models import Group
|
||||
|
@ -922,7 +922,8 @@ class ReviewTests(TestCase):
|
|||
date_today().isoformat(),
|
||||
]
|
||||
review_name = "-".join(c for c in name_components if c).lower()
|
||||
Document.objects.create(name=review_name,type_id='review',group=assignment.review_request.team)
|
||||
|
||||
ReviewFactory(name=review_name,type_id='review',group=assignment.review_request.team)
|
||||
|
||||
r = self.client.post(url, data={
|
||||
"result": ReviewResultName.objects.get(reviewteamsettings_review_results_set__group=assignment.review_request.team, slug="ready").pk,
|
||||
|
@ -938,10 +939,9 @@ class ReviewTests(TestCase):
|
|||
})
|
||||
self.assertEqual(r.status_code, 302)
|
||||
r2 = self.client.get(r.url)
|
||||
# FIXME-LARS: this fails when the tests are run with --debug-mode, i.e., DEBUG is set:
|
||||
if not settings.DEBUG:
|
||||
self.assertEqual(len(r2.context['messages']),1)
|
||||
self.assertIn('Attempt to save review failed', list(r2.context['messages'])[0].message)
|
||||
self.assertEqual(r2.status_code, 200)
|
||||
self.assertEqual(len(r2.context['messages']),1)
|
||||
self.assertIn('Attempt to save review failed', list(r2.context['messages'])[0].message)
|
||||
|
||||
def test_partially_complete_review(self):
|
||||
assignment, url = self.setup_complete_review_test()
|
||||
|
|
|
@ -41,7 +41,7 @@ class IssueRSABBallotTests(TestCase):
|
|||
self.client.login(username="rsab-chair", password="rsab-chair+password")
|
||||
|
||||
for name in [
|
||||
doc.canonical_name()
|
||||
doc.name
|
||||
for doc in (individual_draft, wg_draft, rg_draft, ed_rfc)
|
||||
]:
|
||||
url = urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=name))
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -396,9 +396,9 @@ class StatusChangeTests(TestCase):
|
|||
self.assertTrue(notification['Subject'].startswith('Approved:'))
|
||||
notification_text = get_payload_text(notification)
|
||||
self.assertIn('The AD has approved changing the status', notification_text)
|
||||
self.assertIn(Document.objects.get(name='rfc9999').canonical_name(), notification_text)
|
||||
self.assertIn(Document.objects.get(name='rfc9998').canonical_name(), notification_text)
|
||||
self.assertNotIn(Document.objects.get(name='rfc14').canonical_name(), notification_text)
|
||||
self.assertIn(Document.objects.get(name='rfc9999').name, notification_text)
|
||||
self.assertIn(Document.objects.get(name='rfc9998').name, notification_text)
|
||||
self.assertNotIn(Document.objects.get(name='rfc14').name, notification_text)
|
||||
self.assertNotIn('No value found for', notification_text) # make sure all interpolation values were set
|
||||
else:
|
||||
self.assertEqual(len(outbox), 0)
|
||||
|
@ -501,7 +501,7 @@ class StatusChangeSubmitTests(TestCase):
|
|||
# Right now, nothing to test - we let people put whatever the web browser will let them put into that textbox
|
||||
|
||||
# sane post using textbox
|
||||
path = os.path.join(settings.STATUS_CHANGE_PATH, '%s-%s.txt' % (doc.canonical_name(), doc.rev))
|
||||
path = os.path.join(settings.STATUS_CHANGE_PATH, '%s-%s.txt' % (doc.name, doc.rev))
|
||||
self.assertEqual(doc.rev,'00')
|
||||
self.assertFalse(os.path.exists(path))
|
||||
r = self.client.post(url,dict(content="Some initial review text\n",submit_response="1"))
|
||||
|
@ -520,7 +520,7 @@ class StatusChangeSubmitTests(TestCase):
|
|||
# A little additional setup
|
||||
# doc.rev is u'00' per the test setup - double-checking that here - if it fails, the breakage is in setUp
|
||||
self.assertEqual(doc.rev,'00')
|
||||
path = os.path.join(settings.STATUS_CHANGE_PATH, '%s-%s.txt' % (doc.canonical_name(), doc.rev))
|
||||
path = os.path.join(settings.STATUS_CHANGE_PATH, '%s-%s.txt' % (doc.name, doc.rev))
|
||||
with io.open(path,'w') as f:
|
||||
f.write('This is the old proposal.')
|
||||
f.close()
|
||||
|
@ -552,7 +552,7 @@ class StatusChangeSubmitTests(TestCase):
|
|||
self.assertEqual(r.status_code, 302)
|
||||
doc = Document.objects.get(name='status-change-imaginary-mid-review')
|
||||
self.assertEqual(doc.rev,'01')
|
||||
path = os.path.join(settings.STATUS_CHANGE_PATH, '%s-%s.txt' % (doc.canonical_name(), doc.rev))
|
||||
path = os.path.join(settings.STATUS_CHANGE_PATH, '%s-%s.txt' % (doc.name, doc.rev))
|
||||
with io.open(path) as f:
|
||||
self.assertEqual(f.read(),"This is a new proposal.")
|
||||
f.close()
|
||||
|
|
|
@ -340,16 +340,16 @@ class RebuildReferenceRelationsTests(TestCase):
|
|||
'Test conditions set up incorrectly: wrong prior document relationships')
|
||||
for other_doc in [self.normative, self.informative, self.unknown]:
|
||||
self.assertEqual(
|
||||
self.doc.relateddocument_set.filter(target__name=other_doc.canonical_name()).count(),
|
||||
self.doc.relateddocument_set.filter(target__name=other_doc.name).count(),
|
||||
0,
|
||||
'Test conditions set up incorrectly: new documents already related',
|
||||
)
|
||||
|
||||
def _get_refs_return_value(self):
|
||||
return {
|
||||
self.normative.canonical_name(): Draft.REF_TYPE_NORMATIVE,
|
||||
self.informative.canonical_name(): Draft.REF_TYPE_INFORMATIVE,
|
||||
self.unknown.canonical_name(): Draft.REF_TYPE_UNKNOWN,
|
||||
self.normative.name: Draft.REF_TYPE_NORMATIVE,
|
||||
self.informative.name: Draft.REF_TYPE_INFORMATIVE,
|
||||
self.unknown.name: Draft.REF_TYPE_UNKNOWN,
|
||||
'draft-not-found': Draft.REF_TYPE_NORMATIVE,
|
||||
}
|
||||
|
||||
|
@ -388,9 +388,9 @@ class RebuildReferenceRelationsTests(TestCase):
|
|||
self.assertCountEqual(
|
||||
self.doc.relateddocument_set.values_list('target__name', 'relationship__slug'),
|
||||
[
|
||||
(self.normative.canonical_name(), 'refnorm'),
|
||||
(self.informative.canonical_name(), 'refinfo'),
|
||||
(self.unknown.canonical_name(), 'refunk'),
|
||||
(self.normative.name, 'refnorm'),
|
||||
(self.informative.name, 'refinfo'),
|
||||
(self.unknown.name, 'refunk'),
|
||||
(self.updated.name, 'updates'),
|
||||
]
|
||||
)
|
||||
|
@ -419,9 +419,9 @@ class RebuildReferenceRelationsTests(TestCase):
|
|||
self.assertCountEqual(
|
||||
self.doc.relateddocument_set.values_list('target__name', 'relationship__slug'),
|
||||
[
|
||||
(self.normative.canonical_name(), 'refnorm'),
|
||||
(self.informative.canonical_name(), 'refinfo'),
|
||||
(self.unknown.canonical_name(), 'refunk'),
|
||||
(self.normative.name, 'refnorm'),
|
||||
(self.informative.name, 'refinfo'),
|
||||
(self.unknown.name, 'refunk'),
|
||||
(self.updated.name, 'updates'),
|
||||
]
|
||||
)
|
||||
|
@ -451,9 +451,9 @@ class RebuildReferenceRelationsTests(TestCase):
|
|||
self.assertCountEqual(
|
||||
self.doc.relateddocument_set.values_list('target__name', 'relationship__slug'),
|
||||
[
|
||||
(self.normative.canonical_name(), 'refnorm'),
|
||||
(self.informative.canonical_name(), 'refinfo'),
|
||||
(self.unknown.canonical_name(), 'refunk'),
|
||||
(self.normative.name, 'refnorm'),
|
||||
(self.informative.name, 'refinfo'),
|
||||
(self.unknown.name, 'refunk'),
|
||||
(self.updated.name, 'updates'),
|
||||
]
|
||||
)
|
||||
|
|
|
@ -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),
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ def save_document_in_history(doc):
|
|||
# copy fields
|
||||
fields = get_model_fields_as_dict(doc)
|
||||
fields["doc"] = doc
|
||||
fields["name"] = doc.canonical_name()
|
||||
fields["name"] = doc.name
|
||||
|
||||
dochist = DocHistory(**fields)
|
||||
dochist.save()
|
||||
|
@ -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,22 +932,20 @@ 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():
|
||||
if document not in predecessors:
|
||||
predecessors.append(document)
|
||||
predecessors.extend(get_predecessors(document, predecessors))
|
||||
for document in doc.related_that_doc('replaces'):
|
||||
if document not in predecessors:
|
||||
predecessors.append(document)
|
||||
predecessors.extend(get_predecessors(document, predecessors))
|
||||
return predecessors
|
||||
|
||||
def get_ancestors(doc, ancestors = None):
|
||||
if ancestors is None:
|
||||
ancestors = []
|
||||
if hasattr(doc, 'relateddocument_set'):
|
||||
for alias in doc.related_that('replaces'):
|
||||
for document in alias.docs.all():
|
||||
if document not in ancestors:
|
||||
ancestors.append(document)
|
||||
ancestors.extend(get_ancestors(document, ancestors))
|
||||
for document in doc.related_that('replaces'):
|
||||
if document not in ancestors:
|
||||
ancestors.append(document)
|
||||
ancestors.extend(get_ancestors(document, ancestors))
|
||||
return ancestors
|
||||
|
||||
def get_replaces_tree(doc):
|
||||
|
@ -981,8 +978,8 @@ def make_rev_history(doc):
|
|||
if e:
|
||||
url = urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=e.doc))
|
||||
history[url] = {
|
||||
'name': e.doc.canonical_name(),
|
||||
'rev': e.doc.canonical_name(),
|
||||
'name': e.doc.name,
|
||||
'rev': e.doc.name,
|
||||
'published': e.time.isoformat(),
|
||||
'url': url
|
||||
}
|
||||
|
@ -1120,12 +1117,15 @@ def generate_idnits2_rfc_status():
|
|||
|
||||
# Workarounds for unusual states in the datatracker
|
||||
|
||||
# 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
|
||||
# DocAliases starting with rfc - the canonical name code
|
||||
# searches for the lexically highest alias starting with rfc
|
||||
# which is getting lucky.
|
||||
# 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
|
||||
# DocAliases starting with rfc - the canonical name code
|
||||
# searches for the lexically highest alias starting with rfc
|
||||
# which is getting lucky.
|
||||
blob[6312 - 1] = 'O'
|
||||
|
||||
# RFC200 is an old RFC List by Number
|
||||
|
@ -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
|
||||
|
||||
|
|
|
@ -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", 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:
|
||||
|
@ -249,7 +249,7 @@ def prepare_document_table(request, docs, query=None, max_results=200):
|
|||
if rfc_num is not None:
|
||||
res.append(rfc_num)
|
||||
else:
|
||||
res.append(d.canonical_name())
|
||||
res.append(d.name)
|
||||
|
||||
return res
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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"])
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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 )
|
||||
|
@ -171,7 +171,7 @@ class UploadForm(forms.Form):
|
|||
return get_cleaned_text_file_content(self.cleaned_data["txt"])
|
||||
|
||||
def save(self, review):
|
||||
filename = os.path.join(settings.CONFLICT_REVIEW_PATH, '%s-%s.txt' % (review.canonical_name(), review.rev))
|
||||
filename = os.path.join(settings.CONFLICT_REVIEW_PATH, '%s-%s.txt' % (review.name, review.rev))
|
||||
with io.open(filename, 'w', encoding='utf-8') as destination:
|
||||
if self.cleaned_data['txt']:
|
||||
destination.write(self.cleaned_data['txt'])
|
||||
|
@ -185,7 +185,7 @@ def submit(request, name):
|
|||
|
||||
login = request.user.person
|
||||
|
||||
path = os.path.join(settings.CONFLICT_REVIEW_PATH, '%s-%s.txt' % (review.canonical_name(), review.rev))
|
||||
path = os.path.join(settings.CONFLICT_REVIEW_PATH, '%s-%s.txt' % (review.name, review.rev))
|
||||
not_uploaded_yet = review.rev == "00" and not os.path.exists(path)
|
||||
|
||||
if not_uploaded_yet:
|
||||
|
@ -202,7 +202,7 @@ def submit(request, name):
|
|||
|
||||
events = []
|
||||
e = NewRevisionDocEvent(doc=review, by=login, type="new_revision")
|
||||
e.desc = "New version available: <b>%s-%s.txt</b>" % (review.canonical_name(), review.rev)
|
||||
e.desc = "New version available: <b>%s-%s.txt</b>" % (review.name, review.rev)
|
||||
e.rev = review.rev
|
||||
e.save()
|
||||
events.append(e)
|
||||
|
@ -234,7 +234,7 @@ def submit(request, name):
|
|||
dict(),
|
||||
))
|
||||
else:
|
||||
filename = os.path.join(settings.CONFLICT_REVIEW_PATH, '%s-%s.txt' % (review.canonical_name(), review.rev))
|
||||
filename = os.path.join(settings.CONFLICT_REVIEW_PATH, '%s-%s.txt' % (review.name, review.rev))
|
||||
try:
|
||||
with io.open(filename, 'r') as f:
|
||||
init["content"] = f.read()
|
||||
|
@ -276,7 +276,7 @@ def edit_ad(request, name):
|
|||
|
||||
|
||||
conflictdoc = review.relateddocument_set.get(relationship__slug='conflrev').target
|
||||
titletext = 'the conflict review of %s-%s' % (conflictdoc.canonical_name(),conflictdoc.rev)
|
||||
titletext = 'the conflict review of %s-%s' % (conflictdoc.name,conflictdoc.rev)
|
||||
return render(request, 'doc/change_ad.html',
|
||||
{'form': form,
|
||||
'doc': review,
|
||||
|
@ -448,9 +448,6 @@ def build_conflict_review_document(login, doc_to_review, ad, notify, create_in_s
|
|||
group=iesg_group,
|
||||
)
|
||||
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')
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
@ -796,7 +796,7 @@ def document_main(request, name, rev=None, document_html=False):
|
|||
))
|
||||
|
||||
elif doc.type_id == "conflrev":
|
||||
filename = "%s-%s.txt" % (doc.canonical_name(), doc.rev)
|
||||
filename = "%s-%s.txt" % (doc.name, doc.rev)
|
||||
pathname = os.path.join(settings.CONFLICT_REVIEW_PATH,filename)
|
||||
|
||||
if doc.rev == "00" and not os.path.isfile(pathname):
|
||||
|
@ -826,7 +826,7 @@ def document_main(request, name, rev=None, document_html=False):
|
|||
))
|
||||
|
||||
elif doc.type_id == "statchg":
|
||||
filename = "%s-%s.txt" % (doc.canonical_name(), doc.rev)
|
||||
filename = "%s-%s.txt" % (doc.name, doc.rev)
|
||||
pathname = os.path.join(settings.STATUS_CHANGE_PATH,filename)
|
||||
|
||||
if doc.rev == "00" and not os.path.isfile(pathname):
|
||||
|
@ -866,7 +866,7 @@ def document_main(request, name, rev=None, document_html=False):
|
|||
# we need to remove the extension for the globbing below to work
|
||||
basename = os.path.splitext(doc.uploaded_filename)[0]
|
||||
else:
|
||||
basename = "%s-%s" % (doc.canonical_name(), doc.rev)
|
||||
basename = "%s-%s" % (doc.name, doc.rev)
|
||||
|
||||
pathname = os.path.join(doc.get_file_path(), basename)
|
||||
|
||||
|
@ -1051,7 +1051,7 @@ def document_html(request, name, rev=None):
|
|||
|
||||
if not requested_rev and doc.type_id == "rfc": # Someone asked for /doc/html/8989
|
||||
if not name.startswith('rfc'):
|
||||
return redirect('ietf.doc.views_doc.document_html', name=doc.canonical_name())
|
||||
return redirect('ietf.doc.views_doc.document_html', name=doc.name)
|
||||
|
||||
if rev:
|
||||
doc = doc.history_set.filter(rev=rev).first() or doc.fake_history_obj(rev)
|
||||
|
@ -1061,7 +1061,7 @@ def document_html(request, name, rev=None):
|
|||
|
||||
return document_main(
|
||||
request,
|
||||
name=doc.name if requested_rev else doc.canonical_name(),
|
||||
name=doc.name if requested_rev else doc.name,
|
||||
rev=doc.rev if requested_rev or doc.type_id != "rfc" else None,
|
||||
document_html=True,
|
||||
)
|
||||
|
@ -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.type_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
|
||||
|
@ -1293,14 +1296,10 @@ def document_bibtex(request, name, rev=None):
|
|||
if rev == h.rev:
|
||||
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()
|
||||
|
@ -1462,9 +1461,9 @@ def document_referenced_by(request, name):
|
|||
refs=refs[:250]
|
||||
else:
|
||||
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.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
|
||||
|
||||
|
@ -1768,8 +1768,8 @@ def telechat_date(request, name):
|
|||
def doc_titletext(doc):
|
||||
if doc.type.slug=='conflrev':
|
||||
conflictdoc = doc.relateddocument_set.get(relationship__slug='conflrev').target
|
||||
return 'the conflict review of %s' % conflictdoc.canonical_name()
|
||||
return doc.canonical_name()
|
||||
return 'the conflict review of %s' % conflictdoc.name
|
||||
return doc.name
|
||||
|
||||
|
||||
def edit_notify(request, name):
|
||||
|
@ -2008,7 +2008,7 @@ def remind_action_holders(request, name):
|
|||
form = ReminderEmailForm(request.POST)
|
||||
if form.is_valid():
|
||||
email_remind_action_holders(request, doc, form.cleaned_data['note'])
|
||||
return redirect('ietf.doc.views_doc.document_main', name=doc.canonical_name())
|
||||
return redirect('ietf.doc.views_doc.document_main', name=doc.name)
|
||||
|
||||
form = ReminderEmailForm()
|
||||
return render(
|
||||
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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":
|
||||
|
|
|
@ -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[0].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(type_id="draft", 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(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.upper()}</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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
@ -99,7 +99,7 @@ def change_state(request, name, option=None):
|
|||
)
|
||||
related_doc_info = [
|
||||
dict(title=rel_doc.target.title,
|
||||
canonical_name=rel_doc.target.canonical_name(),
|
||||
name=rel_doc.target.name,
|
||||
newstatus=newstatus(rel_doc))
|
||||
for rel_doc in related_docs
|
||||
]
|
||||
|
@ -148,7 +148,7 @@ class UploadForm(forms.Form):
|
|||
return get_cleaned_text_file_content(self.cleaned_data["txt"])
|
||||
|
||||
def save(self, doc):
|
||||
filename = os.path.join(settings.STATUS_CHANGE_PATH, '%s-%s.txt' % (doc.canonical_name(), doc.rev))
|
||||
filename = os.path.join(settings.STATUS_CHANGE_PATH, '%s-%s.txt' % (doc.name, doc.rev))
|
||||
with io.open(filename, 'w', encoding='utf-8') as destination:
|
||||
if self.cleaned_data['txt']:
|
||||
destination.write(self.cleaned_data['txt'])
|
||||
|
@ -162,7 +162,7 @@ def submit(request, name):
|
|||
|
||||
login = request.user.person
|
||||
|
||||
path = os.path.join(settings.STATUS_CHANGE_PATH, '%s-%s.txt' % (doc.canonical_name(), doc.rev))
|
||||
path = os.path.join(settings.STATUS_CHANGE_PATH, '%s-%s.txt' % (doc.name, doc.rev))
|
||||
not_uploaded_yet = doc.rev == "00" and not os.path.exists(path)
|
||||
|
||||
if not_uploaded_yet:
|
||||
|
@ -179,7 +179,7 @@ def submit(request, name):
|
|||
|
||||
events = []
|
||||
e = NewRevisionDocEvent(doc=doc, by=login, type="new_revision")
|
||||
e.desc = "New version available: <b>%s-%s.txt</b>" % (doc.canonical_name(), doc.rev)
|
||||
e.desc = "New version available: <b>%s-%s.txt</b>" % (doc.name, doc.rev)
|
||||
e.rev = doc.rev
|
||||
e.save()
|
||||
events.append(e)
|
||||
|
@ -211,7 +211,7 @@ def submit(request, name):
|
|||
dict(),
|
||||
)
|
||||
else:
|
||||
filename = os.path.join(settings.STATUS_CHANGE_PATH, '%s-%s.txt' % (doc.canonical_name(), doc.rev))
|
||||
filename = os.path.join(settings.STATUS_CHANGE_PATH, '%s-%s.txt' % (doc.name, doc.rev))
|
||||
try:
|
||||
with io.open(filename, 'r') as f:
|
||||
init["content"] = f.read()
|
||||
|
@ -253,7 +253,7 @@ def edit_title(request, name):
|
|||
init = { "title" : status_change.title }
|
||||
form = ChangeTitleForm(initial=init)
|
||||
|
||||
titletext = '%s-%s.txt' % (status_change.canonical_name(),status_change.rev)
|
||||
titletext = '%s-%s.txt' % (status_change.name,status_change.rev)
|
||||
return render(request, 'doc/change_title.html',
|
||||
{'form': form,
|
||||
'doc': status_change,
|
||||
|
@ -284,7 +284,7 @@ def edit_ad(request, name):
|
|||
init = { "ad" : status_change.ad_id }
|
||||
form = AdForm(initial=init)
|
||||
|
||||
titletext = '%s-%s.txt' % (status_change.canonical_name(),status_change.rev)
|
||||
titletext = '%s-%s.txt' % (status_change.name,status_change.rev)
|
||||
return render(request, 'doc/change_ad.html',
|
||||
{'form': form,
|
||||
'doc': status_change,
|
||||
|
@ -399,7 +399,7 @@ def approve(request, name):
|
|||
init = []
|
||||
for rel in status_change.relateddocument_set.filter(relationship__slug__in=STATUSCHANGE_RELATIONS):
|
||||
init.append({"announcement_text" : escape(default_approval_text(status_change,rel)),
|
||||
"label": "Announcement text for %s to %s"%(rel.target.canonical_name(),newstatus(rel)),
|
||||
"label": "Announcement text for %s to %s"%(rel.target.name,newstatus(rel)),
|
||||
})
|
||||
formset = AnnouncementFormSet(initial=init)
|
||||
for form in formset.forms:
|
||||
|
@ -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
|
||||
|
||||
|
@ -560,8 +560,6 @@ def start_rfc_status_change(request, name=None):
|
|||
group=iesg_group,
|
||||
)
|
||||
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),
|
||||
|
@ -576,9 +574,9 @@ def start_rfc_status_change(request, name=None):
|
|||
init = {}
|
||||
if name:
|
||||
init['title'] = "%s to CHANGETHIS" % seed_rfc.title
|
||||
init['document_name'] = "%s-to-CHANGETHIS" % seed_rfc.canonical_name()
|
||||
init['document_name'] = "%s-to-CHANGETHIS" % seed_rfc.name
|
||||
relations={}
|
||||
relations[seed_rfc.canonical_name()]=None
|
||||
relations[seed_rfc.name]=None
|
||||
init['relations'] = relations
|
||||
form = StartStatusChangeForm(initial=init)
|
||||
|
||||
|
@ -604,7 +602,7 @@ def edit_relations(request, name):
|
|||
|
||||
old_relations={}
|
||||
for rel in status_change.relateddocument_set.filter(relationship__slug__in=STATUSCHANGE_RELATIONS):
|
||||
old_relations[rel.target.canonical_name()]=rel.relationship.slug
|
||||
old_relations[rel.target.name]=rel.relationship.slug
|
||||
new_relations=form.cleaned_data['relations']
|
||||
status_change.relateddocument_set.filter(relationship__slug__in=STATUSCHANGE_RELATIONS).delete()
|
||||
for key in new_relations:
|
||||
|
@ -625,7 +623,7 @@ def edit_relations(request, name):
|
|||
else:
|
||||
relations={}
|
||||
for rel in status_change.relateddocument_set.filter(relationship__slug__in=STATUSCHANGE_RELATIONS):
|
||||
relations[rel.target.canonical_name()]=rel.relationship.slug
|
||||
relations[rel.target.name]=rel.relationship.slug
|
||||
init = { "relations":relations,
|
||||
}
|
||||
form = EditStatusChangeForm(initial=init)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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+)@.*? +(.*)$')
|
||||
|
@ -775,7 +770,7 @@ def dependencies(request, acronym, group_type=None):
|
|||
graph = {
|
||||
"nodes": [
|
||||
{
|
||||
"id": x.canonical_name(),
|
||||
"id": x.name,
|
||||
"rfc": x.get_state("draft").slug == "rfc",
|
||||
"post-wg": not x.get_state("draft-iesg").slug
|
||||
in ["idexists", "watching", "dead"],
|
||||
|
@ -793,8 +788,8 @@ def dependencies(request, acronym, group_type=None):
|
|||
],
|
||||
"links": [
|
||||
{
|
||||
"source": x.source.canonical_name(),
|
||||
"target": x.target.canonical_name(),
|
||||
"source": x.source.name,
|
||||
"target": x.target.name,
|
||||
"rel": "downref" if x.is_downref() else x.relationship.slug,
|
||||
}
|
||||
for x in links
|
||||
|
|
|
@ -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,18 @@ 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(rfc.related_that("became_rfc")), None)
|
||||
if draft is not None:
|
||||
rfcs[draft.name] = 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 +80,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")
|
||||
|
||||
|
@ -108,12 +111,15 @@ def file_types_for_drafts():
|
|||
def all_id2_txt():
|
||||
# this returns a lot of data so try to be efficient
|
||||
|
||||
drafts = Document.objects.filter(type="draft").exclude(name__startswith="rfc").order_by('name')
|
||||
drafts = Document.objects.filter(type="draft").order_by('name')
|
||||
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(rfc.related_that("became_rfc")), None)
|
||||
if draft is not None:
|
||||
rfcs[draft.name] = 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 +170,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 = ""
|
||||
|
|
|
@ -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(rfc_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")
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ def agenda_json(request, date=None):
|
|||
|
||||
for doc in docs:
|
||||
wginfo = {
|
||||
'docname': doc.canonical_name(),
|
||||
'docname': doc.name,
|
||||
'rev': doc.rev,
|
||||
'wgname': doc.group.name,
|
||||
'acronym': doc.group.acronym,
|
||||
|
@ -137,7 +137,7 @@ def agenda_json(request, date=None):
|
|||
|
||||
for doc in docs:
|
||||
docinfo = {
|
||||
'docname':doc.canonical_name(),
|
||||
'docname':doc.name,
|
||||
'title':doc.title,
|
||||
'ad':doc.ad.name if doc.ad else None,
|
||||
}
|
||||
|
@ -173,7 +173,7 @@ def agenda_json(request, date=None):
|
|||
elif doc.type_id == 'conflrev':
|
||||
docinfo['rev'] = doc.rev
|
||||
td = doc.relateddocument_set.get(relationship__slug='conflrev').target
|
||||
docinfo['target-docname'] = td.canonical_name()
|
||||
docinfo['target-docname'] = td.name
|
||||
docinfo['target-title'] = td.title
|
||||
docinfo['target-rev'] = td.rev
|
||||
docinfo['intended-std-level'] = str(td.intended_std_level)
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
78
ietf/ipr/migrations/0002_iprdocrel_no_aliases.py
Normal file
78
ietf/ipr/migrations/0002_iprdocrel_no_aliases.py
Normal 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',
|
||||
),
|
||||
),
|
||||
]
|
18
ietf/ipr/migrations/0003_alter_iprdisclosurebase_docs.py
Normal file
18
ietf/ipr/migrations/0003_alter_iprdisclosurebase_docs.py
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Copyright The IETF Trust 2023, All Rights Reserved
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("doc", "0015_delete_docalias"),
|
||||
("ipr", "0002_iprdocrel_no_aliases"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="iprdisclosurebase",
|
||||
name="docs",
|
||||
field=models.ManyToManyField(through="ipr.IprDocRel", to="doc.document"),
|
||||
),
|
||||
]
|
|
@ -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,
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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",
|
||||
|
@ -720,7 +720,7 @@ Subject: test
|
|||
'iprdocrel_set-INITIAL_FORMS' : 0,
|
||||
'iprdocrel_set-0-id': '',
|
||||
"iprdocrel_set-0-document": disclosure.docs.first().pk,
|
||||
"iprdocrel_set-0-revisions": disclosure.docs.first().document.rev,
|
||||
"iprdocrel_set-0-revisions": disclosure.docs.first().rev,
|
||||
'holder_legal_name': disclosure.holder_legal_name,
|
||||
'patent_number': patent_dict['Number'],
|
||||
'patent_title': patent_dict['Title'],
|
||||
|
|
|
@ -32,27 +32,32 @@ 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():
|
||||
if document.ipr(**kwargs):
|
||||
iprdocrels += document.ipr(**kwargs)
|
||||
for document in docs:
|
||||
if document.ipr(**kwargs):
|
||||
iprdocrels += document.ipr(**kwargs)
|
||||
return list(set([i.disclosure for i in iprdocrels]))
|
||||
|
||||
def related_docs(doc, relationship=('replaces', 'obs')):
|
||||
def related_docs(doc, relationship=('replaces', 'obs'), reverse_relationship=("became_rfc",)):
|
||||
"""Returns list of related documents"""
|
||||
|
||||
results = [doc]
|
||||
|
||||
rels = list(doc.document.all_relations_that_doc(relationship))
|
||||
rels = doc.all_relations_that_doc(relationship)
|
||||
|
||||
for rel in rels:
|
||||
rel.target.related = rel
|
||||
rel.target.relation = rel.relationship.revname
|
||||
results += [x.target for x in rels]
|
||||
|
||||
rev_rels = doc.all_relations_that(reverse_relationship)
|
||||
for rel in rev_rels:
|
||||
rel.source.related = rel
|
||||
rel.source.relation = rel.relationship.name
|
||||
results += [x.source for x in rev_rels]
|
||||
|
||||
return list(set(results))
|
||||
|
||||
|
||||
|
@ -60,17 +65,16 @@ 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
|
||||
if name.startswith("rfc"):
|
||||
name = name.upper()
|
||||
if not name in docipr:
|
||||
docipr[name] = []
|
||||
docipr[name].append(o.disclosure_id)
|
||||
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:
|
||||
docipr[name] = []
|
||||
docipr[name].append(o.disclosure_id)
|
||||
|
||||
lines = [ "# Machine-readable list of IPR disclosures by Internet-Draft name" ]
|
||||
for name, iprs in docipr.items():
|
||||
|
|
|
@ -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)
|
||||
|
@ -38,7 +38,7 @@ from ietf.message.models import Message
|
|||
from ietf.message.utils import infer_message
|
||||
from ietf.name.models import IprLicenseTypeName
|
||||
from ietf.person.models import Person
|
||||
from ietf.secr.utils.document import get_rfc_num, is_draft
|
||||
from ietf.utils import log
|
||||
from ietf.utils.draft_search import normalize_draftname
|
||||
from ietf.utils.mail import send_mail, send_mail_message
|
||||
from ietf.utils.response import permission_denied
|
||||
|
@ -69,12 +69,15 @@ def get_document_emails(ipr):
|
|||
has been posted"""
|
||||
messages = []
|
||||
for rel in ipr.iprdocrel_set.all():
|
||||
doc = rel.document.document
|
||||
doc = rel.document
|
||||
|
||||
if is_draft(doc):
|
||||
if doc.type_id=="draft":
|
||||
doc_info = 'Internet-Draft entitled "{}" ({})'.format(doc.title,doc.name)
|
||||
elif doc.type_id=="rfc":
|
||||
doc_info = 'RFC entitled "{}" (RFC{})'.format(doc.title, doc.rfc_number)
|
||||
else:
|
||||
doc_info = 'RFC entitled "{}" (RFC{})'.format(doc.title,get_rfc_num(doc))
|
||||
log.unreachable("2023-08-15")
|
||||
return ""
|
||||
|
||||
addrs = gather_address_lists('ipr_posted_on_doc',doc=doc).as_strings(compact=False)
|
||||
|
||||
|
@ -663,18 +666,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,27 +709,27 @@ 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(group=q))
|
||||
related = []
|
||||
for doc in docs:
|
||||
doc.product_of_this_wg = True
|
||||
related += related_docs(doc)
|
||||
iprs = iprs_from_docs(list(set(docs+related)),states=states)
|
||||
docs = [ doc for doc in docs if doc.document.ipr() ]
|
||||
docs = sorted(docs, key=lambda x: max([ipr.disclosure.time for ipr in x.document.ipr()]), reverse=True)
|
||||
docs = [ doc for doc in docs if doc.ipr() ]
|
||||
docs = sorted(docs, key=lambda x: max([ipr.disclosure.time for ipr in x.ipr()]), reverse=True)
|
||||
template = "ipr/search_wg_result.html"
|
||||
q = Group.objects.get(id=q).acronym # make acronym for use in template
|
||||
|
||||
# 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(title__icontains=q))
|
||||
related = []
|
||||
for doc in docs:
|
||||
related += related_docs(doc)
|
||||
iprs = iprs_from_docs(list(set(docs+related)),states=states)
|
||||
docs = [ doc for doc in docs if doc.document.ipr() ]
|
||||
docs = sorted(docs, key=lambda x: max([ipr.disclosure.time for ipr in x.document.ipr()]), reverse=True)
|
||||
docs = [ doc for doc in docs if doc.ipr() ]
|
||||
docs = sorted(docs, key=lambda x: max([ipr.disclosure.time for ipr in x.ipr()]), reverse=True)
|
||||
template = "ipr/search_doctitle_result.html"
|
||||
|
||||
# Search by title of IPR disclosure
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -550,7 +550,7 @@ class MeetingTests(BaseMeetingTestCase):
|
|||
if material.type_id == 'draft':
|
||||
expected_url = urlreverse(
|
||||
'ietf.doc.views_doc.document_main',
|
||||
kwargs={'name': material.canonical_name()},
|
||||
kwargs={'name': material.name},
|
||||
)
|
||||
else:
|
||||
expected_url = material.get_href(meeting)
|
||||
|
@ -561,7 +561,7 @@ class MeetingTests(BaseMeetingTestCase):
|
|||
if material.type_id == 'draft':
|
||||
expected_url = urlreverse(
|
||||
'ietf.doc.views_doc.document_main',
|
||||
kwargs={'name': material.canonical_name()},
|
||||
kwargs={'name': material.name},
|
||||
)
|
||||
else:
|
||||
expected_url = material.get_href(meeting)
|
||||
|
@ -7773,7 +7773,7 @@ class ProceedingsTests(BaseMeetingTestCase):
|
|||
if material.type_id == 'draft':
|
||||
expected_url = urlreverse(
|
||||
'ietf.doc.views_doc.document_main',
|
||||
kwargs={'name': material.canonical_name()},
|
||||
kwargs={'name': material.name},
|
||||
)
|
||||
else:
|
||||
expected_url = material.get_href(meeting)
|
||||
|
@ -7784,7 +7784,7 @@ class ProceedingsTests(BaseMeetingTestCase):
|
|||
if material.type_id == 'draft':
|
||||
expected_url = urlreverse(
|
||||
'ietf.doc.views_doc.document_main',
|
||||
kwargs={'name': material.canonical_name()},
|
||||
kwargs={'name': material.name},
|
||||
)
|
||||
else:
|
||||
expected_url = material.get_href(meeting)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
@ -779,8 +777,6 @@ def create_recording(session, url, title=None, user=None):
|
|||
rev='00',
|
||||
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',
|
||||
|
@ -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):
|
||||
|
|
|
@ -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():
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -9956,9 +9956,9 @@
|
|||
{
|
||||
"fields": {
|
||||
"desc": "",
|
||||
"name": "Became RFC",
|
||||
"name": "became RFC",
|
||||
"order": 0,
|
||||
"revname": "Became RFC as",
|
||||
"revname": "came from draft",
|
||||
"used": true
|
||||
},
|
||||
"model": "name.docrelationshipname",
|
||||
|
@ -11156,7 +11156,7 @@
|
|||
"fields": {
|
||||
"desc": "",
|
||||
"name": "Comment",
|
||||
"order": 0,
|
||||
"order": 1,
|
||||
"used": true
|
||||
},
|
||||
"model": "name.feedbacktypename",
|
||||
|
@ -11166,7 +11166,7 @@
|
|||
"fields": {
|
||||
"desc": "",
|
||||
"name": "Junk",
|
||||
"order": 0,
|
||||
"order": 5,
|
||||
"used": true
|
||||
},
|
||||
"model": "name.feedbacktypename",
|
||||
|
@ -11176,17 +11176,27 @@
|
|||
"fields": {
|
||||
"desc": "",
|
||||
"name": "Nomination",
|
||||
"order": 0,
|
||||
"order": 2,
|
||||
"used": true
|
||||
},
|
||||
"model": "name.feedbacktypename",
|
||||
"pk": "nomina"
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"desc": "",
|
||||
"name": "Overcome by events",
|
||||
"order": 4,
|
||||
"used": true
|
||||
},
|
||||
"model": "name.feedbacktypename",
|
||||
"pk": "obe"
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"desc": "",
|
||||
"name": "Questionnaire response",
|
||||
"order": 0,
|
||||
"order": 3,
|
||||
"used": true
|
||||
},
|
||||
"model": "name.feedbacktypename",
|
||||
|
@ -11196,7 +11206,7 @@
|
|||
"fields": {
|
||||
"desc": "",
|
||||
"name": "Read",
|
||||
"order": 0,
|
||||
"order": 6,
|
||||
"used": true
|
||||
},
|
||||
"model": "name.feedbacktypename",
|
||||
|
@ -11799,13 +11809,24 @@
|
|||
"model": "name.importantdatename",
|
||||
"pk": "draftwgagenda"
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"default_offset_days": -12,
|
||||
"desc": "Early registration and payment cut-off at UTC 23:59",
|
||||
"name": "Early cutoff",
|
||||
"order": 0,
|
||||
"used": true
|
||||
},
|
||||
"model": "name.importantdatename",
|
||||
"pk": "early"
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"default_offset_days": -47,
|
||||
"desc": "Early Bird registration and payment cut-off at UTC 23:59",
|
||||
"name": "Earlybird cutoff",
|
||||
"order": 0,
|
||||
"used": true
|
||||
"used": false
|
||||
},
|
||||
"model": "name.importantdatename",
|
||||
"pk": "earlybird"
|
||||
|
@ -11926,11 +11947,22 @@
|
|||
"desc": "Standard rate registration and payment cut-off at UTC 23:59.",
|
||||
"name": "Standard rate registration ends",
|
||||
"order": 18,
|
||||
"used": true
|
||||
"used": false
|
||||
},
|
||||
"model": "name.importantdatename",
|
||||
"pk": "stdratecutoff"
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"default_offset_days": -47,
|
||||
"desc": "Super Early registration cutoff at UTC 23:59",
|
||||
"name": "Super Early cutoff",
|
||||
"order": 0,
|
||||
"used": true
|
||||
},
|
||||
"model": "name.importantdatename",
|
||||
"pk": "superearly"
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"desc": "",
|
||||
|
@ -16481,7 +16513,7 @@
|
|||
"fields": {
|
||||
"command": "xym",
|
||||
"switch": "--version",
|
||||
"time": "2023-07-17T07:09:47.664Z",
|
||||
"time": "2023-08-13T07:09:38.976Z",
|
||||
"used": true,
|
||||
"version": "xym 0.7.0"
|
||||
},
|
||||
|
@ -16492,7 +16524,7 @@
|
|||
"fields": {
|
||||
"command": "pyang",
|
||||
"switch": "--version",
|
||||
"time": "2023-07-17T07:09:48.075Z",
|
||||
"time": "2023-08-13T07:09:39.314Z",
|
||||
"used": true,
|
||||
"version": "pyang 2.5.3"
|
||||
},
|
||||
|
@ -16503,7 +16535,7 @@
|
|||
"fields": {
|
||||
"command": "yanglint",
|
||||
"switch": "--version",
|
||||
"time": "2023-07-17T07:09:48.104Z",
|
||||
"time": "2023-08-13T07:09:39.334Z",
|
||||
"used": true,
|
||||
"version": "yanglint SO 1.9.2"
|
||||
},
|
||||
|
@ -16514,9 +16546,9 @@
|
|||
"fields": {
|
||||
"command": "xml2rfc",
|
||||
"switch": "--version",
|
||||
"time": "2023-07-17T07:09:49.075Z",
|
||||
"time": "2023-08-13T07:09:40.245Z",
|
||||
"used": true,
|
||||
"version": "xml2rfc 3.17.4"
|
||||
"version": "xml2rfc 3.18.0"
|
||||
},
|
||||
"model": "utils.versioninfo",
|
||||
"pk": 4
|
||||
|
|
|
@ -191,7 +191,7 @@ class Person(models.Model):
|
|||
def rfcs(self):
|
||||
from ietf.doc.models import Document
|
||||
rfcs = list(Document.objects.filter(documentauthor__person=self, type='draft', states__slug='rfc'))
|
||||
rfcs.sort(key=lambda d: d.canonical_name() )
|
||||
rfcs.sort(key=lambda d: d.name )
|
||||
return rfcs
|
||||
|
||||
def active_drafts(self):
|
||||
|
|
|
@ -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
|
||||
|
@ -287,8 +287,6 @@ class AssignmentOrderResolver:
|
|||
def _collect_context(self):
|
||||
"""Collect all relevant data about this team, document and review request."""
|
||||
|
||||
self.doc_aliases = DocAlias.objects.filter(docs=self.doc).values_list("name", flat=True)
|
||||
|
||||
# This data is collected as a dict, keys being person IDs, values being numbers/objects.
|
||||
self.rotation_index = {p.pk: i for i, p in enumerate(self.rotation_list)}
|
||||
self.reviewer_settings = self._reviewer_settings_for_person_ids(self.possible_person_ids)
|
||||
|
@ -354,8 +352,7 @@ class AssignmentOrderResolver:
|
|||
add_boolean_score(+1, email.person_id in self.wish_to_review, "wishes to review document")
|
||||
add_boolean_score(-1, email.person_id in self.connections,
|
||||
self.connections.get(email.person_id)) # reviewer is somehow connected: bad
|
||||
add_boolean_score(-1, settings.filter_re and any(
|
||||
re.search(settings.filter_re, n) for n in self.doc_aliases), "filter regexp matches")
|
||||
add_boolean_score(-1, settings.filter_re and re.search(settings.filter_re, self.doc.name), "filter regexp matches")
|
||||
|
||||
# minimum interval between reviews
|
||||
days_needed = self.days_needed_for_reviewers.get(email.person_id, 0)
|
||||
|
|
|
@ -175,7 +175,7 @@ def doc_detail(request, date, name):
|
|||
This view displays the ballot information for the document, and lets the user make
|
||||
changes to ballot positions and document state.
|
||||
'''
|
||||
doc = get_object_or_404(Document, docalias__name=name)
|
||||
doc = get_object_or_404(Document, name=name)
|
||||
if not is_doc_on_telechat(doc, date):
|
||||
messages.warning(request, 'Dcoument: {name} is not on the Telechat agenda for {date}'.format(
|
||||
name=doc.name,
|
||||
|
@ -342,7 +342,7 @@ def doc_navigate(request, date, name, nav):
|
|||
nav - [next|previous] which direction the user wants to navigate in the list of docs
|
||||
The view retrieves the appropriate document and redirects to the doc view.
|
||||
'''
|
||||
doc = get_object_or_404(Document, docalias__name=name)
|
||||
doc = get_object_or_404(Document, name=name)
|
||||
agenda = agenda_data(date=date)
|
||||
target = name
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@
|
|||
{% if downrefs %}
|
||||
<h2 id="downrefs">Downward References</h2>
|
||||
{% for ref in downrefs %}
|
||||
<p>Add {{ref.target.canonical_name}}
|
||||
<p>Add {{ref.target.name}}
|
||||
({{ref.target.std_level}} - {{ref.target.stream.desc}})
|
||||
to downref registry.<br>
|
||||
{% if not ref.target.std_level %}
|
||||
|
|
|
@ -13,15 +13,6 @@ def get_full_path(doc):
|
|||
return None
|
||||
return os.path.join(doc.get_file_path(), doc.uploaded_filename)
|
||||
|
||||
def get_rfc_num(doc):
|
||||
qs = doc.docalias.filter(name__startswith='rfc')
|
||||
return qs[0].name[3:] if qs else None
|
||||
|
||||
def is_draft(doc):
|
||||
if doc.docalias.filter(name__startswith='rfc'):
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def get_start_date(doc):
|
||||
'''
|
||||
|
|
|
@ -600,7 +600,6 @@ TEST_CODE_COVERAGE_EXCLUDE_FILES = [
|
|||
"ietf/utils/test_runner.py",
|
||||
"ietf/name/generate_fixtures.py",
|
||||
"ietf/review/import_from_review_tool.py",
|
||||
"ietf/stats/backfill_data.py",
|
||||
"ietf/utils/patch.py",
|
||||
"ietf/utils/test_data.py",
|
||||
]
|
||||
|
|
|
@ -1,184 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# Copyright The IETF Trust 2017-2020, All Rights Reserved
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
import io
|
||||
import sys
|
||||
import os
|
||||
import os.path
|
||||
import argparse
|
||||
import time
|
||||
|
||||
from typing import Set, Optional # pyflakes:ignore
|
||||
|
||||
basedir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../.."))
|
||||
sys.path = [ basedir ] + sys.path
|
||||
os.environ["DJANGO_SETTINGS_MODULE"] = "ietf.settings"
|
||||
|
||||
virtualenv_activation = os.path.join(basedir, "env", "bin", "activate_this.py")
|
||||
if os.path.exists(virtualenv_activation):
|
||||
exec(compile(io.open(virtualenv_activation, "rb").read(), virtualenv_activation, 'exec'), dict(__file__=virtualenv_activation))
|
||||
|
||||
import django
|
||||
django.setup()
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
import debug # pyflakes:ignore
|
||||
|
||||
from ietf.doc.models import Document
|
||||
from ietf.name.models import FormalLanguageName
|
||||
from ietf.utils.draft import PlaintextDraft
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--document", help="specific document name")
|
||||
parser.add_argument("--words", action="store_true", help="fill in word count")
|
||||
parser.add_argument("--formlang", action="store_true", help="fill in formal languages")
|
||||
parser.add_argument("--authors", action="store_true", help="fill in author info")
|
||||
args = parser.parse_args()
|
||||
|
||||
formal_language_dict = { l.pk: l for l in FormalLanguageName.objects.all() }
|
||||
|
||||
docs_qs = Document.objects.filter(type="draft")
|
||||
|
||||
if args.document:
|
||||
docs_qs = docs_qs.filter(docalias__name=args.document)
|
||||
|
||||
ts = time.strftime("%Y-%m-%d_%H:%M%z")
|
||||
logfile = io.open('backfill-authorstats-%s.log'%ts, 'w')
|
||||
print("Writing log to %s" % os.path.abspath(logfile.name))
|
||||
|
||||
def say(msg):
|
||||
msg = msg.encode('utf8')
|
||||
sys.stderr.write(msg)
|
||||
sys.stderr.write('\n')
|
||||
logfile.write(msg)
|
||||
logfile.write('\n')
|
||||
|
||||
def unicode(text):
|
||||
if text is None:
|
||||
return text
|
||||
# order matters here:
|
||||
for encoding in ['ascii', 'utf8', 'latin1', ]:
|
||||
try:
|
||||
utext = text.decode(encoding)
|
||||
# if encoding == 'latin1':
|
||||
# say("Warning: falling back to latin1 decoding for %s ..." % utext[:216]])
|
||||
return utext
|
||||
except UnicodeDecodeError:
|
||||
pass
|
||||
|
||||
start = time.time()
|
||||
say("Running query for documents to process ...")
|
||||
for doc in docs_qs.prefetch_related("docalias", "formal_languages", "documentauthor_set", "documentauthor_set__person", "documentauthor_set__person__alias_set"):
|
||||
canonical_name = doc.name
|
||||
for n in doc.docalias.all():
|
||||
if n.name.startswith("rfc"):
|
||||
canonical_name = n.name
|
||||
|
||||
if canonical_name.startswith("rfc"):
|
||||
path = os.path.join(settings.RFC_PATH, canonical_name + ".txt")
|
||||
else:
|
||||
path = os.path.join(settings.INTERNET_ALL_DRAFTS_ARCHIVE_DIR, canonical_name + "-" + doc.rev + ".txt")
|
||||
|
||||
if not os.path.exists(path):
|
||||
say("Skipping %s, no txt file found at %s" % (doc.name, path))
|
||||
continue
|
||||
|
||||
with io.open(path, 'rb') as f:
|
||||
say("\nProcessing %s" % doc.name)
|
||||
sys.stdout.flush()
|
||||
d = PlaintextDraft(unicode(f.read()), path)
|
||||
|
||||
updated = False
|
||||
|
||||
updates = {}
|
||||
|
||||
if args.words:
|
||||
words = d.get_wordcount()
|
||||
if words != doc.words:
|
||||
updates["words"] = words
|
||||
|
||||
if args.formlang:
|
||||
langs = d.get_formal_languages()
|
||||
|
||||
new_formal_languages = set(formal_language_dict[l] for l in langs)
|
||||
old_formal_languages = set(doc.formal_languages.all())
|
||||
|
||||
if new_formal_languages != old_formal_languages:
|
||||
for l in new_formal_languages - old_formal_languages:
|
||||
doc.formal_languages.add(l)
|
||||
updated = True
|
||||
for l in old_formal_languages - new_formal_languages:
|
||||
doc.formal_languages.remove(l)
|
||||
updated = True
|
||||
|
||||
if args.authors:
|
||||
old_authors = doc.documentauthor_set.all()
|
||||
old_authors_by_name = {}
|
||||
old_authors_by_email = {}
|
||||
for author in old_authors:
|
||||
for alias in author.person.alias_set.all():
|
||||
old_authors_by_name[alias.name] = author
|
||||
old_authors_by_name[author.person.plain_name()] = author
|
||||
|
||||
if author.email_id:
|
||||
old_authors_by_email[author.email_id] = author
|
||||
|
||||
# the draft parser sometimes has a problem when
|
||||
# affiliation isn't in the second line and it then thinks
|
||||
# it's an extra author - skip those extra authors
|
||||
seen = set() # type: Set[Optional[str]]
|
||||
for full, _, _, _, _, email, country, company in d.get_author_list():
|
||||
assert full is None or isinstance(full, str)
|
||||
assert email is None or isinstance(email, str)
|
||||
assert country is None or isinstance(country, str)
|
||||
assert isinstance(company, str)
|
||||
#full, email, country, company = [ unicode(s) for s in [full, email, country, company, ] ]
|
||||
if email in seen:
|
||||
continue
|
||||
seen.add(email)
|
||||
|
||||
old_author = None
|
||||
if email:
|
||||
old_author = old_authors_by_email.get(email)
|
||||
if not old_author:
|
||||
old_author = old_authors_by_name.get(full)
|
||||
|
||||
if not old_author:
|
||||
say("UNKNOWN AUTHOR: %s, %s, %s, %s, %s" % (doc.name, full, email, country, company))
|
||||
continue
|
||||
|
||||
if old_author.affiliation != company:
|
||||
say("new affiliation: %s [ %s <%s> ] %s -> %s" % (canonical_name, full, email, old_author.affiliation, company))
|
||||
old_author.affiliation = company
|
||||
old_author.save(update_fields=["affiliation"])
|
||||
updated = True
|
||||
|
||||
if country is None:
|
||||
country = ""
|
||||
|
||||
if old_author.country != country:
|
||||
say("new country: %s [ %s <%s> ] %s -> %s" % (canonical_name , full, email, old_author.country, country))
|
||||
old_author.country = country
|
||||
old_author.save(update_fields=["country"])
|
||||
updated = True
|
||||
|
||||
|
||||
if updates:
|
||||
Document.objects.filter(pk=doc.pk).update(**updates)
|
||||
updated = True
|
||||
|
||||
if updated:
|
||||
say("updated: %s" % canonical_name)
|
||||
|
||||
stop = time.time()
|
||||
dur = stop-start
|
||||
sec = dur%60
|
||||
min = dur//60
|
||||
say("Processing time %d:%02d" % (min, sec))
|
||||
|
||||
print("\n\nWrote log to %s" % os.path.abspath(logfile.name))
|
||||
logfile.close()
|
||||
|
|
@ -11,6 +11,10 @@ from ietf.name.models import CountryName
|
|||
from ietf.person.models import Person
|
||||
from ietf.utils.models import ForeignKey
|
||||
|
||||
### NOTE WELL: These models are expected to be removed and the stats app reimplemented.
|
||||
# A bare python file that should have been a management command was used to populate
|
||||
# these models when the app was first installed - it has been removed from main, but
|
||||
# can be seen at https://github.com/ietf-tools/datatracker/blob/f2b716fc052a0152c32b86b428ba6ebfdcdf5cd2/ietf/stats/backfill_data.py
|
||||
|
||||
class AffiliationAlias(models.Model):
|
||||
"""Records that alias should be treated as name for statistical
|
||||
|
|
|
@ -20,7 +20,7 @@ import ietf.stats.views
|
|||
|
||||
from ietf.submit.models import Submission
|
||||
from ietf.doc.factories import WgDraftFactory, WgRfcFactory
|
||||
from ietf.doc.models import Document, DocAlias, State, RelatedDocument, NewRevisionDocEvent, DocumentAuthor
|
||||
from ietf.doc.models import Document, State, RelatedDocument, NewRevisionDocEvent, DocumentAuthor
|
||||
from ietf.group.factories import RoleFactory
|
||||
from ietf.meeting.factories import MeetingFactory, AttendedFactory
|
||||
from ietf.person.factories import PersonFactory
|
||||
|
@ -79,7 +79,6 @@ class StatisticsTests(TestCase):
|
|||
words=100
|
||||
)
|
||||
referencing_draft.set_state(State.objects.get(used=True, type="draft", slug="active"))
|
||||
DocAlias.objects.create(name=referencing_draft.name).docs.add(referencing_draft)
|
||||
RelatedDocument.objects.create(
|
||||
source=referencing_draft,
|
||||
target=draft,
|
||||
|
|
|
@ -34,7 +34,7 @@ from ietf.group.models import Role, Group
|
|||
from ietf.person.models import Person
|
||||
from ietf.name.models import ReviewResultName, CountryName, DocRelationshipName, ReviewAssignmentStateName
|
||||
from ietf.person.name import plain_name
|
||||
from ietf.doc.models import DocAlias, Document, State, DocEvent
|
||||
from ietf.doc.models import Document, State, DocEvent
|
||||
from ietf.meeting.models import Meeting
|
||||
from ietf.stats.models import MeetingRegistration, CountryAlias
|
||||
from ietf.stats.utils import get_aliased_affiliations, get_aliased_countries, compute_hirsch_index
|
||||
|
@ -214,13 +214,13 @@ def document_stats(request, stats_type=None):
|
|||
|
||||
if any(stats_type == t[0] for t in possible_document_stats_types):
|
||||
# filter documents
|
||||
docalias_filters = Q(docs__type="draft")
|
||||
document_filters = Q(type__in=["draft","rfc"]) # TODO - review lots of "rfc is a draft" assumptions below
|
||||
|
||||
rfc_state = State.objects.get(type="draft", slug="rfc")
|
||||
if document_type == "rfc":
|
||||
docalias_filters &= Q(docs__states=rfc_state)
|
||||
document_filters &= Q(states=rfc_state)
|
||||
elif document_type == "draft":
|
||||
docalias_filters &= ~Q(docs__states=rfc_state)
|
||||
document_filters &= ~Q(states=rfc_state)
|
||||
|
||||
if from_time:
|
||||
# this is actually faster than joining in the database,
|
||||
|
@ -229,11 +229,11 @@ def document_stats(request, stats_type=None):
|
|||
type="draft",
|
||||
docevent__time__gte=from_time,
|
||||
docevent__type__in=["published_rfc", "new_revision"],
|
||||
).values_list("pk"))
|
||||
).values_list("pk",flat=True))
|
||||
|
||||
docalias_filters &= Q(docs__in=docs_within_time_constraint)
|
||||
document_filters &= Q(pk__in=docs_within_time_constraint)
|
||||
|
||||
docalias_qs = DocAlias.objects.filter(docalias_filters)
|
||||
document_qs = Document.objects.filter(document_filters)
|
||||
|
||||
if document_type == "rfc":
|
||||
doc_label = "RFC"
|
||||
|
@ -242,28 +242,15 @@ def document_stats(request, stats_type=None):
|
|||
else:
|
||||
doc_label = "document"
|
||||
|
||||
total_docs = docalias_qs.values_list("docs__name").distinct().count()
|
||||
|
||||
def generate_canonical_names(values):
|
||||
for doc_id, ts in itertools.groupby(values.order_by("docs__name"), lambda a: a[0]):
|
||||
chosen = None
|
||||
for t in ts:
|
||||
if chosen is None:
|
||||
chosen = t
|
||||
else:
|
||||
if t[1].startswith("rfc"):
|
||||
chosen = t
|
||||
elif t[1].startswith("draft") and not chosen[1].startswith("rfc"):
|
||||
chosen = t
|
||||
yield chosen
|
||||
total_docs = document_qs.values_list("name").distinct().count()
|
||||
|
||||
if stats_type == "authors":
|
||||
stats_title = "Number of authors for each {}".format(doc_label)
|
||||
|
||||
bins = defaultdict(set)
|
||||
|
||||
for name, canonical_name, author_count in generate_canonical_names(docalias_qs.values_list("docs__name", "name").annotate(Count("docs__documentauthor"))):
|
||||
bins[author_count or 0].add(canonical_name)
|
||||
for name, author_count in document_qs.values_list("name").annotate(Count("documentauthor")).values_list("name","documentauthor__count"):
|
||||
bins[author_count or 0].add(name)
|
||||
|
||||
series_data = []
|
||||
for author_count, names in sorted(bins.items(), key=lambda t: t[0]):
|
||||
|
@ -278,8 +265,8 @@ def document_stats(request, stats_type=None):
|
|||
|
||||
bins = defaultdict(set)
|
||||
|
||||
for name, canonical_name, pages in generate_canonical_names(docalias_qs.values_list("docs__name", "name", "docs__pages")):
|
||||
bins[pages or 0].add(canonical_name)
|
||||
for name, pages in document_qs.values_list("name", "pages"):
|
||||
bins[pages or 0].add(name)
|
||||
|
||||
series_data = []
|
||||
for pages, names in sorted(bins.items(), key=lambda t: t[0]):
|
||||
|
@ -297,8 +284,8 @@ def document_stats(request, stats_type=None):
|
|||
|
||||
bins = defaultdict(set)
|
||||
|
||||
for name, canonical_name, words in generate_canonical_names(docalias_qs.values_list("docs__name", "name", "docs__words")):
|
||||
bins[put_into_bin(words, bin_size)].add(canonical_name)
|
||||
for name, words in document_qs.values_list("name", "words"):
|
||||
bins[put_into_bin(words, bin_size)].add(name)
|
||||
|
||||
series_data = []
|
||||
for (value, words), names in sorted(bins.items(), key=lambda t: t[0][0]):
|
||||
|
@ -322,20 +309,20 @@ def document_stats(request, stats_type=None):
|
|||
submission_types[doc_name] = file_types
|
||||
|
||||
doc_names_with_missing_types = {}
|
||||
for doc_name, canonical_name, rev in generate_canonical_names(docalias_qs.values_list("docs__name", "name", "docs__rev")):
|
||||
for doc_name, doc_type, rev in document_qs.values_list("name", "type_id", "rev"):
|
||||
types = submission_types.get(doc_name)
|
||||
if types:
|
||||
for dot_ext in types.split(","):
|
||||
bins[dot_ext.lstrip(".").upper()].add(canonical_name)
|
||||
bins[dot_ext.lstrip(".").upper()].add(doc_name)
|
||||
|
||||
else:
|
||||
|
||||
if canonical_name.startswith("rfc"):
|
||||
filename = canonical_name
|
||||
if doc_type == "rfc":
|
||||
filename = doc_name
|
||||
else:
|
||||
filename = canonical_name + "-" + rev
|
||||
filename = doc_name + "-" + rev
|
||||
|
||||
doc_names_with_missing_types[filename] = canonical_name
|
||||
doc_names_with_missing_types[filename] = doc_name
|
||||
|
||||
# look up the remaining documents on disk
|
||||
for filename in itertools.chain(os.listdir(settings.INTERNET_ALL_DRAFTS_ARCHIVE_DIR), os.listdir(settings.RFC_PATH)):
|
||||
|
@ -348,10 +335,10 @@ def document_stats(request, stats_type=None):
|
|||
if not any(ext==allowlisted_ext for allowlisted_ext in settings.DOCUMENT_FORMAT_ALLOWLIST):
|
||||
continue
|
||||
|
||||
canonical_name = doc_names_with_missing_types.get(basename)
|
||||
name = doc_names_with_missing_types.get(basename)
|
||||
|
||||
if canonical_name:
|
||||
bins[ext.upper()].add(canonical_name)
|
||||
if name:
|
||||
bins[ext.upper()].add(name)
|
||||
|
||||
series_data = []
|
||||
for fmt, names in sorted(bins.items(), key=lambda t: t[0]):
|
||||
|
@ -367,8 +354,8 @@ def document_stats(request, stats_type=None):
|
|||
|
||||
bins = defaultdict(set)
|
||||
|
||||
for name, canonical_name, formal_language_name in generate_canonical_names(docalias_qs.values_list("docs__name", "name", "docs__formal_languages__name")):
|
||||
bins[formal_language_name or ""].add(canonical_name)
|
||||
for name, formal_language_name in document_qs.values_list("name", "formal_languages__name"):
|
||||
bins[formal_language_name or ""].add(name)
|
||||
|
||||
series_data = []
|
||||
for formal_language, names in sorted(bins.items(), key=lambda t: t[0]):
|
||||
|
|
|
@ -108,14 +108,14 @@ class Submission(models.Model):
|
|||
@property
|
||||
def active_wg_drafts_replaced(self):
|
||||
return Document.objects.filter(
|
||||
docalias__name__in=self.replaces.split(','),
|
||||
name__in=self.replaces.split(','),
|
||||
group__in=Group.objects.active_wgs()
|
||||
)
|
||||
|
||||
@property
|
||||
def closed_wg_drafts_replaced(self):
|
||||
return Document.objects.filter(
|
||||
docalias__name__in=self.replaces.split(','),
|
||||
name__in=self.replaces.split(','),
|
||||
group__in=Group.objects.closed_wgs()
|
||||
)
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ from ietf.submit.utils import (expirable_submissions, expire_submission, find_su
|
|||
process_and_validate_submission)
|
||||
from ietf.doc.factories import (DocumentFactory, WgDraftFactory, IndividualDraftFactory,
|
||||
ReviewFactory, WgRfcFactory)
|
||||
from ietf.doc.models import ( Document, DocAlias, DocEvent, State,
|
||||
from ietf.doc.models import ( Document, DocEvent, State,
|
||||
BallotPositionDocEvent, DocumentAuthor, SubmissionDocEvent )
|
||||
from ietf.doc.utils import create_ballot_if_not_open, can_edit_docextresources, update_action_holders
|
||||
from ietf.group.factories import GroupFactory, RoleFactory
|
||||
|
@ -358,8 +358,6 @@ class SubmitTests(BaseSubmitTestCase):
|
|||
note="",
|
||||
)
|
||||
sug_replaced_draft.set_state(State.objects.get(used=True, type="draft", slug="active"))
|
||||
sug_replaced_alias = DocAlias.objects.create(name=sug_replaced_draft.name)
|
||||
sug_replaced_alias.docs.add(sug_replaced_draft)
|
||||
|
||||
name = "draft-ietf-mars-testing-tests"
|
||||
rev = "00"
|
||||
|
@ -400,7 +398,7 @@ class SubmitTests(BaseSubmitTestCase):
|
|||
r = self.client.post(status_url, dict(action=action))
|
||||
self.assertEqual(r.status_code, 302)
|
||||
|
||||
draft = Document.objects.get(docalias__name=name)
|
||||
draft = Document.objects.get(name=name)
|
||||
self.assertEqual(draft.rev, rev)
|
||||
new_revision = draft.latest_event(type="new_revision")
|
||||
self.assertEqual(draft.group.acronym, "mars")
|
||||
|
@ -420,7 +418,7 @@ class SubmitTests(BaseSubmitTestCase):
|
|||
self.assertEqual(draft.relations_that_doc("replaces").count(), 1)
|
||||
self.assertTrue(draft.relations_that_doc("replaces").first().target, draft)
|
||||
self.assertEqual(draft.relations_that_doc("possibly-replaces").count(), 1)
|
||||
self.assertTrue(draft.relations_that_doc("possibly-replaces").first().target, sug_replaced_alias)
|
||||
self.assertTrue(draft.relations_that_doc("possibly-replaces").first().target, sug_replaced_draft)
|
||||
self.assertEqual(len(outbox), mailbox_before + 5)
|
||||
self.assertIn(("I-D Action: %s" % name), outbox[-4]["Subject"])
|
||||
self.assertIn(author.ascii, get_payload_text(outbox[-4]))
|
||||
|
@ -433,7 +431,7 @@ class SubmitTests(BaseSubmitTestCase):
|
|||
# Check "Review of suggested possible replacements for..." mail
|
||||
self.assertIn("review", outbox[-1]["Subject"].lower())
|
||||
self.assertIn(name, get_payload_text(outbox[-1]))
|
||||
self.assertIn(sug_replaced_alias.name, get_payload_text(outbox[-1]))
|
||||
self.assertIn(sug_replaced_draft.name, get_payload_text(outbox[-1]))
|
||||
self.assertIn("ames-chairs@", outbox[-1]["To"].lower())
|
||||
self.assertIn("mars-chairs@", outbox[-1]["To"].lower())
|
||||
# Check submission settings
|
||||
|
@ -684,7 +682,7 @@ class SubmitTests(BaseSubmitTestCase):
|
|||
self.assertTrue('New version approved' in edescs)
|
||||
self.assertTrue('Uploaded new revision' in edescs)
|
||||
|
||||
draft = Document.objects.get(docalias__name=name)
|
||||
draft = Document.objects.get(name=name)
|
||||
self.assertEqual(draft.rev, rev)
|
||||
self.assertEqual(draft.group.acronym, name.split("-")[2])
|
||||
#
|
||||
|
@ -911,7 +909,7 @@ class SubmitTests(BaseSubmitTestCase):
|
|||
r = self.client.post(confirmation_url, {'action':'confirm'})
|
||||
self.assertEqual(r.status_code, 302)
|
||||
|
||||
draft = Document.objects.get(docalias__name=name)
|
||||
draft = Document.objects.get(name=name)
|
||||
self.assertEqual(draft.rev, rev)
|
||||
new_revision = draft.latest_event()
|
||||
self.assertEqual(new_revision.type, "new_revision")
|
||||
|
@ -951,7 +949,7 @@ class SubmitTests(BaseSubmitTestCase):
|
|||
action = force_post_button.parents("form").find('input[type=hidden][name="action"]').val()
|
||||
r = self.client.post(status_url, dict(action=action))
|
||||
|
||||
doc = Document.objects.get(docalias__name=name)
|
||||
doc = Document.objects.get(name=name)
|
||||
self.assertEqual(doc.documentauthor_set.count(), 1)
|
||||
docauth = doc.documentauthor_set.first()
|
||||
self.assertEqual(docauth.person, author)
|
||||
|
@ -1084,7 +1082,7 @@ class SubmitTests(BaseSubmitTestCase):
|
|||
self.assertIn("New Version Notification", notification_email["Subject"])
|
||||
self.assertIn(author.email().address.lower(), notification_email["To"])
|
||||
|
||||
draft = Document.objects.get(docalias__name=name)
|
||||
draft = Document.objects.get(name=name)
|
||||
self.assertEqual(draft.rev, rev)
|
||||
self.assertEqual(draft.docextresource_set.count(), 0)
|
||||
new_revision = draft.latest_event()
|
||||
|
@ -1132,7 +1130,7 @@ class SubmitTests(BaseSubmitTestCase):
|
|||
self._assert_extresources_form_not_present(r)
|
||||
|
||||
# Check that the draft itself got the resources
|
||||
draft = Document.objects.get(docalias__name=name)
|
||||
draft = Document.objects.get(name=name)
|
||||
self.assertCountEqual(
|
||||
[str(r) for r in draft.docextresource_set.all()],
|
||||
[str(r) for r in resources],
|
||||
|
@ -1178,7 +1176,7 @@ class SubmitTests(BaseSubmitTestCase):
|
|||
r = self.client.post(confirmation_url, {'action':'confirm'})
|
||||
self.assertEqual(r.status_code, 302)
|
||||
self.assertEqual(len(outbox), mailbox_before+3)
|
||||
draft = Document.objects.get(docalias__name=name)
|
||||
draft = Document.objects.get(name=name)
|
||||
self.assertEqual(draft.rev, rev)
|
||||
self.assertEqual(draft.relateddocument_set.filter(relationship_id='replaces').count(), replaces_count)
|
||||
self.assertEqual(draft.docextresource_set.count(), 0)
|
||||
|
@ -1296,7 +1294,7 @@ class SubmitTests(BaseSubmitTestCase):
|
|||
r = self.client.post(confirmation_url, {'action':'cancel'})
|
||||
self.assertEqual(r.status_code, 302)
|
||||
self.assertEqual(len(outbox), mailbox_before)
|
||||
draft = Document.objects.get(docalias__name=name)
|
||||
draft = Document.objects.get(name=name)
|
||||
self.assertEqual(draft.rev, old_rev)
|
||||
|
||||
def test_submit_new_wg_with_dash(self):
|
||||
|
@ -1453,7 +1451,7 @@ class SubmitTests(BaseSubmitTestCase):
|
|||
r = self.client.post(status_url, dict(action=action))
|
||||
self.assertEqual(r.status_code, 302)
|
||||
|
||||
draft = Document.objects.get(docalias__name=name)
|
||||
draft = Document.objects.get(name=name)
|
||||
self.assertEqual(draft.rev, rev)
|
||||
self.assertEqual(draft.docextresource_set.count(), 0)
|
||||
self.verify_bibxml_ids_creation(draft)
|
||||
|
|
|
@ -25,7 +25,7 @@ from django.utils import timezone
|
|||
|
||||
import debug # pyflakes:ignore
|
||||
|
||||
from ietf.doc.models import ( Document, State, DocAlias, DocEvent, SubmissionDocEvent,
|
||||
from ietf.doc.models import ( Document, State, DocEvent, SubmissionDocEvent,
|
||||
DocumentAuthor, AddedMessageEvent )
|
||||
from ietf.doc.models import NewRevisionDocEvent
|
||||
from ietf.doc.models import RelatedDocument, DocRelationshipName, DocExtResource
|
||||
|
@ -375,10 +375,6 @@ def post_submission(request, submission, approved_doc_desc, approved_subm_desc):
|
|||
events.append(e)
|
||||
log.log(f"{submission.name}: created doc events")
|
||||
|
||||
# update related objects
|
||||
alias, __ = DocAlias.objects.get_or_create(name=submission.name)
|
||||
alias.docs.add(draft)
|
||||
|
||||
draft.set_state(State.objects.get(used=True, type="draft", slug="active"))
|
||||
|
||||
update_authors(draft, submission)
|
||||
|
@ -1000,7 +996,7 @@ def accept_submission(submission: Submission, request: Optional[HttpRequest] = N
|
|||
docevent_from_submission(submission, desc="Uploaded new revision",
|
||||
who=requester if requester_is_author else None)
|
||||
|
||||
replaces = DocAlias.objects.filter(name__in=submission.replaces_names)
|
||||
replaces = Document.objects.filter(name__in=submission.replaces_names)
|
||||
pretty_replaces = '(none)' if not replaces else (
|
||||
', '.join(prettify_std_name(r.name) for r in replaces)
|
||||
)
|
||||
|
|
|
@ -22,7 +22,7 @@ from django.views.decorators.csrf import csrf_exempt
|
|||
|
||||
import debug # pyflakes:ignore
|
||||
|
||||
from ietf.doc.models import Document, DocAlias, AddedMessageEvent
|
||||
from ietf.doc.models import Document, AddedMessageEvent
|
||||
from ietf.doc.forms import ExtResourceForm
|
||||
from ietf.group.models import Group
|
||||
from ietf.group.utils import group_features_group_filter
|
||||
|
@ -410,7 +410,7 @@ def submission_status(request, submission_id, access_token=None):
|
|||
)
|
||||
|
||||
submitter_form = SubmitterForm(initial=submission.submitter_parsed(), prefix="submitter")
|
||||
replaces_form = ReplacesForm(name=submission.name,initial=DocAlias.objects.filter(name__in=submission.replaces.split(",")))
|
||||
replaces_form = ReplacesForm(name=submission.name,initial=Document.objects.filter(name__in=submission.replaces.split(",")))
|
||||
extresources_form = ExtResourceForm(
|
||||
initial=dict(resources=[er['res'] for er in external_resources]),
|
||||
extresource_model=SubmissionExtResource,
|
||||
|
@ -626,7 +626,7 @@ def edit_submission(request, submission_id, access_token=None):
|
|||
else:
|
||||
edit_form = EditSubmissionForm(instance=submission, prefix="edit")
|
||||
submitter_form = SubmitterForm(initial=submission.submitter_parsed(), prefix="submitter")
|
||||
replaces_form = ReplacesForm(name=submission.name,initial=DocAlias.objects.filter(name__in=submission.replaces.split(",")))
|
||||
replaces_form = ReplacesForm(name=submission.name, initial=Document.objects.filter(name__in=submission.replaces.split(",")))
|
||||
author_forms = [ AuthorForm(initial=author, prefix="authors-%s" % i)
|
||||
for i, author in enumerate(submission.authors) ]
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ def update_rfc_log_from_protocol_page(rfc_names, rfc_must_published_later_than):
|
|||
|
||||
updated = []
|
||||
|
||||
docs = Document.objects.filter(docalias__name__in=rfc_names).exclude(
|
||||
docs = Document.objects.filter(name__in=rfc_names).exclude(
|
||||
docevent__type="rfc_in_iana_registry").filter(
|
||||
# only take those that were published after cutoff since we
|
||||
# have a big bunch of old RFCs that we unfortunately don't have data for
|
||||
|
@ -189,7 +189,7 @@ def update_history_with_changes(changes, send_email=True):
|
|||
state_type=state_type, state=state)
|
||||
if not e:
|
||||
try:
|
||||
doc = Document.objects.get(docalias__name=docname)
|
||||
doc = Document.objects.get(name=docname)
|
||||
except Document.DoesNotExist:
|
||||
warnings.append("Document %s not found" % docname)
|
||||
continue
|
||||
|
|
|
@ -17,7 +17,7 @@ from django.utils.encoding import smart_bytes, force_str
|
|||
|
||||
import debug # pyflakes:ignore
|
||||
|
||||
from ietf.doc.models import ( Document, DocAlias, State, StateType, DocEvent, DocRelationshipName,
|
||||
from ietf.doc.models import ( Document, State, StateType, DocEvent, DocRelationshipName,
|
||||
DocTagName, RelatedDocument )
|
||||
from ietf.doc.expire import move_draft_files_to_archive
|
||||
from ietf.doc.utils import add_state_change_event, prettify_std_name, update_action_holders
|
||||
|
@ -156,7 +156,7 @@ def update_drafts_from_queue(drafts):
|
|||
names = [t[0] for t in drafts]
|
||||
|
||||
drafts_in_db = dict((d.name, d)
|
||||
for d in Document.objects.filter(type="draft", docalias__name__in=names))
|
||||
for d in Document.objects.filter(type="draft", name__in=names))
|
||||
|
||||
changed = set()
|
||||
|
||||
|
@ -229,7 +229,7 @@ def update_drafts_from_queue(drafts):
|
|||
|
||||
|
||||
# remove tags and states for those not in the queue anymore
|
||||
for d in Document.objects.exclude(docalias__name__in=names).filter(states__type="draft-rfceditor").distinct():
|
||||
for d in Document.objects.exclude(name__in=names).filter(states__type="draft-rfceditor").distinct():
|
||||
d.tags.remove(*list(tag_mapping.values()))
|
||||
d.unset_state("draft-rfceditor")
|
||||
# we do not add a history entry here - most likely we already
|
||||
|
@ -441,10 +441,6 @@ def update_docs_from_rfc_index(
|
|||
)
|
||||
if created_rfc:
|
||||
rfc_changes.append(f"created document {prettify_std_name(doc.name)}")
|
||||
# Create DocAlias (for consistency until we drop DocAlias altogether)
|
||||
alias, _ = DocAlias.objects.get_or_create(name=doc.name)
|
||||
alias.docs.add(doc)
|
||||
rfc_changes.append(f"created alias {prettify_std_name(doc.name)}")
|
||||
doc.set_state(rfc_published_state)
|
||||
if draft:
|
||||
doc.formal_languages.set(draft.formal_languages.all())
|
||||
|
@ -654,12 +650,15 @@ def update_docs_from_rfc_index(
|
|||
)
|
||||
)
|
||||
|
||||
if also:
|
||||
for a in also:
|
||||
a = a.lower()
|
||||
if not DocAlias.objects.filter(name=a):
|
||||
DocAlias.objects.create(name=a).docs.add(doc)
|
||||
rfc_changes.append(f"created alias {prettify_std_name(a)}")
|
||||
# This block attempted to alias subseries names to RFCs.
|
||||
# Handle that differently when we add subseries as a document type.
|
||||
#
|
||||
# if also:
|
||||
# for a in also:
|
||||
# a = a.lower()
|
||||
# if not DocAlias.objects.filter(name=a):
|
||||
# DocAlias.objects.create(name=a).docs.add(doc)
|
||||
# rfc_changes.append(f"created alias {prettify_std_name(a)}")
|
||||
|
||||
doc_errata = errata.get(f"RFC{rfc_number}", [])
|
||||
all_rejected = doc_errata and all(
|
||||
|
|
|
@ -16,7 +16,7 @@ from django.utils import timezone
|
|||
import debug # pyflakes:ignore
|
||||
|
||||
from ietf.doc.factories import WgDraftFactory, RfcFactory
|
||||
from ietf.doc.models import Document, DocAlias, DocEvent, DeletedEvent, DocTagName, RelatedDocument, State, StateDocEvent
|
||||
from ietf.doc.models import Document, DocEvent, DeletedEvent, DocTagName, RelatedDocument, State, StateDocEvent
|
||||
from ietf.doc.utils import add_state_change_event
|
||||
from ietf.group.factories import GroupFactory
|
||||
from ietf.person.models import Person
|
||||
|
@ -30,19 +30,20 @@ from ietf.utils.timezone import date_today, RPC_TZINFO
|
|||
class IANASyncTests(TestCase):
|
||||
def test_protocol_page_sync(self):
|
||||
draft = WgDraftFactory()
|
||||
DocAlias.objects.create(name="rfc1234").docs.add(draft)
|
||||
DocEvent.objects.create(doc=draft, rev=draft.rev, type="published_rfc", by=Person.objects.get(name="(System)"))
|
||||
rfc = RfcFactory(rfc_number=1234)
|
||||
draft.relateddocument_set.create(relationship_id="became_rfc", target = rfc)
|
||||
DocEvent.objects.create(doc=rfc, rev="", type="published_rfc", by=Person.objects.get(name="(System)"))
|
||||
|
||||
rfc_names = iana.parse_protocol_page('<html><a href="/go/rfc1234/">RFC 1234</a></html>')
|
||||
self.assertEqual(len(rfc_names), 1)
|
||||
self.assertEqual(rfc_names[0], "rfc1234")
|
||||
|
||||
iana.update_rfc_log_from_protocol_page(rfc_names, timezone.now() - datetime.timedelta(days=1))
|
||||
self.assertEqual(DocEvent.objects.filter(doc=draft, type="rfc_in_iana_registry").count(), 1)
|
||||
self.assertEqual(DocEvent.objects.filter(doc=rfc, type="rfc_in_iana_registry").count(), 1)
|
||||
|
||||
# make sure it doesn't create duplicates
|
||||
iana.update_rfc_log_from_protocol_page(rfc_names, timezone.now() - datetime.timedelta(days=1))
|
||||
self.assertEqual(DocEvent.objects.filter(doc=draft, type="rfc_in_iana_registry").count(), 1)
|
||||
self.assertEqual(DocEvent.objects.filter(doc=rfc, type="rfc_in_iana_registry").count(), 1)
|
||||
|
||||
def test_changes_sync(self):
|
||||
draft = WgDraftFactory(ad=Person.objects.get(user__username='ad'))
|
||||
|
@ -380,10 +381,11 @@ class RFCSyncTests(TestCase):
|
|||
tag_slugs = rfc_doc.tags.values_list("slug", flat=True)
|
||||
self.assertTrue("errata" in tag_slugs)
|
||||
self.assertFalse("verified-errata" in tag_slugs)
|
||||
self.assertTrue(DocAlias.objects.filter(name="rfc1234", docs=rfc_doc))
|
||||
self.assertTrue(DocAlias.objects.filter(name="bcp1", docs=rfc_doc))
|
||||
self.assertTrue(DocAlias.objects.filter(name="fyi1", docs=rfc_doc))
|
||||
self.assertTrue(DocAlias.objects.filter(name="std1", docs=rfc_doc))
|
||||
# TODO: adjust these when we have subseries document types
|
||||
# self.assertTrue(DocAlias.objects.filter(name="rfc1234", docs=rfc_doc))
|
||||
# self.assertTrue(DocAlias.objects.filter(name="bcp1", docs=rfc_doc))
|
||||
# self.assertTrue(DocAlias.objects.filter(name="fyi1", docs=rfc_doc))
|
||||
# self.assertTrue(DocAlias.objects.filter(name="std1", docs=rfc_doc))
|
||||
self.assertTrue(RelatedDocument.objects.filter(source=rfc_doc, target__name="rfc123", relationship="updates").exists())
|
||||
self.assertTrue(RelatedDocument.objects.filter(source=draft_doc, target=rfc_doc, relationship="became_rfc").exists())
|
||||
self.assertEqual(rfc_doc.title, "A Testing RFC")
|
||||
|
|
|
@ -67,7 +67,7 @@
|
|||
<label class="d-none d-md-block" aria-label="Document search">
|
||||
<input class="form-control select2-field search-select"
|
||||
id="navbar-doc-search"
|
||||
data-select2-ajax-url="{% url 'ietf.doc.views_search.ajax_select2_search_docs' model_name='docalias' doc_type='draft' %}"
|
||||
data-select2-ajax-url="{% url 'ietf.doc.views_search.ajax_select2_search_docs' model_name='document' doc_type='draft' %}"
|
||||
type="text"
|
||||
data-placeholder="Document search">
|
||||
</label>
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
href="{% url 'ietf.doc.views_ballot.approve_ballot' name=doc.name %}">Approve ballot</a>
|
||||
{% endif %}
|
||||
<a class="btn btn-secondary float-end"
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.canonical_name %}">
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.name %}">
|
||||
Back
|
||||
</a>
|
||||
</form>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<button class="btn btn-primary" type="submit">Email RFC Editor (DNP) & close ballot"</button>
|
||||
{% endif %}
|
||||
<a class="btn btn-secondary float-end"
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.canonical_name %}">
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.name %}">
|
||||
Back
|
||||
</a>
|
||||
</form>
|
||||
|
|
|
@ -12,16 +12,16 @@
|
|||
</h1>
|
||||
<p>
|
||||
The ballot for
|
||||
<a href="{% url "ietf.doc.views_doc.document_main" name=doc.canonical_name %}">{{ doc }}</a>
|
||||
<a href="{% url "ietf.doc.views_doc.document_main" name=doc.name %}">{{ doc }}</a>
|
||||
was just approved.
|
||||
</p>
|
||||
{% if not downrefs_to_rfc %}
|
||||
<p>
|
||||
No downward references for
|
||||
<a href="{% url "ietf.doc.views_doc.document_main" name=doc.canonical_name %}">{{ doc }}</a>
|
||||
<a href="{% url "ietf.doc.views_doc.document_main" name=doc.name %}">{{ doc }}</a>
|
||||
</p>
|
||||
<a class="btn btn-secondary"
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.canonical_name %}">Back</a>
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.name %}">Back</a>
|
||||
{% else %}
|
||||
<p>
|
||||
Add downward references to RFCs to the DOWNREF registry, if they were identified in the IETF Last Call and approved by the Sponsoring Area Director.
|
||||
|
@ -41,7 +41,7 @@
|
|||
{% csrf_token %}
|
||||
{% bootstrap_form approve_downrefs_form %}
|
||||
<a class="btn btn-primary"
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.canonical_name %}">
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.name %}">
|
||||
Add no DOWNREF entries
|
||||
</a>
|
||||
<button type="submit" class="btn btn-warning" value="Save checked downrefs">Add checked DOWNREF entries</button>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
</h1>
|
||||
<p>
|
||||
Ballot for
|
||||
<a href="{% url "ietf.doc.views_doc.document_main" name=doc.canonical_name %}">{{ doc }}</a>
|
||||
<a href="{% url "ietf.doc.views_doc.document_main" name=doc.name %}">{{ doc }}</a>
|
||||
has been sent out.
|
||||
</p>
|
||||
{% if doc.telechat_date %}
|
||||
|
@ -24,5 +24,5 @@
|
|||
</p>
|
||||
{% endif %}
|
||||
<a class="btn btn-secondary"
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.canonical_name %}">Back</a>
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.name %}">Back</a>
|
||||
{% endblock %}
|
||||
|
|
|
@ -14,14 +14,14 @@
|
|||
{% csrf_token %}
|
||||
<p class="alert alert-danger my-3">
|
||||
<b>Clear the ballot for
|
||||
<a href="{% url "ietf.doc.views_doc.document_main" name=doc.canonical_name %}">{{ doc }}</a>?
|
||||
<a href="{% url "ietf.doc.views_doc.document_main" name=doc.name %}">{{ doc }}</a>?
|
||||
</b>
|
||||
<br>
|
||||
This will clear all ballot positions and discuss entries.
|
||||
</p>
|
||||
<button type="submit" class="btn btn-danger">Clear</button>
|
||||
<a class="btn btn-secondary float-end"
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.canonical_name %}">
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.name %}">
|
||||
Back
|
||||
</a>
|
||||
</form>
|
||||
|
|
|
@ -14,14 +14,14 @@
|
|||
{% csrf_token %}
|
||||
<p class="alert alert-danger my-3">
|
||||
<b>Defer the ballot for
|
||||
<a href="{% url "ietf.doc.views_doc.document_main" name=doc.canonical_name %}">{{ doc }}</a>?
|
||||
<a href="{% url "ietf.doc.views_doc.document_main" name=doc.name %}">{{ doc }}</a>?
|
||||
</b>
|
||||
<br>
|
||||
The ballot will then be put on the IESG agenda of {{ telechat_date }}.
|
||||
</p>
|
||||
<button type="submit" class="btn btn-danger">Defer ballot</button>
|
||||
<a class="btn btn-secondary float-end"
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.canonical_name %}">
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.name %}">
|
||||
Back
|
||||
</a>
|
||||
</form>
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
{% endif %}
|
||||
{% endif %}
|
||||
<a class="btn btn-secondary float-end"
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.canonical_name %}">
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.name %}">
|
||||
Back
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
href="{% url 'ietf.doc.views_ballot.make_last_call' name=doc.name %}">Issue last call</a>
|
||||
{% endif %}
|
||||
<a class="btn btn-secondary float-end"
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.canonical_name %}">
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.name %}">
|
||||
Back
|
||||
</a>
|
||||
</form>
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
Clear
|
||||
</button>
|
||||
<a class="btn btn-secondary float-end"
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.canonical_name %}">
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.name %}">
|
||||
Back
|
||||
</a>
|
||||
</form>
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
</div>
|
||||
<button type="submit" class="btn btn-danger">Send</button>
|
||||
<a class="btn btn-secondary float-end"
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.canonical_name %}">
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.name %}">
|
||||
Back
|
||||
</a>
|
||||
</form>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
</p>
|
||||
<button class="btn btn-danger" type="submit">Undefer ballot</button>
|
||||
<a class="btn btn-secondary float-end"
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.canonical_name %}">
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.name %}">
|
||||
Back
|
||||
</a>
|
||||
</form>
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
Save & {% if ballot_issued %}re-{% endif %}issue ballot
|
||||
</button>
|
||||
<a class="btn btn-secondary float-end"
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.canonical_name %}">
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.name %}">
|
||||
Back
|
||||
</a>
|
||||
</form>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
{% bootstrap_form form %}
|
||||
<button type="submit" class="btn btn-primary">Submit</button>
|
||||
<a class="btn btn-secondary float-end"
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.canonical_name %}">
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.name %}">
|
||||
Back
|
||||
</a>
|
||||
</form>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
{% bootstrap_form form %}
|
||||
<button type="submit" class="btn btn-primary">Submit</button>
|
||||
<a class="btn btn-secondary float-end"
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.canonical_name %}">
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.name %}">
|
||||
Back
|
||||
</a>
|
||||
</form>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
{% bootstrap_form form %}
|
||||
<button type="submit" class="btn btn-primary">Submit</button>
|
||||
<a class="btn btn-secondary float-end"
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.canonical_name %}">
|
||||
href="{% url "ietf.doc.views_doc.document_main" name=doc.name %}">
|
||||
Back
|
||||
</a>
|
||||
</form>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue