diff --git a/ietf/ipr/urls.py b/ietf/ipr/urls.py index f58bc0223..0fd40582b 100644 --- a/ietf/ipr/urls.py +++ b/ietf/ipr/urls.py @@ -7,7 +7,7 @@ urlpatterns = patterns('', (r'^ipr-(?P\d+)/$', views.show), (r'^update/$', views.updatelist), (r'^update/(?P\d+)/$', views.update), - (r'^new-(?P(specific|generic|thirdpty))/$', views.new), + (r'^new-(?P(specific|generic|third_party))/$', views.new), ) queryset = models.IprDetail.objects.all() diff --git a/ietf/ipr/views.py b/ietf/ipr/views.py index 55835fd89..cb2384180 100644 --- a/ietf/ipr/views.py +++ b/ietf/ipr/views.py @@ -1,6 +1,7 @@ import models from django.shortcuts import render_to_response as render import django.newforms as forms +from django.utils.html import escape, linebreaks import ietf.utils import syslog @@ -30,31 +31,60 @@ def list(request, template): 'thirdpty_disclosures': thirdpty_disclosures.order_by(* ['-submitted_date', ] ), } ) +# Details views + +section_table = { + "index": { "index": True }, + "specific": { "index": False, "title": True, + "legacy_intro": False, "new_intro": True, "form_intro": False, + "holder": True, "holder_contact": True, "ietf_contact": True, + "ietf_doc": True, "patent_info": True, "licensing": True, + "submitter": True, "notes": True, "form_submit": False, + }, + "generic": { "index": False, "title": True, + "legacy_intro": False, "new_intro": True, "form_intro": False, + "holder": True, "holder_contact": True, "ietf_contact": False, + "ietf_doc": False, "patent_info": True, "licensing": True, + "submitter": True, "notes": True, "form_submit": False, + }, + "third_party": {"index": False, "title": True, + "legacy_intro": False, "new_intro": True, "form_intro": False, + "holder": True, "holder_contact": False, "ietf_contact": True, + "ietf_doc": True, "patent_info": True, "licensing": False, + "submitter": False, "notes": False, "form_submit": False, + }, + "legacy": { "index": False, "title": True, + "legacy_intro": True, "new_intro": False, "form_intro": False, + "holder": True, "holder_contact": True, "ietf_contact": False, + "ietf_doc": True, "patent_info": False, "licensing": False, + "submitter": False, "notes": False, "form_submit": False, + }, + } + def show(request, ipr_id=None): """Show a specific IPR disclosure""" assert ipr_id != None ipr = models.IprDetail.objects.filter(ipr_id=ipr_id)[0] ipr.disclosure_type = get_disclosure_type(ipr) - try: - ipr.holder_contact = ipr.contact.filter(contact_type=1)[0] - except IndexError: - ipr.holder_contact = "" - try: - ipr.ietf_contact = ipr.contact.filter(contact_type=2)[0] - except IndexError: - ipr.ietf_contact = "" - try: - ipr.submitter = ipr.contact.filter(contact_type=3)[0] - except IndexError: - ipr.submitter = "" + section_list = get_section_list(ipr) + contacts = ipr.contact.all() + for contact in contacts: + if contact.contact_type == 1: + ipr.holder_contact = contact + elif contact.contact_type == 2: + ipr.ietf_contact = contact + elif contact.contact_type == 3: + ipr.submitter = contact + else: + raise KeyError("Unexpected contact_type in ipr_contacts: ipr_id=%s" % ipr.ipr_id) + # do escaping and line-breaking here instead of in the template, + # so that we can use the template for the form display, too. + ipr.p_notes = linebreaks(escape(ipr.p_notes)) + ipr.discloser_identify = linebreaks(escape(ipr.discloser_identify)) + ipr.comments = linebreaks(escape(ipr.comments)) + ipr.other_notes = linebreaks(escape(ipr.other_notes)) - if ipr.generic: - return render("ipr/details_generic.html", {"ipr": ipr}) - if ipr.third_party: - return render("ipr/details_thirdpty.html", {"ipr": ipr}) - else: - return render("ipr/details_specific.html", {"ipr": ipr}) - + return render("ipr/details.html", {"ipr": ipr, "section_list": section_list}) def update(request, ipr_id=None): """Update a specific IPR disclosure""" @@ -65,34 +95,55 @@ def new(request, type): """Make a new IPR disclosure""" debug = "" -# CustomForm = mk_formatting_form(format="%(errors)s%(field)s%(help_text)s") CustomForm = ietf.utils.makeFormattingForm(template="ipr/formfield.html") BaseIprForm = forms.form_for_model(models.IprDetail, form=CustomForm, formfield_callback=detail_field_fixup) - ContactForm = forms.form_for_model(models.IprContact, form=CustomForm) + BaseContactForm = forms.form_for_model(models.IprContact, form=CustomForm) + + section_list = section_table[type] + section_list.update({"title":False, "new_intro":False, "form_intro":True, "form_submit":True, }) # Some subclassing: + class MultiformWidget(forms.Widget): + def value_from_datadict(self, data, name): + return data + + class ContactForm(BaseContactForm): + widget = MultiformWidget() + + def add_prefix(self, field_name): + return self.prefix and ('%s_%s' % (self.prefix, field_name)) or field_name + def clean(self, *value): + if value: + return self.full_clean() + else: + return self.clean_data + class IprForm(BaseIprForm): holder_contact = None rfclist = forms.CharField(required=False) draftlist = forms.CharField(required=False) stdonly_license = forms.BooleanField(required=False) def __init__(self, *args, **kw): - self.base_fields["holder_contact"] = ContactForm(prefix="ph", *args, **kw) - # syslog.syslog("IprForm.__init__: holder_contact: %s" % repr(self.base_fields["holder_contact"])) - - self.base_fields["ietf_contact"] = ContactForm(prefix="ietf", *args, **kw) - self.base_fields["submitter"] = ContactForm(prefix="sub", *args, **kw) + for contact in ["holder_contact", "ietf_contact", "submitter"]: + if contact in section_list: + self.base_fields[contact] = ContactForm(prefix=contact[:4], *args, **kw) BaseIprForm.__init__(self, *args, **kw) if request.method == 'POST': form = IprForm(request.POST) if form.is_valid(): - form.save() + #instance = form.save() + #return HttpResponseRedirect("/ipr/ipr-%s" % instance.ipr_id) return HttpResponseRedirect("/ipr/") + else: + # Fall through, and let the partially bound form, with error + # indications, be rendered again. + pass else: form = IprForm() + form.unbound_form = True - return render("ipr/new_%s.html" % type, {"ipr": form, "debug": ""}) + return render("ipr/details.html", {"ipr": form, "section_list":section_list, "debug": ""}) def detail_field_fixup(field): if field.name == "licensing_option": @@ -108,7 +159,18 @@ def get_disclosure_type(ipr): if ipr.generic: assert not ipr.third_party return "Generic" - if ipr.third_party: + elif ipr.third_party: return "Third Party" else: return "Specific" + +def get_section_list(ipr): + if ipr.old_ipr_url: + return section_table["legacy"] + elif ipr.generic: + assert not ipr.third_party + return section_table["generic"] + elif ipr.third_party: + return section_table["third_party"] + else: + return section_table["specific"] diff --git a/ietf/templates/ipr/details.html b/ietf/templates/ipr/details.html index 9ea3da34d..27dc49a27 100644 --- a/ietf/templates/ipr/details.html +++ b/ietf/templates/ipr/details.html @@ -2,37 +2,10 @@ {% block title %}IPR Details{% endblock %} {% block content %} - +{% include "ipr/style.html" %} - {% block top_info %}
+ {% if section_list.title %}
@@ -41,7 +14,8 @@

- {% if ipr.old_ipr_url %} + {% endif %} + {% if section_list.legacy_intro %} This IPR disclosure was submitted by e-mail.
{% if not ipr.comply %} @@ -55,57 +29,114 @@ Additional information may be available in the original submission.
See the content of the original IPR disclosure.
- {% else %} + {% endif %} + {% if section_list.new_intro %} Only those sections of the "Patent Disclosure and Licensing Declaration Template for {{ ipr.disclosure_type }} IPR Disclosures" where the submitter provided information are displayed.
{% endif %} + {% if section_list.new_intro or section_list.legacy_intro %} + {% if ipr.additional_old_title1 %} + {{ ipr.additional_old_title1 }}
+ {% endif %} - {% if ipr.additional_old_title1 %} - {{ ipr.additional_old_title1 }}
+ {% if ipr.additional_old_title2 %} + {{ ipr.additional_old_title2 }}
+ {% endif %} + + {% for item in ipr.updates.all %} + +
+ This IPR disclosure updates IPR disclosure ID #{{ item.updated.ipr_id }}, + {% ifequal item.status_to_be 1 %} + "{{ item.updated.document_title }}". + {% else %} + "{{ item.updated.document_title }}", which was removed at the request of the submitter. + {% endifequal %} +
+
+ {% endfor %} + + {% for item in ipr.updated_by.all %} + {% ifequal item.processed 1 %} + +
+ This IPR disclosure has been updated by IPR disclosure ID #{{ item.ipr.ipr_id }}, + {% ifequal item.status_to_be 1 %} + "{{ item.ipr.document_title }}". + {% else %} + "{{ item.ipr.document_title }}", which was removed at the request of the submitter. + {% endifequal %} +
+
+ {% endifequal %} + {% endfor %} + +
+ Click here to update this IPR disclosure
+ +
+ Submitted Date: {{ ipr.submitted_date|date:"F j, Y" }} {% endif %} - {% if ipr.additional_old_title2 %} - {{ ipr.additional_old_title2 }}
+ {% if section_list.index %} +

+ The IETF takes no position regarding the validity or scope of any + intellectual property rights or other rights that might be claimed to + pertain to the implementation or use of the technology described in any IETF documents or the extent to + which any license under such rights might or might not be available; nor does it represent that it has made any independent effort to identify any such rights. +

+

+ There are 3 different IPR disclosures that can be made: +

+

+ + "Specific": A disclosure about your IPR related to a specific IETF contribution +

+

+ + "Generic": An IPR disclosure about your IPR that is not related to a specific IETF contribution +

+

+ + "Third-Party": Notify the IETF of IPR other than your own which you believe may be related to a specific IETF contribution +

+ {% endif %} + + {% if section_list.form_intro %} +

The Patent Disclosure and Licensing Declaration Template for {{ ipr.disclosure_type }} IPR Disclosures

+

+ + This document is an IETF IPR Disclosure and Licensing Declaration + Template and is submitted to inform the IETF of a) patent or patent + application information regarding the IETF document or contribution + listed in Section IV, and b) an IPR Holder's intention with respect to + the licensing of its necessary patent claims. No actual license is + implied by submission of this template. Please complete and submit a + separate template for each IETF document or contribution to which the + disclosed patent information relates. + +

+

+ + If you wish to submit your IPR disclosure by e-mail, then please send + it to ietf-ipr@ietf.org. + Submissions made by e-mail that do not comply with the formal + requirements of Section 6, "IPR Disclosures," of RFC 3979, + "Intellectual Property Rights in IETF Technology," will be posted, but + will be marked as "non-compliant." + +

+
+
{% endif %} - {% for item in ipr.updates.all %} - -
- This IPR disclosure updates IPR disclosure ID #{{ item.updated.ipr_id }}, - {% ifequal item.status_to_be 1 %} - "{{ item.updated.document_title }}". - {% else %} - "{{ item.updated.document_title }}", which was removed at the request of the submitter. - {% endifequal %} -
-
- {% endfor %} - {% for item in ipr.updated_by.all %} - {% ifequal item.processed 1 %} - -
- This IPR disclosure has been updated by IPR disclosure ID #{{ item.ipr.ipr_id }}, - {% ifequal item.status_to_be 1 %} - "{{ item.ipr.document_title }}". - {% else %} - "{{ item.ipr.document_title }}", which was removed at the request of the submitter. - {% endifequal %} -
-
- {% endifequal %} - {% endfor %} -
- Click here to update this IPR disclosure
- -
- Submitted Date: {{ ipr.submitted_date|date:"F j, Y" }}
- {% endblock %} - {% block section1 %} + {% if section_list.holder %}
@@ -122,10 +153,10 @@
- {% endblock %} + {% endif %} - {% block section2 %} + {% if section_list.holder_contact %}
- {% block section2_data %} - - + + - {% endblock %}
@@ -133,22 +164,20 @@ Patent Holder's Contact for License Application
Name: {{ ipr.holder_contact.name }}
Title: {{ ipr.holder_contact.title }}
Department: {{ ipr.holder_contact.department }}
Address1: {{ ipr.holder_contact.address1 }}
Address2: {{ ipr.holder_contact.address2 }}
Address1: {{ ipr.holder_contact.address1 }}
Address2: {{ ipr.holder_contact.address2 }}
Telephone: {{ ipr.holder_contact.telephone }}
Fax: {{ ipr.holder_contact.fax }}
Email: {{ ipr.holder_contact.email }}
- {% endblock %} + {% endif %} - {% block section3 %} + {% if section_list.ietf_contact %}
@@ -157,26 +186,24 @@ Contact Information for the IETF Participant Whose Personal Belief Triggered this Disclosure: - {% block section3_data %} - {% if not ipr.is_bound or ipr.ietf_contact.name %} + {% if ipr.ietf_contact.name %} - - + + {% else %} {% endif %} - {% endblock %}
Name: {{ ipr.ietf_contact.name }}
Title: {{ ipr.ietf_contact.title }}
Department: {{ ipr.ietf_contact.department }}
Address1: {{ ipr.ietf_contact.address1 }}
Address2: {{ ipr.ietf_contact.address2 }}
Address1: {{ ipr.ietf_contact.address1 }}
Address2: {{ ipr.ietf_contact.address2 }}
Telephone: {{ ipr.ietf_contact.telephone }}
Fax: {{ ipr.ietf_contact.fax }}
Email: {{ ipr.ietf_contact.email }}
No information submitted
- {% endblock %} + {% endif %} - {% block section4 %} + {% if section_list.ietf_doc %}
@@ -199,9 +226,9 @@ {% endblock %}
- {% endblock %} + {% endif %} - {% block section5 %} + {% if section_list.patent_info %}
@@ -211,25 +238,23 @@ applications required to be disclosed by Section 6 of RFC 3979) - {% block section5_data %} {% if ipr.p_applications or ipr.p_notes %} - - - - + + + + - {% block clause5c %} {% if ipr.discloser_identify %} - + {% else %} - + {% endif %} - {% endblock %} {% else %} {% endif %} - {% endblock %}
A. For granted patents or published pending patent applications, please provide the following information:
Patent, Serial, Publication, Registration, - or Application/File number(s):{{ ipr.p_applications }}
Date(s) granted or applied for: {{ ipr.date_applied }}
Country: {{ ipr.country }}
Additional Notes: {{ ipr.p_notes|escape|linebreaks }}
Patent, Serial, Publication, Registration, + or Application/File number(s): {{ ipr.p_applications }}
Date(s) granted or applied for: {{ ipr.date_applied }}
Country: {{ ipr.country }}
Additional Notes: {{ ipr.p_notes }}
B. Does this disclosure relate to an unpublished pending patent application?: {{ ipr.get_selecttype_display }}
C. If an Internet-Draft or RFC includes multiple parts and it is not @@ -241,21 +266,19 @@
{{ ipr.discloser_identify|escape|linebreaks }}
{{ ipr.discloser_identify }}
No information submitted
No information submitted
This disclosure relates to an unpublished pending patent application.
- {% endblock %} + {% endif %} - {% block section6 %} + {% if section_list.licensing %}
@@ -274,7 +297,6 @@ specification, is as follows(select one licensing declaration option only): - {% block section6_data %} {% if ipr.comments %} - + {% else %} {% endif %} - {% if ipr.lic_checkbox %} {% endif %} - {% endblock %}
{{ ipr.get_licensing_option_display }}
@@ -289,11 +311,10 @@
{{ ipr.comments|escape|linebreaks }}
{{ ipr.comments }}
No information submitted
@@ -304,7 +325,6 @@
Note: The individual submitting this template represents and warrants @@ -314,10 +334,10 @@
- {% endblock %} + {% endif %} - {% block section7 %} + {% if section_list.submitter %}
@@ -327,7 +347,6 @@ IETF Participant in Section III above) - {% block section7_data %} {% if ipr.submitter.name %} @@ -340,13 +359,12 @@ {% else %} {% endif %} - {% endblock %}
Name: {{ ipr.submitter.name }}
Title: {{ ipr.submitter.title }}
No information submitted
- {% endblock %} + {% endif %} - {% block section8 %} + {% if section_list.notes %}
@@ -355,19 +373,25 @@ Other Notes: - {% block section8_data %} {% if ipr.other_notes %} - + {% else %} {% endif %} - {% endblock %}
{{ ipr.other_notes|escape|linebreaks }}
{{ ipr.other_notes }}
No information submitted
- {% endblock %} + {% endif %} + + {% if section_list.form_submit %} +
+ +
+
+ IPR Disclosure Page
+ View IPR Disclosures

+
+ {% endif %} {{ debug }} - {% block bot_info %} - {% endblock %} {% endblock %} diff --git a/ietf/templates/ipr/formfield.html b/ietf/templates/ipr/formfield.html index 880868b3d..53bf13f41 100644 --- a/ietf/templates/ipr/formfield.html +++ b/ietf/templates/ipr/formfield.html @@ -1,7 +1,7 @@ {% if errors %} -
    +
      {% for error in errors %} -
    • {{ errorr }}
    • +
    • {{ error }}
    • {% endfor %}
    {% endif %} diff --git a/ietf/templates/ipr/style.html b/ietf/templates/ipr/style.html new file mode 100644 index 000000000..08da06c75 --- /dev/null +++ b/ietf/templates/ipr/style.html @@ -0,0 +1,27 @@ + diff --git a/ietf/utils.py b/ietf/utils.py index 9eb9c498e..fc0d5ab43 100644 --- a/ietf/utils.py +++ b/ietf/utils.py @@ -1,4 +1,6 @@ import operator +import syslog +from django.utils.html import escape # look at snippets 59, 148, 99 for newforms helpers # http://www.djangosnippets.org/snippets/59/ @@ -255,6 +257,7 @@ def makeFormattingForm(template=None): _template = template def __getitem__(self, name): "Returns a BoundField with the given name." + #syslog.syslog("FormattingForm.__getitem__(%s)" % (name, )) try: field = self.fields[name] except KeyError: @@ -262,5 +265,7 @@ def makeFormattingForm(template=None): if not isinstance(field, forms.fields.Field): return field bf = forms.forms.BoundField(self, field, name) - return loader.render_to_string(self._template, { "errors": bf.errors, "label": bf.label, "field": unicode(bf), "help_text": field.help_text }) + errors = [escape(error) for error in bf.errors] + rendering = loader.render_to_string(self._template, { "errors": errors, "label": bf.label, "field": unicode(bf), "help_text": field.help_text }) + return rendering return FormattingForm