Port IPR tool to new schema and fix some bugs

- Legacy-Id: 3158
This commit is contained in:
Ole Laursen 2011-05-27 11:07:59 +00:00
parent fd23dc9d5d
commit 215d4ff9fd
15 changed files with 335 additions and 46 deletions

View file

@ -122,7 +122,8 @@ class RfcAdmin(admin.ModelAdmin):
fieldsets=((None, {'fields': ('rfc_number', 'title', 'group_acronym', 'area_acronym', 'status', 'comments', 'last_modified_date')}), ('Metadata', {'fields': (('online_version', 'txt_page_count'), ('fyi_number', 'std_number')), 'classes': 'collapse'}), ('Standards Track Dates', {'fields': ('rfc_published_date', ('proposed_date', 'draft_date'), ('standard_date', 'historic_date')), 'classes': 'collapse'}), ('Last Call / Ballot Info', {'fields': ('intended_status', ('lc_sent_date', 'lc_expiration_date'), ('b_sent_date', 'b_approve_date')), 'classes': 'collapse'}))
list_display=['rfc_number', 'title']
search_fields=['title']
admin.site.register(Rfc, RfcAdmin)
if not settings.USE_DB_REDESIGN_PROXY_CLASSES:
admin.site.register(Rfc, RfcAdmin)
class RfcIntendedStatusAdmin(admin.ModelAdmin):
pass

View file

@ -1089,13 +1089,14 @@ class DocumentWrapper(object):
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
InternetDraftOld = InternetDraft
IDInternalOld = IDInternal
RfcOld = Rfc
BallotInfoOld = BallotInfo
IDStateOld = IDState
IDSubStateOld = IDSubState
AreaOld = Area
AcronymOld = Acronym
IESGLoginOld = IESGLogin
from redesign.doc.proxy import InternetDraft, IDInternal, BallotInfo, IDState, IDSubState
from redesign.doc.proxy import InternetDraft, IDInternal, BallotInfo, IDState, IDSubState, Rfc
from redesign.group.proxy import Area, Acronym
from redesign.person.proxy import IESGLogin

View file

@ -1,5 +1,6 @@
#coding: utf-8
from django.contrib import admin
from django.conf import settings
from ietf.ipr.models import *
class IprContactAdmin(admin.ModelAdmin):
@ -12,7 +13,8 @@ admin.site.register(IprDetail, IprDetailAdmin)
class IprDraftAdmin(admin.ModelAdmin):
pass
admin.site.register(IprDraft, IprDraftAdmin)
if not settings.USE_DB_REDESIGN_PROXY_CLASSES:
admin.site.register(IprDraft, IprDraftAdmin)
class IprLicensingAdmin(admin.ModelAdmin):
pass
@ -24,7 +26,8 @@ admin.site.register(IprNotification, IprNotificationAdmin)
class IprRfcAdmin(admin.ModelAdmin):
pass
admin.site.register(IprRfc, IprRfcAdmin)
if not settings.USE_DB_REDESIGN_PROXY_CLASSES:
admin.site.register(IprRfc, IprRfcAdmin)
class IprSelecttypeAdmin(admin.ModelAdmin):
pass

View file

@ -115,6 +115,8 @@ class IprDetail(models.Model):
def __str__(self):
return self.title
def docs(self):
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
return list(IprDraftProxy.objects.filter(ipr=self))
return list(self.drafts.all()) + list(self.rfcs.all())
def get_absolute_url(self):
return "/ipr/%d/" % self.ipr_id
@ -151,7 +153,7 @@ class IprContact(models.Model):
class IprDraft(models.Model):
ipr = models.ForeignKey(IprDetail, related_name='drafts_old' if settings.USE_DB_REDESIGN_PROXY_CLASSES else 'drafts')
document = models.ForeignKey(InternetDraft, db_column='id_document_tag', related_name="ipr_old" if settings.USE_DB_REDESIGN_PROXY_CLASSES else "ipr")
document = models.ForeignKey(InternetDraft, db_column='id_document_tag', related_name="ipr_draft_old" if settings.USE_DB_REDESIGN_PROXY_CLASSES else "ipr")
revision = models.CharField(max_length=2)
def __str__(self):
return "%s which applies to %s-%s" % ( self.ipr, self.document, self.revision )
@ -170,7 +172,7 @@ class IprNotification(models.Model):
class IprRfc(models.Model):
ipr = models.ForeignKey(IprDetail, related_name='rfcs_old' if settings.USE_DB_REDESIGN_PROXY_CLASSES else 'rfcs')
document = models.ForeignKey(Rfc, db_column='rfc_number', related_name="ipr")
document = models.ForeignKey(Rfc, db_column='rfc_number', related_name="ipr_rfc_old" if settings.USE_DB_REDESIGN_PROXY_CLASSES else "ipr")
def __str__(self):
return "%s applies to RFC%04d" % ( self.ipr, self.document_id )
class Meta:
@ -186,19 +188,41 @@ class IprUpdate(models.Model):
db_table = 'ipr_updates'
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
from doc.models import Document
if settings.USE_DB_REDESIGN_PROXY_CLASSES or hasattr(settings, "IMPORTING_IPR"):
from doc.models import DocAlias
class IprDocument(models.Model):
class IprDocAlias(models.Model):
ipr = models.ForeignKey(IprDetail, related_name='documents')
document = models.ForeignKey(Document, related_name="ipr")
rev = models.CharField(max_length=2)
doc_alias = models.ForeignKey(DocAlias)
rev = models.CharField(max_length=2, blank=True)
def __unicode__(self):
if self.rev != None:
if self.rev:
return u"%s which applies to %s-%s" % (self.ipr, self.document, self.revision)
else:
return u"%s which applies to %s" % (self.ipr, self.document)
# proxy stuff
IprDraftOld = IprDraft
IprRfcOld = IprRfc
class IprDraftProxy(IprDocAlias):
# document = models.ForeignKey(InternetDraft, db_column='id_document_tag', "ipr")
# document = models.ForeignKey(Rfc, db_column='rfc_number', related_name="ipr")
@property
def document(self):
from redesign.doc.proxy import DraftLikeDocAlias
return DraftLikeDocAlias.objects.get(pk=self.doc_alias_id)
#revision = models.CharField(max_length=2)
@property
def revision(self):
return self.rev
class Meta:
proxy = True
IprDraft = IprDraftProxy
IprRfc = IprDraftProxy

View file

@ -134,7 +134,11 @@ def new(request, type, update=None, submitter=None):
rfclist = rfclist.strip().split()
for rfc in rfclist:
try:
Rfc.objects.get(rfc_number=int(rfc))
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
from doc.models import DocAlias
DocAlias.objects.get(name="rfc%s" % int(rfc))
else:
Rfc.objects.get(rfc_number=int(rfc))
except:
raise forms.ValidationError("Unknown RFC number: %s - please correct this." % rfc)
rfclist = " ".join(rfclist)
@ -155,7 +159,13 @@ def new(request, type, update=None, submitter=None):
filename = draft
rev = None
try:
id = InternetDraft.objects.get(filename=filename)
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
from doc.models import DocAlias
id = DocAlias.objects.get(name=filename)
# proxy attribute for code below
id.revision = id.document.rev
else:
id = InternetDraft.objects.get(filename=filename)
except Exception, e:
log("Exception: %s" % e)
raise forms.ValidationError("Unknown Internet-Draft: %s - please correct this." % filename)
@ -263,15 +273,32 @@ def new(request, type, update=None, submitter=None):
# Save IprDraft(s)
for draft in form.cleaned_data["draftlist"].split():
id = InternetDraft.objects.get(filename=draft[:-3])
iprdraft = models.IprDraft(document=id, ipr=instance, revision=draft[-2:])
iprdraft.save()
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
name = draft[:-3]
rev = draft[-2:]
from doc.models import DocAlias
models.IprDocAlias.objects.create(
doc_alias=DocAlias.objects.get(name=name),
ipr=instance,
rev=rev)
else:
id = InternetDraft.objects.get(filename=draft[:-3])
iprdraft = models.IprDraft(document=id, ipr=instance, revision=draft[-2:])
iprdraft.save()
# Save IprRfc(s)
for rfcnum in form.cleaned_data["rfclist"].split():
rfc = Rfc.objects.get(rfc_number=int(rfcnum))
iprrfc = models.IprRfc(document=rfc, ipr=instance)
iprrfc.save()
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
from doc.models import DocAlias
models.IprDocAlias.objects.create(
doc_alias=DocAlias.objects.get(name="rfc%s" % int(rfcnum)),
ipr=instance,
rev="")
else:
rfc = Rfc.objects.get(rfc_number=int(rfcnum))
iprrfc = models.IprRfc(document=rfc, ipr=instance)
iprrfc.save()
send_mail(request, settings.IPR_EMAIL_TO, ('IPR Submitter App', 'ietf-ipr@ietf.org'), 'New IPR Submission Notification', "ipr/new_update_email.txt", {"ipr": instance, "update": update})
return render("ipr/submitted.html", {"update": update}, context_instance=RequestContext(request))

View file

@ -1,5 +1,7 @@
# Copyright The IETF Trust 2007, All Rights Reserved
from django.conf import settings
from django.db.models import Q
from ietf.idtracker.models import InternetDraft, Rfc
inverse = {
@ -77,3 +79,59 @@ def related_docs(doc, found = []):
set_relation(doc, 'is_draft_of', item)
found = related_docs(item, found)
return found
def related_docsREDESIGN(alias, _):
"""Get related document aliases to given alias through depth-first search."""
from redesign.doc.models import RelatedDocument
from redesign.doc.proxy import DraftLikeDocAlias
mapping = dict(
updates='that updated',
obs='that obsoleted',
replaces='that replaced',
)
inverse_mapping = dict(
updates='that was updated by',
obs='that was obsoleted by',
replaces='that was replaced by',
)
res = [ alias ]
remaining = [ alias ]
while remaining:
a = remaining.pop()
related = RelatedDocument.objects.filter(relationship__in=mapping.keys()).filter(Q(source=a.document) | Q(target=a))
for r in related:
if r.source == a.document:
found = DraftLikeDocAlias.objects.filter(pk=r.target_id)
inverse = True
else:
found = DraftLikeDocAlias.objects.filter(document=r.source)
inverse = False
for x in found:
if not x in res:
x.related = a
x.relation = (inverse_mapping if inverse else mapping)[r.relationship_id]
res.append(x)
remaining.append(x)
# there's one more source of relatedness, a draft can have been published
aliases = DraftLikeDocAlias.objects.filter(document=a.document).exclude(pk__in=[x.pk for x in res])
for oa in aliases:
rel = None
if a.name.startswith("rfc") and oa.name.startswith("draft"):
rel = "that was published as"
elif a.name.startswith("draft") and oa.name.startswith("rfc"):
rel = "which came from"
if rel:
oa.related = a
oa.relation = rel
res.append(oa)
remaining.append(oa)
return res
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
related_docs = related_docsREDESIGN

View file

@ -24,7 +24,11 @@ def mark_last_doc(iprs):
def iprs_from_docs(docs):
iprs = []
for doc in docs:
if isinstance(doc, InternetDraft):
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
from ietf.ipr.models import IprDocAlias
disclosures = [ x.ipr for x in IprDocAlias.objects.filter(doc_alias=doc, ipr__status__in=[1,3]) ]
elif isinstance(doc, InternetDraft):
disclosures = [ item.ipr for item in IprDraft.objects.filter(document=doc, ipr__status__in=[1,3]) ]
elif isinstance(doc, Rfc):
disclosures = [ item.ipr for item in IprRfc.objects.filter(document=doc, ipr__status__in=[1,3]) ]
@ -50,7 +54,11 @@ def patent_file_search(url, q):
return False
def search(request, type="", q="", id=""):
wgs = IETFWG.objects.filter(group_type__group_type_id=1).exclude(group_acronym__acronym='2000').select_related().order_by('acronym.acronym')
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
from group.models import Group
wgs = Group.objects.filter(type="wg").exclude(acronym="2000").select_related().order_by("acronym")
else:
wgs = IETFWG.objects.filter(group_type__group_type_id=1).exclude(group_acronym__acronym='2000').select_related().order_by('acronym.acronym')
args = request.REQUEST.items()
if args:
for key, value in args:
@ -70,20 +78,32 @@ def search(request, type="", q="", id=""):
if type == "document_search":
if q:
q = normalize_draftname(q)
start = InternetDraft.objects.filter(filename__contains=q)
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
from redesign.doc.proxy import DraftLikeDocAlias
start = DraftLikeDocAlias.objects.filter(name__contains=q, name__startswith="draft")
else:
start = InternetDraft.objects.filter(filename__contains=q)
if id:
try:
id = int(id,10)
except:
id = -1
start = InternetDraft.objects.filter(id_document_tag=id)
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
from redesign.doc.proxy import DraftLikeDocAlias
start = DraftLikeDocAlias.objects.filter(name=id)
else:
try:
id = int(id,10)
except:
id = -1
start = InternetDraft.objects.filter(id_document_tag=id)
if type == "rfc_search":
if q:
try:
q = int(q, 10)
except:
q = -1
start = Rfc.objects.filter(rfc_number=q)
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
from redesign.doc.proxy import DraftLikeDocAlias
start = DraftLikeDocAlias.objects.filter(name__contains=q, name__startswith="rfc")
else:
start = Rfc.objects.filter(rfc_number=q)
if start.count() == 1:
first = start[0]
doc = str(first)
@ -142,12 +162,20 @@ def search(request, type="", q="", id=""):
# Search by wg acronym
# Document list with IPRs
elif type == "wg_search":
try:
docs = list(InternetDraft.objects.filter(group__acronym=q))
except:
docs = []
docs += [ draft.replaced_by for draft in docs if draft.replaced_by_id ]
docs += list(Rfc.objects.filter(group_acronym=q))
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
from redesign.doc.proxy import DraftLikeDocAlias
try:
docs = list(DraftLikeDocAlias.objects.filter(document__group__acronym=q))
docs += list(DraftLikeDocAlias.objects.filter(document__relateddocument__target__in=docs, document__relateddocument__relationship="replaces"))
except:
docs = []
else:
try:
docs = list(InternetDraft.objects.filter(group__acronym=q))
except:
docs = []
docs += [ draft.replaced_by for draft in docs if draft.replaced_by_id ]
docs += list(Rfc.objects.filter(group_acronym=q))
docs = [ doc for doc in docs if doc.ipr.count() ]
iprs, docs = iprs_from_docs(docs)
@ -158,11 +186,18 @@ def search(request, type="", q="", id=""):
# Search by rfc and id title
# Document list with IPRs
elif type == "title_search":
try:
docs = list(InternetDraft.objects.filter(title__icontains=q))
except:
docs = []
docs += list(Rfc.objects.filter(title__icontains=q))
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
from redesign.doc.proxy import DraftLikeDocAlias
try:
docs = list(DraftLikeDocAlias.objects.filter(document__title__icontains=q))
except:
docs = []
else:
try:
docs = list(InternetDraft.objects.filter(title__icontains=q))
except:
docs = []
docs += list(Rfc.objects.filter(title__icontains=q))
docs = [ doc for doc in docs if doc.ipr.count() ]
iprs, docs = iprs_from_docs(docs)

View file

@ -48,6 +48,8 @@ class IprUrlTestCase(SimpleUrlTestCase):
else:
return content
# this test should be ported to run on a test database instead of the
# real database, and possibly expanded
class NewIprTestCase(unittest.TestCase,RealDatabaseTest):
SPECIFIC_DISCLOSURE = {
'legal_name':'Testing Only Please Ignore',
@ -58,6 +60,7 @@ class NewIprTestCase(unittest.TestCase,RealDatabaseTest):
'ietf_telephone':'555-555-0101',
'ietf_email':'test.participant@example.com',
'rfclist':'1149',
'draftlist':'draft-burdis-http-sasl-00',
'patents':'none',
'date_applied':'never',
'country':'nowhere',

View file

@ -48,6 +48,34 @@ def list_drafts(request):
context_instance=RequestContext(request)),
mimetype="text/plain")
def list_draftsREDESIGN(request):
from ipr.models import IprDocAlias
docipr = {}
for o in IprDocAlias.objects.filter(ipr__status=1).select_related("doc_alias"):
name = o.doc_alias.name
if name.startswith("rfc"):
name = name.upper()
if not name in docipr:
docipr[name] = []
docipr[name].append(o.ipr_id)
docs = [ dict(name=name, iprs=sorted(iprs)) for name, iprs in docipr.iteritems() ]
# drafts.html is not an HTML file
return HttpResponse(render_to_string("ipr/drafts.html",
dict(docs=docs),
context_instance=RequestContext(request)),
mimetype="text/plain")
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
list_drafts = list_draftsREDESIGN
# Details views
def show(request, ipr_id=None, removed=None):
@ -93,6 +121,12 @@ def show(request, ipr_id=None, removed=None):
except:
# if file does not exist, iframe is used instead
pass
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
from ietf.ipr.models import IprDraft, IprRfc
ipr.drafts = IprDraft.objects.filter(ipr=ipr).exclude(doc_alias__name__startswith="rfc").order_by("id")
ipr.rfcs = IprRfc.objects.filter(ipr=ipr).filter(doc_alias__name__startswith="rfc").order_by("id")
return render("ipr/details.html", {"ipr": ipr, "section_list": section_list},
context_instance=RequestContext(request))

View file

@ -170,7 +170,7 @@ Template for {{ section_list.disclosure_type }}" where the submitter provided
<tr class="{% cycle row_parity %}"><td class="iprlabel">I-D Filenames (draft-...):</td><td class="iprdata">{{ ipr.draftlist }}</td></tr>
{% else %}
{% for doc in ipr.drafts.all %}
<tr class="{% cycle row_parity %}"><td class="iprlabel">Internet-Draft:</td><td class="iprdata">"{{ doc.document.title }}"<br />({{ doc.document.filename }}-{{ doc.revision }})</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Internet-Draft:</td><td class="iprdata">"{{ doc.document.title }}"<br />({{ doc.document.filename }}{% if doc.revision %}-{{ doc.revision }}{% endif %})</td></tr>
{% endfor %}
{% endif %}
{% if ipr.other_designations %}

View file

@ -24,7 +24,7 @@
<td colspan="3">
{% block intro_prefix %}IPR that was submitted by <b><i>{{ q }}</i></b>, and{% endblock %}
{% block related %}
{% if not ipr.drafts.count and not ipr.rfcs.count %}
{% if not ipr.docs %}
is not related to a specific IETF contribution.
{% else %}
is related to

View file

@ -27,7 +27,7 @@ class DocumentInfo(models.Model):
rfc_state = models.ForeignKey(RfcDocStateName, verbose_name="RFC state", blank=True, null=True)
# Other
abstract = models.TextField()
rev = models.CharField(verbose_name="revision", max_length=16)
rev = models.CharField(verbose_name="revision", max_length=16, blank=True)
pages = models.IntegerField(blank=True, null=True)
intended_std_level = models.ForeignKey(IntendedStdLevelName, blank=True, null=True)
std_level = models.ForeignKey(StdLevelName, blank=True, null=True)

View file

@ -9,7 +9,8 @@ import glob, os
class InternetDraft(Document):
objects = TranslatingManager(dict(filename="name",
id_document_tag="id",
filename__contains="name__contains",
id_document_tag="pk",
status=lambda v: ("state", { 1: 'active', 2: 'expired', 3: 'rfc', 4: 'auth-rm', 5: 'repl', 6: 'ietf-rm'}[v]),
job_owner="ad",
rfc_number=lambda v: ("docalias__name", "rfc%s" % v),
@ -149,6 +150,11 @@ class InternetDraft(Document):
def replaced_by(self):
r = InternetDraft.objects.filter(relateddocument__target__document=self, relateddocument__relationship="replaces")
return r[0] if r else None
@property
def replaced_by_id(self):
r = self.replaced_by
return r.id_document_tag if r else None
#replaces = FKAsOneToOne('replaces', reverse=True)
@property
@ -714,6 +720,11 @@ class InternetDraft(Document):
d = Dummy()
d.res = res
return d
@property
def ipr(self):
from ipr.models import IprDraftProxy
return IprDraftProxy.objects.filter(doc_alias__document=self.pk)
class Meta:
proxy = True
@ -721,6 +732,7 @@ class InternetDraft(Document):
IDInternal = InternetDraft
BallotInfo = InternetDraft
RfcIndex = InternetDraft
Rfc = InternetDraft
class IDAuthor(DocumentAuthor):
@ -938,3 +950,35 @@ class IDSubState(DocInfoTagName):
class Meta:
proxy = True
class DraftLikeDocAlias(DocAlias):
# this class is mostly useful for the IPR part
def __str__(self):
return str(unicode(self))
def __unicode__(self):
if self.name.startswith("rfc"):
return "RFC%04d" % int(self.name[3:])
else:
return self.name
@property
def id_document_tag(self):
return self.name
@property
def title(self):
return self.document.title
@property
def filename(self):
return self.name
@property
def ipr(self):
from ipr.models import IprDraftProxy
return IprDraftProxy.objects.filter(doc_alias=self.pk)
class Meta:
proxy = True

View file

@ -992,7 +992,7 @@ for index, o in enumerate(all_rfcs.iterator()):
res.append(x)
return res
RelatedDocument.objects.filter(document=d).delete()
RelatedDocument.objects.filter(source=d).delete()
for x in parse_relation_list(o.obsoletes):
make_relation(x, relationship_obsoletes, False)
for x in parse_relation_list(o.obsoleted_by):

View file

@ -0,0 +1,59 @@
#!/usr/bin/python
import sys, os, re, datetime
basedir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../.."))
sys.path = [ basedir ] + sys.path
from ietf import settings
settings.USE_DB_REDESIGN_PROXY_CLASSES = False
settings.IMPORTING_IPR = True
from django.core import management
management.setup_environ(settings)
from ietf.ipr.models import IprDraftOld, IprRfcOld, IprDocAlias, IprDetail
from redesign.doc.models import DocAlias
# imports IprDraft and IprRfc, converting them to IprDocAlias links to Document
# assumptions: documents have been imported
# some links are borked, only import those that reference an existing IprDetail
ipr_ids = IprDetail.objects.all()
for o in IprDraftOld.objects.filter(ipr__in=ipr_ids).select_related("document").order_by("id").iterator():
try:
alias = DocAlias.objects.get(name=o.document.filename)
except DocAlias.DoesNotExist:
print "COULDN'T FIND DOCUMENT", o.document.filename
continue
try:
IprDocAlias.objects.get(ipr=o.ipr_id, doc_alias=alias)
except IprDocAlias.DoesNotExist:
link = IprDocAlias()
link.ipr_id = o.ipr_id
link.doc_alias = alias
link.rev = o.revision or ""
link.save()
print "importing IprDraft", o.pk, "linking", o.ipr_id, o.document.filename
for o in IprRfcOld.objects.filter(ipr__in=ipr_ids).select_related("document").order_by("id").iterator():
try:
alias = DocAlias.objects.get(name="rfc%s" % o.document.rfc_number)
except DocAlias.DoesNotExist:
print "COULDN'T FIND RFC%s", o.document.rfc_number
continue
try:
IprDocAlias.objects.get(ipr=o.ipr_id, doc_alias=alias)
except IprDocAlias.DoesNotExist:
link = IprDocAlias()
link.ipr_id = o.ipr_id
link.doc_alias = alias
link.rev = ""
link.save()
print "importing IprRfc", o.pk, "linking", o.ipr_id, o.document.rfc_number