Rewrote text_to_dict() and dict_to_text() to support unicode without RFC2822 encoding issues. Added initial values in IPR update forms, from the original disclosure, in order to make updates easier. Addresses issue #2413.

- Legacy-Id: 14531
This commit is contained in:
Henrik Levkowetz 2018-01-17 00:21:34 +00:00
parent d7e1d258e5
commit 717868cae2
5 changed files with 65 additions and 15 deletions

View file

@ -17,6 +17,7 @@ from ietf.ipr.models import (IprDocRel, IprDisclosureBase, HolderIprDisclosure,
IprLicenseTypeName, IprDisclosureStateName)
from ietf.message.models import Message
from ietf.utils.fields import DatepickerDateField
from ietf.utils.text import dict_to_text
# ----------------------------------------------------------------
# Globals
@ -178,8 +179,9 @@ class GenericDisclosureForm(forms.Form):
raise forms.ValidationError("A generic IPR disclosure cannot have any patent-specific information, "
"but a patent-specific disclosure must provide full patent information.")
patent_values = [str(v) for v in patent_values if v ] + [ cleaned_data['patent_notes'] ]
cleaned_data['patent_info'] = ('\n'.join(patent_values)).strip()
patent_fields += ['patent_notes']
patent_info = dict([ (k.replace('patent_','').capitalize(), cleaned_data.get(k)) for k in patent_fields if cleaned_data.get(k) ] )
cleaned_data['patent_info'] = dict_to_text(patent_info).strip()
cleaned_data['patent_fields'] = patent_fields
return cleaned_data
@ -189,7 +191,7 @@ class GenericDisclosureForm(forms.Form):
same_as_ii_above = nargs.get('same_as_ii_above')
del nargs['same_as_ii_above']
for k in self.cleaned_data['patent_fields'] + ['patent_fields', 'patent_notes']:
for k in self.cleaned_data['patent_fields'] + ['patent_fields',]:
del nargs[k]
if self.cleaned_data.get('patent_info'):
@ -261,9 +263,9 @@ class IprDisclosureFormBase(forms.ModelForm):
raise forms.ValidationError('Submitter information must be provided in section VII')
patent_fields = [ 'patent_'+k for k in ['number', 'inventor', 'title', 'date', 'notes'] ]
patent_values = [ cleaned_data.get(k) for k in patent_fields ]
patent_values = [ str(v) for v in patent_values if v ]
cleaned_data['patent_info'] = ('\n'.join(patent_values)).strip()
patent_info = dict([ (k.replace('patent_','').capitalize(), cleaned_data.get(k)) for k in patent_fields if cleaned_data.get(k) ] )
cleaned_data['patent_info'] = dict_to_text(patent_info).strip()
cleaned_data['patent_fields'] = patent_fields
return cleaned_data

View file

@ -39,7 +39,7 @@ class IprTests(TestCase):
title="Statement regarding rights Update",
holder_legal_name="Native Martians United",
state_id='pending',
patent_info='US12345',
patent_info='Number: US12345\nTitle: A method of transfering bits\nInventor: A. Nonymous\nDate: 2000-01-01',
holder_contact_name='Update Holder',
holder_contact_email='update_holder@acme.com',
licensing_id='royalty-free',
@ -383,8 +383,13 @@ class IprTests(TestCase):
def test_update(self):
draft = make_test_data()
original_ipr = IprDisclosureBase.objects.get(title='Statement regarding rights')
url = urlreverse("ietf.ipr.views.new", kwargs={ "type": "specific" })
# get
url = urlreverse("ietf.ipr.views.update", kwargs={ "id": original_ipr.id })
r = self.client.get(url)
self.assertContains(r, "Statement regarding rights")
#url = urlreverse("ietf.ipr.views.new", kwargs={ "type": "specific" })
# successful post
empty_outbox()
r = self.client.post(url, {

View file

@ -7,7 +7,7 @@ from django.conf import settings
from django.contrib import messages
from django.urls import reverse as urlreverse
from django.db.models import Q
from django.forms.models import inlineformset_factory
from django.forms.models import inlineformset_factory, model_to_dict
from django.forms.formsets import formset_factory
from django.http import HttpResponse, Http404, HttpResponseRedirect
from django.shortcuts import render, get_object_or_404, redirect
@ -30,6 +30,7 @@ from ietf.ipr.models import (IprDisclosureStateName, IprDisclosureBase,
RelatedIpr,IprEvent)
from ietf.ipr.utils import (get_genitive, get_ipr_summary,
iprs_from_docs, related_docs)
from ietf.mailtrigger.utils import gather_address_lists
from ietf.message.models import Message
from ietf.message.utils import infer_message
from ietf.name.models import IprLicenseTypeName
@ -37,7 +38,7 @@ from ietf.person.models import Person
from ietf.secr.utils.document import get_rfc_num, is_draft
from ietf.utils.draft_search import normalize_draftname
from ietf.utils.mail import send_mail, send_mail_message
from ietf.mailtrigger.utils import gather_address_lists
from ietf.utils.text import text_to_dict
# ----------------------------------------------------------------
# Globals
@ -531,7 +532,16 @@ def new(request, type, updates=None):
else:
if updates:
form = ipr_form_mapping[type](initial={'updates':str(updates)})
original = IprDisclosureBase(id=updates).get_child()
initial = model_to_dict(original)
initial.update({'updates':str(updates), })
patent_info = text_to_dict(initial['patent_info'])
if patent_info.keys():
patent_dict = dict([ ('patent_'+k.lower(), v) for k,v in patent_info.items() ])
else:
patent_dict = {'patent_notes': initial['patent_info']}
initial.update(patent_dict)
form = ipr_form_mapping[type](initial=initial)
else:
form = ipr_form_mapping[type]()
disclosure = IprDisclosureBase() # dummy disclosure for inlineformset
@ -764,8 +774,8 @@ def show(request, id):
'in_force_ipr_rfc': ipr_rfc_number(ipr.time, ipr.is_thirdparty),
'tabs': get_details_tabs(ipr, 'Disclosure'),
'choices_abc': [ i.desc for i in IprLicenseTypeName.objects.filter(slug__in=['no-license', 'royalty-free', 'reasonable', ]) ],
'updates_iprs': ipr.relatedipr_source_set.all(),
'updated_by_iprs': ipr.relatedipr_target_set.filter(source__state="posted")
'updates_iprs': ipr.relatedipr_source_set.all().order_by('source__time'),
'updated_by_iprs': ipr.relatedipr_target_set.filter(source__state="posted").order_by('target__time')
})
def showlist(request):

View file

@ -331,7 +331,7 @@ def make_test_data():
title="Statement regarding rights",
holder_legal_name="Native Martians United",
state=IprDisclosureStateName.objects.get(slug='posted'),
patent_info='US12345',
patent_info='Number: US12345\nTitle: A method of transfering bits\nInventor: A. Nonymous\nDate: 2000-01-01',
holder_contact_name='George',
holder_contact_email='george@acme.com',
holder_contact_info='14 Main Street\nEarth',

View file

@ -140,4 +140,37 @@ def decode(raw):
text = raw.decode('latin-1')
#
return text
def text_to_dict(t):
"Converts text with RFC2822-formatted header fields into a dictionary-like object."
# ensure we're handed a unicode parameter
assert isinstance(t, six.text_type)
d = {}
# Return {} for malformed input
if not len(t.lstrip()) == len(t):
return {}
lines = t.splitlines()
items = []
# unfold folded lines
for l in lines:
if l[0].isspace():
if items:
items[-1] += l
else:
return {}
else:
items.append(l)
for i in items:
if re.match('^[A-Za-z0-9-]+: ', i):
k, v = i.split(': ', 1)
d[k] = v
else:
return {}
return d
def dict_to_text(d):
"Convert a dictionary to RFC2822-formatted text"
t = ""
for k, v in d.items():
t += "%s: %s\n" % (k, v)
return t