Merged in branch/amsl/iprtool/5.7.4@8734 from rcross@amsl.com, providing new IPR models, refactored code, and improved list, search, and management interfaces.

- Legacy-Id: 8808
This commit is contained in:
Henrik Levkowetz 2014-12-21 19:26:33 +00:00
parent 04164ad157
commit 5183042d58
91 changed files with 6378 additions and 4244 deletions

View file

@ -8,7 +8,7 @@ from django.conf import settings
from django.core.urlresolvers import reverse as urlreverse
from ietf.utils.mail import send_mail, send_mail_text
from ietf.ipr.search import iprs_from_docs, related_docs
from ietf.ipr.utils import iprs_from_docs, related_docs
from ietf.doc.models import WriteupDocEvent, BallotPositionDocEvent, LastCallDocEvent, DocAlias, ConsensusDocEvent, DocTagName
from ietf.doc.utils import needed_ballot_positions
from ietf.person.models import Person
@ -112,9 +112,9 @@ 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(DocAlias.objects.get(name=doc.canonical_name())))
if iprs:
ipr_links = [ urlreverse("ietf.ipr.views.show", kwargs=dict(ipr_id=i.ipr_id)) for i in 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 ]
else:
ipr_links = None

View file

@ -492,10 +492,10 @@ class Document(DocumentInfo):
else:
return state.name
def ipr(self):
"""Returns the IPR disclosures against this document (as a queryset over IprDocAlias)."""
from ietf.ipr.models import IprDocAlias
return IprDocAlias.objects.filter(doc_alias__document=self)
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__document=self,disclosure__state__in=states)
def related_ipr(self):
"""Returns the IPR disclosures against this document and those documents this

View file

@ -9,6 +9,7 @@ from email.utils import parseaddr
from ietf.doc.models import ConsensusDocEvent
from django import template
from django.utils.html import escape, fix_ampersands
from django.utils.text import wrap
from django.template.defaultfilters import truncatewords_html, linebreaksbr, stringfilter, urlize
from django.template import resolve_variable
from django.utils.safestring import mark_safe, SafeData
@ -16,6 +17,9 @@ from django.utils.html import strip_tags
register = template.Library()
def collapsebr(html):
return re.sub('(<(br ?/|/p)>[ \n]*)(<(br) ?/?>[ \n]*)*(<(br|p) ?/?>[ \n]*)', '\\1\\5', html)
@register.filter(name='expand_comma')
def expand_comma(value):
"""
@ -280,7 +284,7 @@ def split(text, splitter=None):
return text.split(splitter)
@register.filter(name="wrap_long_lines")
def wrap_long_lines(text):
def wrap_long_lines(text, width=72):
"""Wraps long lines without loosing the formatting and indentation
of short lines"""
if not isinstance(text, (types.StringType,types.UnicodeType)):
@ -441,26 +445,26 @@ def ad_area(user):
return None
@register.filter
def format_history_text(text):
def format_history_text(text, trunc_words=25):
"""Run history text through some cleaning and add ellipsis if it's too long."""
full = mark_safe(text)
if text.startswith("This was part of a ballot set with:"):
full = urlize_ietf_docs(full)
return format_snippet(full)
return format_snippet(full, trunc_words)
@register.filter
def format_snippet(text):
full = mark_safe(keep_spacing(linebreaksbr(urlize(sanitize_html(text)))))
snippet = truncatewords_html(full, 25)
def format_snippet(text, trunc_words=25):
full = mark_safe(keep_spacing(collapsebr(linebreaksbr(urlize(sanitize_html(text))))))
snippet = truncatewords_html(full, trunc_words)
if snippet != full:
return mark_safe(u'<div class="snippet">%s<span class="show-all">[show all]</span></div><div style="display:none" class="full">%s</div>' % (snippet, full))
return full
@register.filter
def format_editable_snippet(text,link):
full = mark_safe(keep_spacing(linebreaksbr(urlize(sanitize_html(text)))))
full = mark_safe(keep_spacing(collapsebr(linebreaksbr(urlize(sanitize_html(text))))))
snippet = truncatewords_html(full, 25)
if snippet != full:
return mark_safe(u'<div class="snippet">%s<span class="show-all">[show all]</span></div><div style="display:none" class="full">%s' % (format_editable(snippet,link),format_editable(full,link)) )
@ -529,3 +533,33 @@ def consensus(doc):
else:
return "Unknown"
# The function and class below provides a tag version of the builtin wordwrap filter
# https://djangosnippets.org/snippets/134/
@register.tag
def wordwrap(parser, token):
"""
This is a tag version of the Django builtin 'wordwrap' filter. This is useful
if you need to wrap a combination of fixed template text and template variables.
Usage:
{% wordwrap 80 %}
some really long text here, including template variable expansion, etc.
{% endwordwrap %}
"""
try:
tag_name, len = token.split_contents()
except ValueError:
raise template.TemplateSyntaxError, "The wordwrap tag requires exactly one argument: width."
nodelist = parser.parse(('endwordwrap',))
parser.delete_first_token()
return WordWrapNode(nodelist, len)
class WordWrapNode(template.Node):
def __init__(self, nodelist, len):
self.nodelist = nodelist
self.len = len
def render(self, context):
return wrap(str(self.nodelist.render(context)), int(self.len))

View file

@ -1,28 +1,106 @@
#coding: utf-8
from django import forms
from django.contrib import admin
from ietf.ipr.models import IprContact, IprDetail, IprDocAlias, IprNotification, IprUpdate
class IprContactAdmin(admin.ModelAdmin):
list_display=('__str__', 'ipr')
admin.site.register(IprContact, IprContactAdmin)
from ietf.name.models import DocRelationshipName
from ietf.ipr.models import (IprNotification, IprDisclosureBase, IprDocRel, IprEvent,
RelatedIpr, HolderIprDisclosure, ThirdPartyIprDisclosure, GenericIprDisclosure,
NonDocSpecificIprDisclosure)
class IprDetailAdmin(admin.ModelAdmin):
list_display = ['title', 'submitted_date', 'docs', 'status']
# ------------------------------------------------------
# ModelAdmins
# ------------------------------------------------------
class IprDocRelAdminForm(forms.ModelForm):
class Meta:
model = IprDocRel
widgets = {
'sections':forms.TextInput,
}
class IprDocRelInline(admin.TabularInline):
model = IprDocRel
form = IprDocRelAdminForm
raw_id_fields = ['document']
extra = 1
class RelatedIprInline(admin.TabularInline):
model = RelatedIpr
raw_id_fields = ['target']
fk_name = 'source'
extra = 1
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "relationship":
kwargs["queryset"] = DocRelationshipName.objects.filter(slug='updates')
return super(RelatedIprInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
class IprDisclosureBaseAdmin(admin.ModelAdmin):
list_display = ['title', 'time', 'related_docs', 'state']
search_fields = ['title', 'legal_name']
raw_id_fields = ['by']
inlines = [IprDocRelInline,RelatedIprInline]
def related_docs(self, obj):
return u", ".join(a.formatted_name() for a in IprDocRel.objects.filter(disclosure=obj).order_by("id").select_related("document"))
def docs(self, ipr):
return u", ".join(a.formatted_name() for a in IprDocAlias.objects.filter(ipr=ipr).order_by("id").select_related("doc_alias"))
admin.site.register(IprDisclosureBase, IprDisclosureBaseAdmin)
admin.site.register(IprDetail, IprDetailAdmin)
class HolderIprDisclosureAdmin(admin.ModelAdmin):
list_display = ['title', 'time', 'related_docs', 'state']
raw_id_fields = ["by"]
inlines = [IprDocRelInline,RelatedIprInline]
def related_docs(self, obj):
return u", ".join(a.formatted_name() for a in IprDocRel.objects.filter(disclosure=obj).order_by("id").select_related("document"))
admin.site.register(HolderIprDisclosure, HolderIprDisclosureAdmin)
class ThirdPartyIprDisclosureAdmin(admin.ModelAdmin):
list_display = ['title', 'time', 'related_docs', 'state']
raw_id_fields = ["by"]
inlines = [IprDocRelInline,RelatedIprInline]
def related_docs(self, obj):
return u", ".join(a.formatted_name() for a in IprDocRel.objects.filter(disclosure=obj).order_by("id").select_related("document"))
admin.site.register(ThirdPartyIprDisclosure, ThirdPartyIprDisclosureAdmin)
class GenericIprDisclosureAdmin(admin.ModelAdmin):
list_display = ['title', 'time', 'related_docs', 'state']
raw_id_fields = ["by"]
inlines = [RelatedIprInline]
def related_docs(self, obj):
return u", ".join(a.formatted_name() for a in IprDocRel.objects.filter(disclosure=obj).order_by("id").select_related("document"))
admin.site.register(GenericIprDisclosure, GenericIprDisclosureAdmin)
class NonDocSpecificIprDisclosureAdmin(admin.ModelAdmin):
list_display = ['title', 'time', 'related_docs', 'state']
raw_id_fields = ["by"]
inlines = [RelatedIprInline]
def related_docs(self, obj):
return u", ".join(a.formatted_name() for a in IprDocRel.objects.filter(disclosure=obj).order_by("id").select_related("document"))
admin.site.register(NonDocSpecificIprDisclosure, NonDocSpecificIprDisclosureAdmin)
class IprNotificationAdmin(admin.ModelAdmin):
pass
admin.site.register(IprNotification, IprNotificationAdmin)
class IprUpdateAdmin(admin.ModelAdmin):
pass
admin.site.register(IprUpdate, IprUpdateAdmin)
class IprDocRelAdmin(admin.ModelAdmin):
raw_id_fields = ["disclosure", "document"]
admin.site.register(IprDocRel, IprDocRelAdmin)
class IprDocAliasAdmin(admin.ModelAdmin):
raw_id_fields = ["ipr", "doc_alias"]
admin.site.register(IprDocAlias, IprDocAliasAdmin)
class RelatedIprAdmin(admin.ModelAdmin):
list_display = ['source', 'target', 'relationship', ]
search_fields = ['source__name', 'target__name', 'target__document__name', ]
raw_id_fields = ['source', 'target', ]
admin.site.register(RelatedIpr, RelatedIprAdmin)
class IprEventAdmin(admin.ModelAdmin):
list_display = ["disclosure", "type", "by", "time"]
list_filter = ["time", "type"]
search_fields = ["disclosure__title", "by__name"]
raw_id_fields = ["disclosure", "by", "message", "in_reply_to"]
admin.site.register(IprEvent, IprEventAdmin)

View file

@ -1,13 +1,11 @@
# Copyright The IETF Trust 2007, All Rights Reserved
import datetime
from django.contrib.syndication.views import Feed
from django.utils.feedgenerator import Atom1Feed
from django.core.urlresolvers import reverse_lazy
from django.utils.safestring import mark_safe
from ietf.ipr.models import IprDetail
from ietf.ipr.models import IprDisclosureBase
class LatestIprDisclosuresFeed(Feed):
feed_type = Atom1Feed
@ -18,7 +16,7 @@ class LatestIprDisclosuresFeed(Feed):
feed_url = "/feed/ipr/"
def items(self):
return IprDetail.objects.filter(status__in=[1,3]).order_by('-submitted_date')[:30]
return IprDisclosureBase.objects.filter(state__in=('posted','removed')).order_by('-time')[:30]
def item_title(self, item):
return mark_safe(item.title)
@ -27,18 +25,16 @@ class LatestIprDisclosuresFeed(Feed):
return unicode(item.title)
def item_pubdate(self, item):
# this method needs to return a datetime instance, even
# though the database has only date, not time
return datetime.datetime.combine(item.submitted_date, datetime.time(0,0,0))
return item.time
def item_author_name(self, item):
s = item.get_submitter()
if s:
return s.name
return None
if item.by:
return item.by.name
else:
return None
def item_author_email(self, item):
s = item.get_submitter()
if s:
return s.email
return None
if item.by:
return item.by.email_address()
else:
return None

157
ietf/ipr/fields.py Normal file
View file

@ -0,0 +1,157 @@
import json
from django.utils.html import escape
from django import forms
from django.core.urlresolvers import reverse as urlreverse
import debug # pyflakes:ignore
from ietf.doc.models import DocAlias
from ietf.ipr.models import IprDisclosureBase
def tokeninput_id_name_json(objs):
"""Returns objects as JSON string.
NOTE: double quotes in the object name are replaced with single quotes to avoid
problems with representation of the JSON string in the HTML widget attribute"""
def format_ipr(x):
text = x.title.replace('"',"'")
return escape(u"%s <%s>" % (text, x.time.date().isoformat()))
def format_doc(x):
return escape(x.name)
formatter = format_ipr if objs and isinstance(objs[0], IprDisclosureBase) else format_doc
return json.dumps([{ "id": o.pk, "name": formatter(o) } for o in objs])
class AutocompletedIprDisclosuresField(forms.CharField):
"""Tokenizing autocompleted multi-select field for choosing
IPR disclosures using jquery.tokeninput.js.
The field uses a comma-separated list of primary keys in a
CharField element as its API, the tokeninput Javascript adds some
selection magic on top of this so we have to pass it a JSON
representation of ids and user-understandable labels."""
def __init__(self,
max_entries=None, # max number of selected objs
model=IprDisclosureBase,
hint_text="Type in term(s) to search disclosure title",
*args, **kwargs):
kwargs["max_length"] = 1000
self.max_entries = max_entries
self.model = model
super(AutocompletedIprDisclosuresField, self).__init__(*args, **kwargs)
self.widget.attrs["class"] = "tokenized-field"
self.widget.attrs["data-hint-text"] = hint_text
if self.max_entries != None:
self.widget.attrs["data-max-entries"] = self.max_entries
def parse_tokenized_value(self, value):
return [x.strip() for x in value.split(",") if x.strip()]
def prepare_value(self, value):
if not value:
value = ""
if isinstance(value, basestring):
pks = self.parse_tokenized_value(value)
value = self.model.objects.filter(pk__in=pks)
if isinstance(value, self.model):
value = [value]
self.widget.attrs["data-pre"] = tokeninput_id_name_json(value)
# doing this in the constructor is difficult because the URL
# patterns may not have been fully constructed there yet
self.widget.attrs["data-ajax-url"] = urlreverse("ipr_ajax_search")
return ",".join(str(e.pk) for e in value)
def clean(self, value):
value = super(AutocompletedIprDisclosuresField, self).clean(value)
pks = self.parse_tokenized_value(value)
objs = self.model.objects.filter(pk__in=pks)
found_pks = [str(o.pk) for o in objs]
failed_pks = [x for x in pks if x not in found_pks]
if failed_pks:
raise forms.ValidationError(u"Could not recognize the following {model_name}s: {pks}. You can only input {model_name}s already registered in the Datatracker.".format(pks=", ".join(failed_pks), model_name=self.model.__name__.lower()))
if self.max_entries != None and len(objs) > self.max_entries:
raise forms.ValidationError(u"You can select at most %s entries only." % self.max_entries)
return objs
class AutocompletedDraftsField(AutocompletedIprDisclosuresField):
"""Version of AutocompletedPersonsField with the defaults right for Drafts."""
def __init__(self, model=DocAlias, hint_text="Type in name to search draft name",
*args, **kwargs):
super(AutocompletedDraftsField, self).__init__(model=model, hint_text=hint_text, *args, **kwargs)
def prepare_value(self, value):
if not value:
value = ""
if isinstance(value, basestring):
pks = self.parse_tokenized_value(value)
value = self.model.objects.filter(pk__in=pks)
if isinstance(value, self.model):
value = [value]
if isinstance(value, long):
value = self.model.objects.filter(pk=value)
self.widget.attrs["data-pre"] = tokeninput_id_name_json(value)
# doing this in the constructor is difficult because the URL
# patterns may not have been fully constructed there yet
self.widget.attrs["data-ajax-url"] = urlreverse("ipr_ajax_draft_search")
return ",".join(str(e.pk) for e in value)
class AutocompletedDraftField(AutocompletedDraftsField):
"""Version of AutocompletedEmailsField specialized to a single object."""
def __init__(self, *args, **kwargs):
kwargs["max_entries"] = 1
super(AutocompletedDraftField, self).__init__(*args, **kwargs)
def clean(self, value):
return super(AutocompletedDraftField, self).clean(value).first()
class AutocompletedRfcsField(AutocompletedIprDisclosuresField):
"""Version of AutocompletedPersonsField with the defaults right for Drafts."""
def __init__(self, model=DocAlias, hint_text="Type in the RFC number",
*args, **kwargs):
super(AutocompletedRfcsField, self).__init__(model=model, hint_text=hint_text, *args, **kwargs)
def prepare_value(self, value):
if not value:
value = ""
if isinstance(value, basestring):
pks = self.parse_tokenized_value(value)
value = self.model.objects.filter(pk__in=pks)
if isinstance(value, self.model):
value = [value]
if isinstance(value, long):
value = self.model.objects.filter(pk=value)
self.widget.attrs["data-pre"] = tokeninput_id_name_json(value)
# doing this in the constructor is difficult because the URL
# patterns may not have been fully constructed there yet
self.widget.attrs["data-ajax-url"] = urlreverse("ipr_ajax_rfc_search")
return ",".join(str(e.pk) for e in value)
class AutocompletedRfcField(AutocompletedRfcsField):
"""Version of AutocompletedEmailsField specialized to a single object."""
def __init__(self, *args, **kwargs):
kwargs["max_entries"] = 1
super(AutocompletedRfcField, self).__init__(*args, **kwargs)
def clean(self, value):
return super(AutocompletedRfcField, self).clean(value).first()

281
ietf/ipr/forms.py Normal file
View file

@ -0,0 +1,281 @@
import datetime
import email
from django import forms
from ietf.group.models import Group
from ietf.ipr.mail import utc_from_string
from ietf.ipr.fields import (AutocompletedIprDisclosuresField, AutocompletedDraftField,
AutocompletedRfcField)
from ietf.ipr.models import (IprDocRel, IprDisclosureBase, HolderIprDisclosure,
GenericIprDisclosure, ThirdPartyIprDisclosure, NonDocSpecificIprDisclosure,
IprLicenseTypeName, IprDisclosureStateName)
from ietf.message.models import Message
# ----------------------------------------------------------------
# Globals
# ----------------------------------------------------------------
STATE_CHOICES = [ (x.slug, x.name) for x in IprDisclosureStateName.objects.all() ]
STATE_CHOICES.insert(0,('all','All States'))
# ----------------------------------------------------------------
# Base Classes
# ----------------------------------------------------------------
class CustomModelChoiceField(forms.ModelChoiceField):
def label_from_instance(self, obj):
return obj.desc
class GroupModelChoiceField(forms.ModelChoiceField):
'''Custom ModelChoiceField that displays group acronyms as choices.'''
def label_from_instance(self, obj):
return obj.acronym
class MessageModelChoiceField(forms.ModelChoiceField):
'''Custom ModelChoiceField that displays messages.'''
def label_from_instance(self, obj):
date = obj.time.strftime("%Y-%m-%d")
if len(obj.subject) > 45:
subject = obj.subject[:43] + '....'
else:
subject = obj.subject
return '{} - {}'.format(date,subject)
# ----------------------------------------------------------------
# Forms
# ----------------------------------------------------------------
class AddCommentForm(forms.Form):
private = forms.BooleanField(required=False,help_text="If this box is checked the comment will not appear in the disclosure's public history view.")
comment = forms.CharField(required=True, widget=forms.Textarea)
class AddEmailForm(forms.Form):
direction = forms.ChoiceField(choices=(("incoming", "Incoming"), ("outgoing", "Outgoing")),
widget=forms.RadioSelect)
in_reply_to = MessageModelChoiceField(queryset=Message.objects,label="In Reply To",required=False)
message = forms.CharField(required=True, widget=forms.Textarea)
def __init__(self, *args, **kwargs):
self.ipr = kwargs.pop('ipr', None)
super(AddEmailForm, self).__init__(*args, **kwargs)
if self.ipr:
self.fields['in_reply_to'].queryset = Message.objects.filter(msgevents__disclosure__id=self.ipr.pk)
def clean_message(self):
'''Returns a ietf.message.models.Message object'''
text = self.cleaned_data['message']
message = email.message_from_string(text)
for field in ('to','from','subject','date'):
if not message[field]:
raise forms.ValidationError('Error parsing email: {} field not found.'.format(field))
date = utc_from_string(message['date'])
if not isinstance(date,datetime.datetime):
raise forms.ValidationError('Error parsing email date field')
return message
def clean(self):
if any(self.errors):
return self.cleaned_data
super(AddEmailForm, self).clean()
in_reply_to = self.cleaned_data['in_reply_to']
message = self.cleaned_data['message']
direction = self.cleaned_data['direction']
if in_reply_to:
if direction != 'incoming':
raise forms.ValidationError('Only incoming messages can have In Reply To selected')
date = utc_from_string(message['date'])
if date < in_reply_to.time:
raise forms.ValidationError('The incoming message must have a date later than the message it is replying to')
return self.cleaned_data
class DraftForm(forms.ModelForm):
document = AutocompletedDraftField(required=False)
class Meta:
model = IprDocRel
widgets = {
'sections': forms.TextInput(),
}
help_texts = { 'sections': 'Sections' }
class GenericDisclosureForm(forms.Form):
"""Custom ModelForm-like form to use for new Generic or NonDocSpecific Iprs.
If patent_info is submitted create a NonDocSpecificIprDisclosure object
otherwise create a GenericIprDisclosure object."""
compliant = forms.BooleanField(required=False)
holder_legal_name = forms.CharField(max_length=255)
notes = forms.CharField(max_length=255,widget=forms.Textarea,required=False)
other_designations = forms.CharField(max_length=255,required=False)
holder_contact_name = forms.CharField(max_length=255)
holder_contact_email = forms.EmailField()
holder_contact_info = forms.CharField(max_length=255,widget=forms.Textarea,required=False)
submitter_name = forms.CharField(max_length=255,required=False)
submitter_email = forms.EmailField(required=False)
patent_info = forms.CharField(max_length=255,widget=forms.Textarea,required=False)
has_patent_pending = forms.BooleanField(required=False)
statement = forms.CharField(max_length=255,widget=forms.Textarea,required=False)
updates = AutocompletedIprDisclosuresField(required=False)
same_as_ii_above = forms.BooleanField(required=False)
def __init__(self,*args,**kwargs):
super(GenericDisclosureForm, self).__init__(*args,**kwargs)
self.fields['compliant'].initial = True
def clean(self):
super(GenericDisclosureForm, self).clean()
cleaned_data = self.cleaned_data
# if same_as_above not checked require submitted
if not self.cleaned_data.get('same_as_ii_above'):
if not ( self.cleaned_data.get('submitter_name') and self.cleaned_data.get('submitter_email') ):
raise forms.ValidationError('Submitter information must be provided in section VII')
return cleaned_data
def save(self, *args, **kwargs):
nargs = self.cleaned_data.copy()
same_as_ii_above = nargs.get('same_as_ii_above')
del nargs['same_as_ii_above']
if self.cleaned_data.get('patent_info'):
obj = NonDocSpecificIprDisclosure(**nargs)
else:
del nargs['patent_info']
del nargs['has_patent_pending']
obj = GenericIprDisclosure(**nargs)
if same_as_ii_above == True:
obj.submitter_name = obj.holder_contact_name
obj.submitter_email = obj.holder_contact_email
if kwargs.get('commit',True):
obj.save()
return obj
class IprDisclosureFormBase(forms.ModelForm):
"""Base form for Holder and ThirdParty disclosures"""
updates = AutocompletedIprDisclosuresField(required=False)
same_as_ii_above = forms.BooleanField(required=False)
def __init__(self,*args,**kwargs):
super(IprDisclosureFormBase, self).__init__(*args,**kwargs)
self.fields['submitter_name'].required = False
self.fields['submitter_email'].required = False
self.fields['compliant'].initial = True
class Meta:
"""This will be overridden"""
model = IprDisclosureBase
def clean(self):
super(IprDisclosureFormBase, self).clean()
cleaned_data = self.cleaned_data
# if same_as_above not checked require submitted
if not self.cleaned_data.get('same_as_ii_above'):
if not ( self.cleaned_data.get('submitter_name') and self.cleaned_data.get('submitter_email') ):
raise forms.ValidationError('Submitter information must be provided in section VII')
return cleaned_data
class HolderIprDisclosureForm(IprDisclosureFormBase):
licensing = CustomModelChoiceField(IprLicenseTypeName.objects.all(),
widget=forms.RadioSelect,empty_label=None)
class Meta:
model = HolderIprDisclosure
exclude = [ 'by','docs','state','rel' ]
def __init__(self, *args, **kwargs):
super(HolderIprDisclosureForm, self).__init__(*args, **kwargs)
if not self.instance.pk:
self.fields['licensing'].queryset = IprLicenseTypeName.objects.exclude(slug='none-selected')
def clean(self):
super(HolderIprDisclosureForm, self).clean()
cleaned_data = self.cleaned_data
if not self.data.get('draft-0-document') and not self.data.get('rfc-0-document') and not cleaned_data.get('other_designations'):
raise forms.ValidationError('You need to specify a contribution in Section IV')
return cleaned_data
def save(self, *args, **kwargs):
obj = super(IprDisclosureFormBase, self).save(*args,commit=False)
if self.cleaned_data.get('same_as_ii_above') == True:
obj.submitter_name = obj.holder_contact_name
obj.submitter_email = obj.holder_contact_email
if kwargs.get('commit',True):
obj.save()
return obj
class GenericIprDisclosureForm(IprDisclosureFormBase):
"""Use for editing a GenericIprDisclosure"""
class Meta:
model = GenericIprDisclosure
exclude = [ 'by','docs','state','rel' ]
class MessageModelForm(forms.ModelForm):
response_due = forms.DateField(required=False,help_text='The date which a response is due')
class Meta:
model = Message
fields = ['to','frm','cc','bcc','reply_to','subject','body']
exclude = ['time','by','content_type','related_groups','related_docs']
def __init__(self, *args, **kwargs):
super(MessageModelForm, self).__init__(*args, **kwargs)
self.fields['frm'].label='From'
self.fields['frm'].widget.attrs['readonly'] = True
self.fields['reply_to'].widget.attrs['readonly'] = True
class NonDocSpecificIprDisclosureForm(IprDisclosureFormBase):
class Meta:
model = NonDocSpecificIprDisclosure
exclude = [ 'by','docs','state','rel' ]
class NotifyForm(forms.Form):
type = forms.CharField(widget=forms.HiddenInput)
text = forms.CharField(widget=forms.Textarea)
class RfcForm(DraftForm):
document = AutocompletedRfcField(required=False)
class Meta(DraftForm.Meta):
exclude = ('revisions',)
class ThirdPartyIprDisclosureForm(IprDisclosureFormBase):
class Meta:
model = ThirdPartyIprDisclosure
exclude = [ 'by','docs','state','rel' ]
def clean(self):
super(ThirdPartyIprDisclosureForm, self).clean()
cleaned_data = self.cleaned_data
if not self.data.get('draft-0-document') and not self.data.get('rfc-0-document') and not cleaned_data.get('other_designations'):
raise forms.ValidationError('You need to specify a contribution in Section III')
return cleaned_data
def save(self, *args, **kwargs):
obj = super(ThirdPartyIprDisclosureForm, self).save(*args,commit=False)
if self.cleaned_data.get('same_as_ii_above') == True:
obj.submitter_name = obj.ietfer_name
obj.submitter_email = obj.ietfer_contact_email
if kwargs.get('commit',True):
obj.save()
return obj
class SearchForm(forms.Form):
state = forms.MultipleChoiceField(choices=STATE_CHOICES,widget=forms.CheckboxSelectMultiple,required=False)
draft = forms.CharField(max_length=128,required=False)
rfc = forms.IntegerField(required=False)
holder = forms.CharField(max_length=128,required=False)
patent = forms.CharField(max_length=128,required=False)
group = GroupModelChoiceField(label="Working group name",queryset=Group.objects.filter(type='wg').order_by('acronym'),required=False)
doctitle = forms.CharField(max_length=128,required=False)
iprtitle = forms.CharField(max_length=128,required=False)
class StateForm(forms.Form):
state = forms.ModelChoiceField(queryset=IprDisclosureStateName.objects,label="New State",empty_label=None)
private = forms.BooleanField(required=False,help_text="If this box is checked the comment will not appear in the disclosure's public history view.")
comment = forms.CharField(required=False, widget=forms.Textarea)

195
ietf/ipr/mail.py Normal file
View file

@ -0,0 +1,195 @@
import base64
import email
import datetime
from dateutil.tz import tzoffset
import os
import pytz
import re
from django.conf import settings
from django.template.loader import render_to_string
from ietf.ipr.models import IprEvent
from ietf.message.models import Message
from ietf.person.models import Person
from ietf.utils.log import log
# ----------------------------------------------------------------
# Date Functions
# ----------------------------------------------------------------
def get_body(msg):
"""Returns the body of the message. A Basic routine to walk parts of a MIME message
concatenating text/plain parts"""
body = ''
for part in msg.walk():
if part.get_content_type() == 'text/plain':
body = body + part.get_payload() + '\n'
return body
def is_aware(date):
"""Returns True if the date object passed in timezone aware, False if naive.
See http://docs.python.org/2/library/datetime.html section 8.1.1
"""
if not isinstance(date,datetime.datetime):
return False
if date.tzinfo and date.tzinfo.utcoffset(date) is not None:
return True
return False
def parsedate_to_datetime(date):
"""Returns a datetime object from string. May return naive or aware datetime.
This function is from email standard library v3.3, converted to 2.x
http://python.readthedocs.org/en/latest/library/email.util.html
"""
try:
tuple = email.utils.parsedate_tz(date)
if not tuple:
return None
tz = tuple[-1]
if tz is None:
return datetime.datetime(*tuple[:6])
return datetime.datetime(*tuple[:6],tzinfo=tzoffset(None,tz))
except ValueError:
return None
def utc_from_string(s):
date = parsedate_to_datetime(s)
if is_aware(date):
return date.astimezone(pytz.utc).replace(tzinfo=None)
else:
return date
# ----------------------------------------------------------------
# Email Functions
# ----------------------------------------------------------------
def get_holders(ipr):
"""Recursive function to follow chain of disclosure updates and return holder emails"""
items = []
for x in [ y.target.get_child() for y in ipr.updates]:
items.extend(get_holders(x))
return ([ipr.holder_contact_email] if hasattr(ipr,'holder_contact_email') else []) + items
def get_pseudo_submitter(ipr):
"""Returns a tuple (name, email) contact for this disclosure. Order of preference
is submitter, ietfer, holder (per legacy app)"""
name = 'UNKNOWN NAME - NEED ASSISTANCE HERE'
email = 'UNKNOWN EMAIL - NEED ASSISTANCE HERE'
if ipr.submitter_email:
name = ipr.submitter_name
email = ipr.submitter_email
elif hasattr(ipr, 'ietfer_contact_email') and ipr.ietfer_contact_email:
name = ipr.ietfer_name
email = ipr.ietfer_contact_email
elif hasattr(ipr, 'holder_contact_email') and ipr.holder_contact_email:
name = ipr.holder_contact_name
email = ipr.holder_contact_email
return (name,email)
def get_reply_to():
"""Returns a new reply-to address for use with an outgoing message. This is an
address with "plus addressing" using a random string. Guaranteed to be unique"""
local,domain = settings.IPR_EMAIL_TO.split('@')
while True:
rand = base64.urlsafe_b64encode(os.urandom(12))
address = "{}+{}@{}".format(local,rand,domain)
q = Message.objects.filter(reply_to=address)
if not q:
break
return address
def get_update_cc_addrs(ipr):
"""Returns list (as a string) of email addresses to use in CC: for an IPR update.
Logic is from legacy tool. Append submitter or ietfer email of first-order updated
IPR, append holder of updated IPR, follow chain of updates, appending holder emails
"""
emails = []
if not ipr.updates:
return ''
for rel in ipr.updates:
if rel.target.submitter_email:
emails.append(rel.target.submitter_email)
elif hasattr(rel.target,'ietfer_email') and rel.target.ietfer_email:
emails.append(rel.target.ietfer_email)
emails = emails + get_holders(ipr)
return ','.join(list(set(emails)))
def get_update_submitter_emails(ipr):
"""Returns list of messages, as flat strings, to submitters of IPR(s) being
updated"""
messages = []
email_to_iprs = {}
email_to_name = {}
for related in ipr.updates:
name, email = get_pseudo_submitter(related.target)
email_to_name[email] = name
if email in email_to_iprs:
email_to_iprs[email].append(related.target)
else:
email_to_iprs[email] = [related.target]
for email in email_to_iprs:
context = dict(
to_email=email,
to_name=email_to_name[email],
iprs=email_to_iprs[email],
new_ipr=ipr,
reply_to=get_reply_to())
text = render_to_string('ipr/update_submitter_email.txt',context)
messages.append(text)
return messages
def message_from_message(message,by=None):
"""Returns a ietf.message.models.Message. msg=email.Message"""
if not by:
by = Person.objects.get(name="(System)")
msg = Message.objects.create(
by = by,
subject = message.get('subject',''),
frm = message.get('from',''),
to = message.get('to',''),
cc = message.get('cc',''),
bcc = message.get('bcc',''),
reply_to = message.get('reply_to',''),
body = get_body(message),
time = utc_from_string(message['date'])
)
return msg
def process_response_email(msg):
"""Saves an incoming message. msg=string. Message "To" field is expected to
be in the format ietf-ipr+[identifier]@ietf.org. Expect to find a message with
a matching value in the reply_to field, associated to an IPR disclosure through
IprEvent. Create a Message object for the incoming message and associate it to
the original message via new IprEvent"""
message = email.message_from_string(msg)
to = message.get('To')
# exit if this isn't a response we're interested in (with plus addressing)
local,domain = settings.IPR_EMAIL_TO.split('@')
if not re.match(r'^{}\+[a-zA-Z0-9_\-]{}@{}'.format(local,'{16}',domain),to):
return None
try:
to_message = Message.objects.get(reply_to=to)
except Message.DoesNotExist:
log('Error finding matching message ({})'.format(to))
return None
try:
disclosure = to_message.msgevents.first().disclosure
except:
log('Error processing message ({})'.format(to))
return None
ietf_message = message_from_message(message)
IprEvent.objects.create(
type_id = 'msgin',
by = Person.objects.get(name="(System)"),
disclosure = disclosure,
message = ietf_message,
in_reply_to = to_message
)
return ietf_message

View file

@ -0,0 +1,29 @@
import sys
from optparse import make_option
from django.core.management.base import BaseCommand, CommandError
from ietf.utils.log import log
from ietf.ipr.mail import process_response_email
import debug # pyflakes:ignore
class Command(BaseCommand):
help = (u"Process incoming email responses to ipr mail")
option_list = BaseCommand.option_list + (
make_option('--email-file', dest='email', help='File containing email (default: stdin)'),)
def handle(self, *args, **options):
email = options.get('email', None)
msg = None
if not email:
msg = sys.stdin.read()
else:
msg = open(email, "r").read()
try:
message = process_response_email(msg)
log(u"Received IPR email from %s" % message.frm)
except ValueError as e:
raise CommandError(e)

View file

@ -0,0 +1,269 @@
# -*- coding: utf-8 -*-
from south.v2 import SchemaMigration
class Migration(SchemaMigration):
def forwards(self, orm):
pass
def backwards(self, orm):
pass
models = {
u'auth.group': {
'Meta': {'object_name': 'Group'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
u'auth.permission': {
'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
u'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
},
u'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
u'doc.docalias': {
'Meta': {'object_name': 'DocAlias'},
'document': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['doc.Document']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'})
},
u'doc.document': {
'Meta': {'object_name': 'Document'},
'abstract': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'ad': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'ad_document_set'", 'null': 'True', 'to': u"orm['person.Person']"}),
'authors': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['person.Email']", 'symmetrical': 'False', 'through': u"orm['doc.DocumentAuthor']", 'blank': 'True'}),
'expires': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'external_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
'group': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['group.Group']", 'null': 'True', 'blank': 'True'}),
'intended_std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['name.IntendedStdLevelName']", 'null': 'True', 'blank': 'True'}),
'internal_comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'primary_key': 'True'}),
'note': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'notify': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '1', 'blank': 'True'}),
'pages': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'rev': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}),
'shepherd': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'shepherd_document_set'", 'null': 'True', 'to': u"orm['person.Email']"}),
'states': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}),
'std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['name.StdLevelName']", 'null': 'True', 'blank': 'True'}),
'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['name.StreamName']", 'null': 'True', 'blank': 'True'}),
'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['name.DocTagName']", 'null': 'True', 'blank': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['name.DocTypeName']", 'null': 'True', 'blank': 'True'})
},
u'doc.documentauthor': {
'Meta': {'ordering': "['document', 'order']", 'object_name': 'DocumentAuthor'},
'author': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['person.Email']"}),
'document': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['doc.Document']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '1'})
},
u'doc.state': {
'Meta': {'ordering': "['type', 'order']", 'object_name': 'State'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'next_states': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'previous_states'", 'blank': 'True', 'to': u"orm['doc.State']"}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['doc.StateType']"}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'doc.statetype': {
'Meta': {'object_name': 'StateType'},
'label': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '30', 'primary_key': 'True'})
},
u'group.group': {
'Meta': {'object_name': 'Group'},
'acronym': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '40'}),
'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['person.Person']", 'null': 'True', 'blank': 'True'}),
'charter': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'related_name': "'chartered_group'", 'unique': 'True', 'null': 'True', 'to': u"orm['doc.Document']"}),
'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'list_archive': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'list_email': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
'list_subscribe': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
'parent': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['group.Group']", 'null': 'True', 'blank': 'True'}),
'state': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['name.GroupStateName']", 'null': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['name.GroupTypeName']", 'null': 'True'}),
'unused_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}),
'unused_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['name.DocTagName']", 'symmetrical': 'False', 'blank': 'True'})
},
u'ipr.iprcontact': {
'Meta': {'object_name': 'IprContact'},
'address1': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'address2': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'contact_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'contact_type': ('django.db.models.fields.IntegerField', [], {}),
'department': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '255'}),
'fax': ('django.db.models.fields.CharField', [], {'max_length': '25', 'blank': 'True'}),
'ipr': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'contact'", 'to': u"orm['ipr.IprDetail']"}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'telephone': ('django.db.models.fields.CharField', [], {'max_length': '25', 'blank': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'})
},
u'ipr.iprdetail': {
'Meta': {'object_name': 'IprDetail'},
'applies_to_all': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'db_column': "'selectowned'", 'blank': 'True'}),
'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'comply': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'country': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'date_applied': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'document_sections': ('django.db.models.fields.TextField', [], {'max_length': '255', 'db_column': "'disclouser_identify'", 'blank': 'True'}),
'generic': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'id_document_tag': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'ipr_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_pending': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'db_column': "'selecttype'", 'blank': 'True'}),
'legacy_title_1': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_column': "'additional_old_title1'", 'blank': 'True'}),
'legacy_title_2': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_column': "'additional_old_title2'", 'blank': 'True'}),
'legacy_url_0': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_column': "'old_ipr_url'", 'blank': 'True'}),
'legacy_url_1': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_column': "'additional_old_url1'", 'blank': 'True'}),
'legacy_url_2': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_column': "'additional_old_url2'", 'blank': 'True'}),
'legal_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'p_h_legal_name'"}),
'lic_checkbox': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'lic_opt_a_sub': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
'lic_opt_b_sub': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
'lic_opt_c_sub': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
'licensing_option': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'notes': ('django.db.models.fields.TextField', [], {'db_column': "'p_notes'", 'blank': 'True'}),
'other_designations': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'other_notes': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'patents': ('django.db.models.fields.TextField', [], {'max_length': '255', 'db_column': "'p_applications'"}),
'rfc_number': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'status': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'submitted_date': ('django.db.models.fields.DateField', [], {'blank': 'True'}),
'third_party': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'document_title'", 'blank': 'True'}),
'update_notified_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'})
},
u'ipr.iprdocalias': {
'Meta': {'object_name': 'IprDocAlias'},
'doc_alias': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['doc.DocAlias']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'ipr': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['ipr.IprDetail']"}),
'rev': ('django.db.models.fields.CharField', [], {'max_length': '2', 'blank': 'True'})
},
u'ipr.iprnotification': {
'Meta': {'object_name': 'IprNotification'},
'date_sent': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'ipr': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['ipr.IprDetail']"}),
'notification': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'time_sent': ('django.db.models.fields.CharField', [], {'max_length': '25', 'blank': 'True'})
},
u'ipr.iprupdate': {
'Meta': {'object_name': 'IprUpdate'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'ipr': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'updates'", 'to': u"orm['ipr.IprDetail']"}),
'processed': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'status_to_be': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'updated': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'updated_by'", 'db_column': "'updated'", 'to': u"orm['ipr.IprDetail']"})
},
u'name.doctagname': {
'Meta': {'ordering': "['order']", 'object_name': 'DocTagName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.doctypename': {
'Meta': {'ordering': "['order']", 'object_name': 'DocTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.groupstatename': {
'Meta': {'ordering': "['order']", 'object_name': 'GroupStateName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.grouptypename': {
'Meta': {'ordering': "['order']", 'object_name': 'GroupTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.intendedstdlevelname': {
'Meta': {'ordering': "['order']", 'object_name': 'IntendedStdLevelName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.stdlevelname': {
'Meta': {'ordering': "['order']", 'object_name': 'StdLevelName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.streamname': {
'Meta': {'ordering': "['order']", 'object_name': 'StreamName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'person.email': {
'Meta': {'object_name': 'Email'},
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'address': ('django.db.models.fields.CharField', [], {'max_length': '64', 'primary_key': 'True'}),
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['person.Person']", 'null': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'})
},
u'person.person': {
'Meta': {'object_name': 'Person'},
'address': ('django.db.models.fields.TextField', [], {'max_length': '255', 'blank': 'True'}),
'affiliation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'ascii': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'ascii_short': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['auth.User']", 'unique': 'True', 'null': 'True', 'blank': 'True'})
}
}
complete_apps = ['ipr']

View file

@ -0,0 +1,540 @@
# -*- coding: utf-8 -*-
from south.db import db
from south.v2 import SchemaMigration
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model 'NonDocSpecificIprDisclosure'
db.create_table(u'ipr_nondocspecificiprdisclosure', (
(u'iprdisclosurebase_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['ipr.IprDisclosureBase'], unique=True, primary_key=True)),
('holder_contact_name', self.gf('django.db.models.fields.CharField')(max_length=255)),
('holder_contact_email', self.gf('django.db.models.fields.EmailField')(max_length=75)),
('holder_contact_info', self.gf('django.db.models.fields.TextField')(blank=True)),
('patent_info', self.gf('django.db.models.fields.TextField')()),
('has_patent_pending', self.gf('django.db.models.fields.BooleanField')(default=False)),
('statement', self.gf('django.db.models.fields.TextField')()),
))
db.send_create_signal(u'ipr', ['NonDocSpecificIprDisclosure'])
# Adding model 'RelatedIpr'
db.create_table(u'ipr_relatedipr', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('source', self.gf('django.db.models.fields.related.ForeignKey')(related_name='relatedipr_source_set', to=orm['ipr.IprDisclosureBase'])),
('target', self.gf('django.db.models.fields.related.ForeignKey')(related_name='relatedipr_target_set', to=orm['ipr.IprDisclosureBase'])),
('relationship', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['name.DocRelationshipName'])),
))
db.send_create_signal(u'ipr', ['RelatedIpr'])
# Adding model 'GenericIprDisclosure'
db.create_table(u'ipr_genericiprdisclosure', (
(u'iprdisclosurebase_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['ipr.IprDisclosureBase'], unique=True, primary_key=True)),
('holder_contact_name', self.gf('django.db.models.fields.CharField')(max_length=255)),
('holder_contact_email', self.gf('django.db.models.fields.EmailField')(max_length=75)),
('holder_contact_info', self.gf('django.db.models.fields.TextField')(blank=True)),
('statement', self.gf('django.db.models.fields.TextField')()),
))
db.send_create_signal(u'ipr', ['GenericIprDisclosure'])
# Adding model 'LegacyMigrationIprEvent'
db.create_table(u'ipr_legacymigrationiprevent', (
(u'iprevent_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['ipr.IprEvent'], unique=True, primary_key=True)),
))
db.send_create_signal(u'ipr', ['LegacyMigrationIprEvent'])
# Adding model 'HolderIprDisclosure'
db.create_table(u'ipr_holderiprdisclosure', (
(u'iprdisclosurebase_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['ipr.IprDisclosureBase'], unique=True, primary_key=True)),
('ietfer_name', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)),
('ietfer_contact_email', self.gf('django.db.models.fields.EmailField')(max_length=75, blank=True)),
('ietfer_contact_info', self.gf('django.db.models.fields.TextField')(blank=True)),
('patent_info', self.gf('django.db.models.fields.TextField')()),
('has_patent_pending', self.gf('django.db.models.fields.BooleanField')(default=False)),
('holder_contact_email', self.gf('django.db.models.fields.EmailField')(max_length=75)),
('holder_contact_name', self.gf('django.db.models.fields.CharField')(max_length=255)),
('holder_contact_info', self.gf('django.db.models.fields.TextField')(blank=True)),
('licensing', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['name.IprLicenseTypeName'])),
('licensing_comments', self.gf('django.db.models.fields.TextField')(blank=True)),
('submitter_claims_all_terms_disclosed', self.gf('django.db.models.fields.BooleanField')(default=False)),
))
db.send_create_signal(u'ipr', ['HolderIprDisclosure'])
# Adding model 'IprDisclosureBase'
db.create_table(u'ipr_iprdisclosurebase', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('by', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['person.Person'])),
('compliant', self.gf('django.db.models.fields.BooleanField')(default=True)),
('holder_legal_name', self.gf('django.db.models.fields.CharField')(max_length=255)),
('notes', self.gf('django.db.models.fields.TextField')(blank=True)),
('other_designations', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)),
('state', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['name.IprDisclosureStateName'])),
('submitter_name', self.gf('django.db.models.fields.CharField')(max_length=255)),
('submitter_email', self.gf('django.db.models.fields.EmailField')(max_length=75)),
('time', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
('title', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)),
))
db.send_create_signal(u'ipr', ['IprDisclosureBase'])
# Adding model 'IprEvent'
db.create_table(u'ipr_iprevent', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('time', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
('type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['name.IprEventTypeName'])),
('by', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['person.Person'])),
('disclosure', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['ipr.IprDisclosureBase'])),
('desc', self.gf('django.db.models.fields.TextField')()),
('message', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='msgevents', null=True, to=orm['message.Message'])),
('in_reply_to', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='irtoevents', null=True, to=orm['message.Message'])),
('response_due', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)),
))
db.send_create_signal(u'ipr', ['IprEvent'])
# Adding model 'IprDocRel'
db.create_table(u'ipr_iprdocrel', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('disclosure', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['ipr.IprDisclosureBase'])),
('document', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['doc.DocAlias'])),
('sections', self.gf('django.db.models.fields.TextField')(blank=True)),
('revisions', self.gf('django.db.models.fields.CharField')(max_length=16, blank=True)),
))
db.send_create_signal(u'ipr', ['IprDocRel'])
# Adding model 'ThirdPartyIprDisclosure'
db.create_table(u'ipr_thirdpartyiprdisclosure', (
(u'iprdisclosurebase_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['ipr.IprDisclosureBase'], unique=True, primary_key=True)),
('ietfer_name', self.gf('django.db.models.fields.CharField')(max_length=255)),
('ietfer_contact_email', self.gf('django.db.models.fields.EmailField')(max_length=75)),
('ietfer_contact_info', self.gf('django.db.models.fields.TextField')(blank=True)),
('patent_info', self.gf('django.db.models.fields.TextField')()),
('has_patent_pending', self.gf('django.db.models.fields.BooleanField')(default=False)),
))
db.send_create_signal(u'ipr', ['ThirdPartyIprDisclosure'])
def backwards(self, orm):
# Deleting model 'NonDocSpecificIprDisclosure'
db.delete_table(u'ipr_nondocspecificiprdisclosure')
# Deleting model 'RelatedIpr'
db.delete_table(u'ipr_relatedipr')
# Deleting model 'GenericIprDisclosure'
db.delete_table(u'ipr_genericiprdisclosure')
# Deleting model 'LegacyMigrationIprEvent'
db.delete_table(u'ipr_legacymigrationiprevent')
# Deleting model 'HolderIprDisclosure'
db.delete_table(u'ipr_holderiprdisclosure')
# Deleting model 'IprDisclosureBase'
db.delete_table(u'ipr_iprdisclosurebase')
# Deleting model 'IprEvent'
db.delete_table(u'ipr_iprevent')
# Deleting model 'IprDocRel'
db.delete_table(u'ipr_iprdocrel')
# Deleting model 'ThirdPartyIprDisclosure'
db.delete_table(u'ipr_thirdpartyiprdisclosure')
models = {
u'auth.group': {
'Meta': {'object_name': 'Group'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
u'auth.permission': {
'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
u'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
},
u'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
u'doc.docalias': {
'Meta': {'object_name': 'DocAlias'},
'document': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['doc.Document']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'})
},
u'doc.document': {
'Meta': {'object_name': 'Document'},
'abstract': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'ad': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'ad_document_set'", 'null': 'True', 'to': u"orm['person.Person']"}),
'authors': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['person.Email']", 'symmetrical': 'False', 'through': u"orm['doc.DocumentAuthor']", 'blank': 'True'}),
'expires': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'external_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
'group': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['group.Group']", 'null': 'True', 'blank': 'True'}),
'intended_std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['name.IntendedStdLevelName']", 'null': 'True', 'blank': 'True'}),
'internal_comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'primary_key': 'True'}),
'note': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'notify': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '1', 'blank': 'True'}),
'pages': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'rev': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}),
'shepherd': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'shepherd_document_set'", 'null': 'True', 'to': u"orm['person.Email']"}),
'states': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}),
'std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['name.StdLevelName']", 'null': 'True', 'blank': 'True'}),
'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['name.StreamName']", 'null': 'True', 'blank': 'True'}),
'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['name.DocTagName']", 'null': 'True', 'blank': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['name.DocTypeName']", 'null': 'True', 'blank': 'True'})
},
u'doc.documentauthor': {
'Meta': {'ordering': "['document', 'order']", 'object_name': 'DocumentAuthor'},
'author': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['person.Email']"}),
'document': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['doc.Document']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '1'})
},
u'doc.state': {
'Meta': {'ordering': "['type', 'order']", 'object_name': 'State'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'next_states': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'previous_states'", 'blank': 'True', 'to': u"orm['doc.State']"}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['doc.StateType']"}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'doc.statetype': {
'Meta': {'object_name': 'StateType'},
'label': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '30', 'primary_key': 'True'})
},
u'group.group': {
'Meta': {'object_name': 'Group'},
'acronym': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '40'}),
'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['person.Person']", 'null': 'True', 'blank': 'True'}),
'charter': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'related_name': "'chartered_group'", 'unique': 'True', 'null': 'True', 'to': u"orm['doc.Document']"}),
'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'list_archive': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'list_email': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
'list_subscribe': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
'parent': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['group.Group']", 'null': 'True', 'blank': 'True'}),
'state': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['name.GroupStateName']", 'null': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['name.GroupTypeName']", 'null': 'True'}),
'unused_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}),
'unused_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['name.DocTagName']", 'symmetrical': 'False', 'blank': 'True'})
},
u'ipr.genericiprdisclosure': {
'Meta': {'object_name': 'GenericIprDisclosure', '_ormbases': [u'ipr.IprDisclosureBase']},
'holder_contact_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
'holder_contact_info': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'holder_contact_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
u'iprdisclosurebase_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['ipr.IprDisclosureBase']", 'unique': 'True', 'primary_key': 'True'}),
'statement': ('django.db.models.fields.TextField', [], {})
},
u'ipr.holderiprdisclosure': {
'Meta': {'object_name': 'HolderIprDisclosure', '_ormbases': [u'ipr.IprDisclosureBase']},
'has_patent_pending': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'holder_contact_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
'holder_contact_info': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'holder_contact_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'ietfer_contact_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'ietfer_contact_info': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'ietfer_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
u'iprdisclosurebase_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['ipr.IprDisclosureBase']", 'unique': 'True', 'primary_key': 'True'}),
'licensing': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['name.IprLicenseTypeName']"}),
'licensing_comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'limited_to_std_track': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'patent_info': ('django.db.models.fields.TextField', [], {}),
'submitter_claims_all_terms_disclosed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
},
u'ipr.iprcontact': {
'Meta': {'object_name': 'IprContact'},
'address1': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'address2': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'contact_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'contact_type': ('django.db.models.fields.IntegerField', [], {}),
'department': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '255'}),
'fax': ('django.db.models.fields.CharField', [], {'max_length': '25', 'blank': 'True'}),
'ipr': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'contact'", 'to': u"orm['ipr.IprDetail']"}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'telephone': ('django.db.models.fields.CharField', [], {'max_length': '25', 'blank': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'})
},
u'ipr.iprdetail': {
'Meta': {'object_name': 'IprDetail'},
'applies_to_all': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'db_column': "'selectowned'", 'blank': 'True'}),
'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'comply': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'country': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'date_applied': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'document_sections': ('django.db.models.fields.TextField', [], {'max_length': '255', 'db_column': "'disclouser_identify'", 'blank': 'True'}),
'generic': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'id_document_tag': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'ipr_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_pending': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'db_column': "'selecttype'", 'blank': 'True'}),
'legacy_title_1': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_column': "'additional_old_title1'", 'blank': 'True'}),
'legacy_title_2': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_column': "'additional_old_title2'", 'blank': 'True'}),
'legacy_url_0': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_column': "'old_ipr_url'", 'blank': 'True'}),
'legacy_url_1': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_column': "'additional_old_url1'", 'blank': 'True'}),
'legacy_url_2': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_column': "'additional_old_url2'", 'blank': 'True'}),
'legal_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'p_h_legal_name'"}),
'lic_checkbox': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'lic_opt_a_sub': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
'lic_opt_b_sub': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
'lic_opt_c_sub': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
'licensing_option': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'notes': ('django.db.models.fields.TextField', [], {'db_column': "'p_notes'", 'blank': 'True'}),
'other_designations': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'other_notes': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'patents': ('django.db.models.fields.TextField', [], {'max_length': '255', 'db_column': "'p_applications'"}),
'rfc_number': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'status': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'submitted_date': ('django.db.models.fields.DateField', [], {'blank': 'True'}),
'third_party': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'document_title'", 'blank': 'True'}),
'update_notified_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'})
},
u'ipr.iprdisclosurebase': {
'Meta': {'object_name': 'IprDisclosureBase'},
'by': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['person.Person']"}),
'compliant': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'docs': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['doc.DocAlias']", 'through': u"orm['ipr.IprDocRel']", 'symmetrical': 'False'}),
'holder_legal_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'notes': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'other_designations': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'rel': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['ipr.IprDisclosureBase']", 'through': u"orm['ipr.RelatedIpr']", 'symmetrical': 'False'}),
'state': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['name.IprDisclosureStateName']"}),
'submitter_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
'submitter_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'})
},
u'ipr.iprdocalias': {
'Meta': {'object_name': 'IprDocAlias'},
'doc_alias': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['doc.DocAlias']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'ipr': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['ipr.IprDetail']"}),
'rev': ('django.db.models.fields.CharField', [], {'max_length': '2', 'blank': 'True'})
},
u'ipr.iprdocrel': {
'Meta': {'object_name': 'IprDocRel'},
'disclosure': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['ipr.IprDisclosureBase']"}),
'document': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['doc.DocAlias']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'revisions': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}),
'sections': ('django.db.models.fields.TextField', [], {'blank': 'True'})
},
u'ipr.iprevent': {
'Meta': {'ordering': "['-time', '-id']", 'object_name': 'IprEvent'},
'by': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['person.Person']"}),
'desc': ('django.db.models.fields.TextField', [], {}),
'disclosure': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['ipr.IprDisclosureBase']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'in_reply_to': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'irtoevents'", 'null': 'True', 'to': u"orm['message.Message']"}),
'message': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'msgevents'", 'null': 'True', 'to': u"orm['message.Message']"}),
'response_due': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['name.IprEventTypeName']"})
},
u'ipr.iprnotification': {
'Meta': {'object_name': 'IprNotification'},
'date_sent': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'ipr': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['ipr.IprDetail']"}),
'notification': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'time_sent': ('django.db.models.fields.CharField', [], {'max_length': '25', 'blank': 'True'})
},
u'ipr.iprupdate': {
'Meta': {'object_name': 'IprUpdate'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'ipr': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'updates'", 'to': u"orm['ipr.IprDetail']"}),
'processed': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'status_to_be': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'updated': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'updated_by'", 'db_column': "'updated'", 'to': u"orm['ipr.IprDetail']"})
},
u'ipr.legacymigrationiprevent': {
'Meta': {'ordering': "['-time', '-id']", 'object_name': 'LegacyMigrationIprEvent', '_ormbases': [u'ipr.IprEvent']},
u'iprevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['ipr.IprEvent']", 'unique': 'True', 'primary_key': 'True'})
},
u'ipr.nondocspecificiprdisclosure': {
'Meta': {'object_name': 'NonDocSpecificIprDisclosure', '_ormbases': [u'ipr.IprDisclosureBase']},
'has_patent_pending': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'holder_contact_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
'holder_contact_info': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'holder_contact_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
u'iprdisclosurebase_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['ipr.IprDisclosureBase']", 'unique': 'True', 'primary_key': 'True'}),
'patent_info': ('django.db.models.fields.TextField', [], {}),
'statement': ('django.db.models.fields.TextField', [], {})
},
u'ipr.relatedipr': {
'Meta': {'object_name': 'RelatedIpr'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'relationship': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['name.DocRelationshipName']"}),
'source': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedipr_source_set'", 'to': u"orm['ipr.IprDisclosureBase']"}),
'target': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedipr_target_set'", 'to': u"orm['ipr.IprDisclosureBase']"})
},
u'ipr.thirdpartyiprdisclosure': {
'Meta': {'object_name': 'ThirdPartyIprDisclosure', '_ormbases': [u'ipr.IprDisclosureBase']},
'has_patent_pending': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'ietfer_contact_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
'ietfer_contact_info': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'ietfer_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
u'iprdisclosurebase_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['ipr.IprDisclosureBase']", 'unique': 'True', 'primary_key': 'True'}),
'patent_info': ('django.db.models.fields.TextField', [], {})
},
u'message.message': {
'Meta': {'ordering': "['time']", 'object_name': 'Message'},
'bcc': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'body': ('django.db.models.fields.TextField', [], {}),
'by': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['person.Person']"}),
'cc': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'blank': 'True'}),
'content_type': ('django.db.models.fields.CharField', [], {'default': "'text/plain'", 'max_length': '255', 'blank': 'True'}),
'frm': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'related_docs': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['doc.Document']", 'symmetrical': 'False', 'blank': 'True'}),
'related_groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['group.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'reply_address': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'reply_to': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'to': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
},
u'name.docrelationshipname': {
'Meta': {'ordering': "['order']", 'object_name': 'DocRelationshipName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'revname': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.doctagname': {
'Meta': {'ordering': "['order']", 'object_name': 'DocTagName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.doctypename': {
'Meta': {'ordering': "['order']", 'object_name': 'DocTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.groupstatename': {
'Meta': {'ordering': "['order']", 'object_name': 'GroupStateName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.grouptypename': {
'Meta': {'ordering': "['order']", 'object_name': 'GroupTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.intendedstdlevelname': {
'Meta': {'ordering': "['order']", 'object_name': 'IntendedStdLevelName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.iprdisclosurestatename': {
'Meta': {'ordering': "['order']", 'object_name': 'IprDisclosureStateName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.ipreventtypename': {
'Meta': {'ordering': "['order']", 'object_name': 'IprEventTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.iprlicensetypename': {
'Meta': {'ordering': "['order']", 'object_name': 'IprLicenseTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.stdlevelname': {
'Meta': {'ordering': "['order']", 'object_name': 'StdLevelName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.streamname': {
'Meta': {'ordering': "['order']", 'object_name': 'StreamName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'person.email': {
'Meta': {'object_name': 'Email'},
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'address': ('django.db.models.fields.CharField', [], {'max_length': '64', 'primary_key': 'True'}),
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['person.Person']", 'null': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'})
},
u'person.person': {
'Meta': {'object_name': 'Person'},
'address': ('django.db.models.fields.TextField', [], {'max_length': '255', 'blank': 'True'}),
'affiliation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'ascii': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'ascii_short': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['auth.User']", 'unique': 'True', 'null': 'True', 'blank': 'True'})
}
}
complete_apps = ['ipr']

View file

@ -0,0 +1,922 @@
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.v2 import DataMigration
#import datetime
import email
import os
import re
import urllib2
#import pytz
from collections import namedtuple
from time import mktime, strptime
from urlparse import urlparse
from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist
from django.template.loader import render_to_string
class Migration(DataMigration):
depends_on = (
("name", "0029_add_ipr_names"),
)
# ---------------------------
# Private Helper Functions
# ---------------------------
def _decode_safely(self,data):
"""Return data decoded according to charset, but do so safely."""
try:
return unicode(data,'latin1')
except (UnicodeDecodeError, LookupError):
return unicode(data,'latin1',errors='replace')
def _get_url(self,url):
"""Returns contents of URL as unicode"""
try:
fp = urllib2.urlopen(url)
data = fp.read()
fp.close()
except Exception:
return ''
return self._decode_safely(data)
def _get_legacy_submitter(self,ipr):
"""Returns tuple of submitter_name, submitter_email if submitter info
is found in the legacy text file"""
match = self.LEGACY_URL_PATTERN.match(ipr.legacy_url_0)
if not match:
return (None,None)
filename = match.groups()[0]
path = os.path.join(settings.IPR_DOCUMENT_PATH,filename)
try:
with open(path) as file:
for line in file:
if re.search('^Submitter:',line):
text = line[10:]
return email.utils.parseaddr(text)
except:
pass
return (None,None)
def _create_comment(self,old, new, url_field, orm, title_field=None):
"""Create an IprEvent Comment given the legacy info.
If called with legacy_url_0 field created use LegacyMigrationIprEvent type"""
url = getattr(old,url_field)
if title_field:
title_text = u"{}: {}\n".format(title_field,getattr(old,title_field))
else:
title_text = u""
if url.endswith('pdf'):
# TODO: check for file ending in txt
data = ''
else:
data = self._get_url(url)
# Fix up missing scheme and hostname for links in message
if re.search('href=[\'"]/', data):
scheme, netloc, _, _, _, _ = urlparse(url)
data = re.sub('(href=[\'"])/', r'\1%s://%s/'%(scheme,netloc), data)
# create event objects
desc = title_text + u"From: {}\n\n{}".format(url,data)
if url_field == 'legacy_url_0':
klass = orm.LegacyMigrationIprEvent
else:
klass = orm.IprEvent
obj = klass.objects.create(type=self.legacy_event,
by=self.system,
disclosure=new,
desc=desc)
obj.time = old.submitted_date
obj.save()
def _combine_fields(self,obj,fields):
"""Returns fields combined into one string. Uses field_mapping to apply
extra formatting for some fields."""
data = u""
for field in fields:
val = getattr(obj,field)
if val:
if field in self.field_mapping:
data += u"{}: {}\n".format(self.field_mapping[field],val)
else:
data += u"{}\n".format(val)
return data
def _handle_contacts(self,old,new,orm):
"""
In some cases, due to bug?, one declaration may have multiple contacts of the same
type (see pk=2185), only process once.
"""
seen = []
for contact in old.contact.all():
if contact.contact_type in seen:
continue
seen.append(contact.contact_type)
fields = self.contact_type_mapping[contact.contact_type]
info = self._combine_fields(contact,['title',
'department',
'address1',
'address2',
'telephone',
'fax'])
fields = self.ContactFields(*fields)
if hasattr(new,fields.name):
setattr(new,fields.name,contact.name)
if hasattr(new,fields.info):
setattr(new,fields.info,info)
if hasattr(new,fields.email):
setattr(new,fields.email,contact.email)
def _handle_docs(self,old,new,orm):
"""Create IprDocRel relationships"""
iprdocaliases = old.iprdocalias_set.all()
for iprdocalias in iprdocaliases:
orm.IprDocRel.objects.create(disclosure=new.iprdisclosurebase_ptr,
document=iprdocalias.doc_alias,
sections=old.document_sections,
revisions=iprdocalias.rev)
# check other_designations for related documents
matches = self.DRAFT_PATTERN.findall(old.other_designations)
for name,rev in map(self._split_revision,matches):
try:
draft = orm['doc.Document'].objects.get(type='draft',name=name)
except ObjectDoesNotExist:
print "WARN: couldn't find other_designation: {}".format(name)
continue
if not orm.IprDocRel.objects.filter(disclosure=new.iprdisclosurebase_ptr,document__in=draft.docalias_set.all()):
orm.IprDocRel.objects.create(disclosure=new.iprdisclosurebase_ptr,
document=draft.docalias_set.get(name=draft.name),
sections=old.document_sections,
revisions=rev)
def _handle_licensing(self,old,new,orm):
"""Map licensing information into new object. ThirdParty disclosures
do not have any. The "limited to standards track only" designators are not
included in the new models. Users will need to include this in the notes
sections. Therefore lic_opt_?_sub options are converted to license text"""
if old.lic_opt_a_sub or old.lic_opt_b_sub or old.lic_opt_c_sub:
extra = "This licensing declaration is limited solely to standards-track IETF documents"
else:
extra = ''
if isinstance(new, (orm.GenericIprDisclosure,orm.NonDocSpecificIprDisclosure)):
context = {'option':old.licensing_option,'info':old.comments,'extra':extra}
new.statement = render_to_string("ipr/migration_licensing.txt",context)
elif isinstance(new, orm.HolderIprDisclosure):
new.licensing = self.licensing_mapping[old.licensing_option]
new.licensing_comments = old.comments
if extra:
new.licensing_comments = new.licensing_comments + '\n\n' + extra
new.submitter_claims_all_terms_disclosed = old.lic_checkbox
def _handle_legacy_fields(self,old,new,orm):
"""Get contents of URLs in legacy fields and save in an IprEvent"""
# legacy_url_0
if old.legacy_url_0:
self._create_comment(old,new,'legacy_url_0',orm)
if not new.submitter_email:
name,email = self._get_legacy_submitter(old)
if name or email:
new.submitter_name = name
new.submitter_email = email
# legacy_url_1
# Titles that start with "update" will be converted to RelatedIpr later
if old.legacy_title_1 and not old.legacy_title_1.startswith('Update'):
self._create_comment(old,new,'legacy_url_1',orm,title_field='legacy_title_1')
# legacy_url_2
def _handle_notification(self,rec,orm):
"""Map IprNotification to IprEvent and Message objects.
NOTE: some IprNotifications contain non-ascii text causing
email.message_from_string() to fail, hence the workaround
"""
parts = rec.notification.split('\r\n\r\n',1)
msg = email.message_from_string(parts[0])
msg.set_payload(parts[1])
disclosure = orm.IprDisclosureBase.objects.get(pk=rec.ipr.pk)
type = orm['name.IprEventTypeName'].objects.get(slug='msgout')
subject = msg['subject']
subject = (subject[:252] + '...') if len(subject) > 255 else subject
time_string = rec.date_sent.strftime('%Y-%m-%d ') + rec.time_sent
struct = strptime(time_string,'%Y-%m-%d %H:%M:%S')
# Use this when we start using TZ-aware datetimes
#timestamp = datetime.datetime.fromtimestamp(mktime(struct), pytz.timezone('US/Pacific'))
timestamp = datetime.datetime.fromtimestamp(mktime(struct))
message = orm['message.Message'].objects.create(
by = self.system,
subject = subject,
frm = msg.get('from'),
to = msg.get('to'),
cc = msg.get('cc'),
body = msg.get_payload(),
time = timestamp,
)
event = orm.IprEvent.objects.create(
type = type,
by = self.system,
disclosure = disclosure,
desc = 'Sent Message',
message = message,
)
# go back fix IprEvent.time
event.time = timestamp
event.save()
def _handle_patent_info(self,old,new,orm):
"""Map patent info. patent_info and applies_to_all are mutually exclusive"""
# TODO: do anything with old.applies_to_all?
if not hasattr(new, 'patent_info'):
return None
data = self._combine_fields(old,['patents','date_applied','country','notes'])
new.patent_info = data
if old.is_pending == 1:
new.has_patent_pending = True
def _handle_rel(self,iprdetail,orm):
"""Create RelatedIpr relationships based on legacy data"""
new = orm.IprDisclosureBase.objects.get(pk=iprdetail.pk)
# build relationships from IprUpdates
for iprupdate in iprdetail.updates.all():
target = orm.IprDisclosureBase.objects.get(pk=iprupdate.updated.pk)
orm.RelatedIpr.objects.create(source=new,
target=target,
relationship=self.UPDATES)
# build relationships from legacy_url_1
url = iprdetail.legacy_url_1
title = iprdetail.legacy_title_1
if title and title.startswith('Updated by'):
# get object id from URL
match = self.URL_PATTERN.match(url)
if match:
id = match.groups()[0]
try:
source = orm.IprDisclosureBase.objects.get(pk=id)
except:
print "No record for {}".format(url)
return
try:
orm.RelatedIpr.objects.get(source=source,target=new,relationship=self.UPDATES)
except ObjectDoesNotExist:
orm.RelatedIpr.objects.create(source=source,target=new,relationship=self.UPDATES)
def _split_revision(self,text):
if self.DRAFT_HAS_REVISION_PATTERN.match(text):
return text[:-3],text[-2:]
else:
return text,None
# ---------------------------
# Migrations Functions
# ---------------------------
def forwards(self, orm):
"Write your forwards methods here."
# Note: Don't use "from appname.models import ModelName".
# Use orm.ModelName to refer to models in this application,
# and orm['appname.ModelName'] for models in other applications.
self.system = orm['person.Person'].objects.get(name="(System)")
self.ContactFields = namedtuple('ContactFields',['name','info','email'])
self.DRAFT_PATTERN = re.compile(r'draft-[a-zA-Z0-9\-]+')
self.DRAFT_HAS_REVISION_PATTERN = re.compile(r'.*-[0-9]{2}')
self.URL_PATTERN = re.compile(r'https?://datatracker.ietf.org/ipr/(\d{1,4})/')
self.LEGACY_URL_PATTERN = re.compile(r'https?://www.ietf.org/ietf-ftp/IPR/(.*)$')
self.SEQUENCE_PATTERN = re.compile(r'.+ \(\d\)$')
self.UPDATES = orm['name.DocRelationshipName'].objects.get(slug='updates')
self.legacy_event = orm['name.IprEventTypeName'].objects.get(slug='legacy')
self.field_mapping = {'telephone':'T','fax':'F','date_applied':'Date','country':'Country','notes':'\nNotes'}
self.contact_type_name_mapping = { 1:'holder',2:'ietfer',3:'submitter' }
self.licensing_mapping = { 0:orm['name.IprLicenseTypeName'].objects.get(slug='none-selected'),
1:orm['name.IprLicenseTypeName'].objects.get(slug='no-license'),
2:orm['name.IprLicenseTypeName'].objects.get(slug='royalty-free'),
3:orm['name.IprLicenseTypeName'].objects.get(slug='reasonable'),
4:orm['name.IprLicenseTypeName'].objects.get(slug='provided-later'),
5:orm['name.IprLicenseTypeName'].objects.get(slug='unwilling-to-commit'),
6:orm['name.IprLicenseTypeName'].objects.get(slug='see-below'),
None:orm['name.IprLicenseTypeName'].objects.get(slug='none-selected') }
self.states_mapping = { 0:orm['name.IprDisclosureStateName'].objects.get(slug='pending'),
1:orm['name.IprDisclosureStateName'].objects.get(slug='posted'),
2:orm['name.IprDisclosureStateName'].objects.get(slug='rejected'),
3:orm['name.IprDisclosureStateName'].objects.get(slug='removed') }
self.contact_type_mapping = { 1:('holder_contact_name','holder_contact_info','holder_contact_email'),
2:('ietfer_name','ietfer_contact_info','ietfer_contact_email'),
3:('submitter_name','submitter_info','submitter_email') }
all = orm.IprDetail.objects.all().order_by('ipr_id')
for rec in all:
# Defaults
kwargs = { 'by':self.system,
'holder_legal_name':(rec.legal_name or "").strip(),
'id':rec.pk,
'notes':rec.other_notes,
'other_designations':rec.other_designations,
'state':self.states_mapping[rec.status],
'title':rec.title,
'time':datetime.datetime.now() }
# Determine Type.
if rec.third_party:
klass = orm.ThirdPartyIprDisclosure
elif rec.generic:
if rec.patents:
klass = orm.NonDocSpecificIprDisclosure
else:
klass = orm.GenericIprDisclosure
else:
klass = orm.HolderIprDisclosure
kwargs['licensing'] = self.licensing_mapping[rec.licensing_option]
new = klass.objects.create(**kwargs)
new.time = rec.submitted_date
self._handle_licensing(rec,new,orm)
self._handle_patent_info(rec,new,orm)
self._handle_contacts(rec,new,orm)
self._handle_legacy_fields(rec,new,orm)
self._handle_docs(rec,new,orm)
# strip sequence from title
if self.SEQUENCE_PATTERN.match(new.title):
new.title = new.title[:-4]
# save changes to disclosure object
new.save()
# create IprEvent:submitted
event = orm.IprEvent.objects.create(type_id='submitted',
by=self.system,
disclosure=new,
desc='IPR Disclosure Submitted')
# need to set time after object creation to override auto_now_add
event.time = rec.submitted_date
event.save()
if rec.status == 1:
# create IprEvent:posted
event = orm.IprEvent.objects.create(type_id='posted',
by=self.system,
disclosure=new,
desc='IPR Disclosure Posted')
# need to set time after object creation to override auto_now_add
event.time = rec.submitted_date
event.save()
# pass two, create relationships
for rec in all:
self._handle_rel(rec,orm)
# migrate IprNotifications
for rec in orm.IprNotification.objects.all():
self._handle_notification(rec,orm)
# print stats
print "-------------------------------"
for klass in (orm.HolderIprDisclosure,
orm.ThirdPartyIprDisclosure,
orm.NonDocSpecificIprDisclosure,
orm.GenericIprDisclosure):
print "{}: {}".format(klass.__name__,klass.objects.count())
print "Total records: {}".format(orm.IprDisclosureBase.objects.count())
def backwards(self, orm):
"Write your backwards methods here."
orm.IprDisclosureBase.objects.all().delete()
orm.IprEvent.objects.all().delete()
orm.RelatedIpr.objects.all().delete()
orm.IprDocRel.objects.all().delete()
models = {
u'auth.group': {
'Meta': {'object_name': 'Group'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
u'auth.permission': {
'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
u'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
},
u'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
u'doc.docalias': {
'Meta': {'object_name': 'DocAlias'},
'document': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['doc.Document']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'})
},
u'doc.document': {
'Meta': {'object_name': 'Document'},
'abstract': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'ad': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'ad_document_set'", 'null': 'True', 'to': u"orm['person.Person']"}),
'authors': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['person.Email']", 'symmetrical': 'False', 'through': u"orm['doc.DocumentAuthor']", 'blank': 'True'}),
'expires': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'external_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
'group': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['group.Group']", 'null': 'True', 'blank': 'True'}),
'intended_std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['name.IntendedStdLevelName']", 'null': 'True', 'blank': 'True'}),
'internal_comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'primary_key': 'True'}),
'note': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'notify': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '1', 'blank': 'True'}),
'pages': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'rev': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}),
'shepherd': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'shepherd_document_set'", 'null': 'True', 'to': u"orm['person.Email']"}),
'states': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}),
'std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['name.StdLevelName']", 'null': 'True', 'blank': 'True'}),
'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['name.StreamName']", 'null': 'True', 'blank': 'True'}),
'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['name.DocTagName']", 'null': 'True', 'blank': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['name.DocTypeName']", 'null': 'True', 'blank': 'True'})
},
u'doc.documentauthor': {
'Meta': {'ordering': "['document', 'order']", 'object_name': 'DocumentAuthor'},
'author': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['person.Email']"}),
'document': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['doc.Document']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '1'})
},
u'doc.state': {
'Meta': {'ordering': "['type', 'order']", 'object_name': 'State'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'next_states': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'previous_states'", 'blank': 'True', 'to': u"orm['doc.State']"}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['doc.StateType']"}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'doc.statetype': {
'Meta': {'object_name': 'StateType'},
'label': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '30', 'primary_key': 'True'})
},
u'group.group': {
'Meta': {'object_name': 'Group'},
'acronym': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '40'}),
'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['person.Person']", 'null': 'True', 'blank': 'True'}),
'charter': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'related_name': "'chartered_group'", 'unique': 'True', 'null': 'True', 'to': u"orm['doc.Document']"}),
'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'list_archive': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'list_email': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
'list_subscribe': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
'parent': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['group.Group']", 'null': 'True', 'blank': 'True'}),
'state': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['name.GroupStateName']", 'null': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['name.GroupTypeName']", 'null': 'True'}),
'unused_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}),
'unused_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['name.DocTagName']", 'symmetrical': 'False', 'blank': 'True'})
},
u'ipr.genericiprdisclosure': {
'Meta': {'object_name': 'GenericIprDisclosure', '_ormbases': [u'ipr.IprDisclosureBase']},
'holder_contact_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
'holder_contact_info': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'holder_contact_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
u'iprdisclosurebase_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['ipr.IprDisclosureBase']", 'unique': 'True', 'primary_key': 'True'}),
'statement': ('django.db.models.fields.TextField', [], {})
},
u'ipr.holderiprdisclosure': {
'Meta': {'object_name': 'HolderIprDisclosure', '_ormbases': [u'ipr.IprDisclosureBase']},
'has_patent_pending': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'holder_contact_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
'holder_contact_info': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'holder_contact_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'ietfer_contact_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'ietfer_contact_info': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'ietfer_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
u'iprdisclosurebase_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['ipr.IprDisclosureBase']", 'unique': 'True', 'primary_key': 'True'}),
'licensing': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['name.IprLicenseTypeName']"}),
'licensing_comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'patent_info': ('django.db.models.fields.TextField', [], {}),
'submitter_claims_all_terms_disclosed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
},
u'ipr.iprcontact': {
'Meta': {'object_name': 'IprContact'},
'address1': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'address2': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'contact_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'contact_type': ('django.db.models.fields.IntegerField', [], {}),
'department': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '255'}),
'fax': ('django.db.models.fields.CharField', [], {'max_length': '25', 'blank': 'True'}),
'ipr': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'contact'", 'to': u"orm['ipr.IprDetail']"}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'telephone': ('django.db.models.fields.CharField', [], {'max_length': '25', 'blank': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'})
},
u'ipr.iprdetail': {
'Meta': {'object_name': 'IprDetail'},
'applies_to_all': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'db_column': "'selectowned'", 'blank': 'True'}),
'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'comply': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'country': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'date_applied': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'document_sections': ('django.db.models.fields.TextField', [], {'max_length': '255', 'db_column': "'disclouser_identify'", 'blank': 'True'}),
'generic': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'id_document_tag': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'ipr_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_pending': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'db_column': "'selecttype'", 'blank': 'True'}),
'legacy_title_1': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_column': "'additional_old_title1'", 'blank': 'True'}),
'legacy_title_2': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_column': "'additional_old_title2'", 'blank': 'True'}),
'legacy_url_0': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_column': "'old_ipr_url'", 'blank': 'True'}),
'legacy_url_1': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_column': "'additional_old_url1'", 'blank': 'True'}),
'legacy_url_2': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_column': "'additional_old_url2'", 'blank': 'True'}),
'legal_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'p_h_legal_name'"}),
'lic_checkbox': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'lic_opt_a_sub': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
'lic_opt_b_sub': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
'lic_opt_c_sub': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
'licensing_option': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'notes': ('django.db.models.fields.TextField', [], {'db_column': "'p_notes'", 'blank': 'True'}),
'other_designations': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'other_notes': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'patents': ('django.db.models.fields.TextField', [], {'max_length': '255', 'db_column': "'p_applications'"}),
'rfc_number': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'status': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'submitted_date': ('django.db.models.fields.DateField', [], {'blank': 'True'}),
'third_party': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'document_title'", 'blank': 'True'}),
'update_notified_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'})
},
u'ipr.iprdisclosurebase': {
'Meta': {'object_name': 'IprDisclosureBase'},
'by': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['person.Person']"}),
'compliant': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'docs': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['doc.DocAlias']", 'through': u"orm['ipr.IprDocRel']", 'symmetrical': 'False'}),
'holder_legal_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'notes': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'other_designations': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'rel': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['ipr.IprDisclosureBase']", 'through': u"orm['ipr.RelatedIpr']", 'symmetrical': 'False'}),
'state': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['name.IprDisclosureStateName']"}),
'submitter_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
'submitter_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'})
},
u'ipr.iprdocalias': {
'Meta': {'object_name': 'IprDocAlias'},
'doc_alias': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['doc.DocAlias']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'ipr': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['ipr.IprDetail']"}),
'rev': ('django.db.models.fields.CharField', [], {'max_length': '2', 'blank': 'True'})
},
u'ipr.iprdocrel': {
'Meta': {'object_name': 'IprDocRel'},
'disclosure': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['ipr.IprDisclosureBase']"}),
'document': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['doc.DocAlias']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'revisions': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}),
'sections': ('django.db.models.fields.TextField', [], {'blank': 'True'})
},
u'ipr.iprevent': {
'Meta': {'ordering': "['-time', '-id']", 'object_name': 'IprEvent'},
'by': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['person.Person']"}),
'desc': ('django.db.models.fields.TextField', [], {}),
'disclosure': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['ipr.IprDisclosureBase']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'in_reply_to': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'irtoevents'", 'null': 'True', 'to': u"orm['message.Message']"}),
'message': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'msgevents'", 'null': 'True', 'to': u"orm['message.Message']"}),
'response_due': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['name.IprEventTypeName']"})
},
u'ipr.iprnotification': {
'Meta': {'object_name': 'IprNotification'},
'date_sent': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'ipr': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['ipr.IprDetail']"}),
'notification': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'time_sent': ('django.db.models.fields.CharField', [], {'max_length': '25', 'blank': 'True'})
},
u'ipr.iprupdate': {
'Meta': {'object_name': 'IprUpdate'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'ipr': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'updates'", 'to': u"orm['ipr.IprDetail']"}),
'processed': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'status_to_be': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'updated': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'updated_by'", 'db_column': "'updated'", 'to': u"orm['ipr.IprDetail']"})
},
u'ipr.legacymigrationiprevent': {
'Meta': {'ordering': "['-time', '-id']", 'object_name': 'LegacyMigrationIprEvent', '_ormbases': [u'ipr.IprEvent']},
u'iprevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['ipr.IprEvent']", 'unique': 'True', 'primary_key': 'True'})
},
u'ipr.nondocspecificiprdisclosure': {
'Meta': {'object_name': 'NonDocSpecificIprDisclosure', '_ormbases': [u'ipr.IprDisclosureBase']},
'has_patent_pending': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'holder_contact_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
'holder_contact_info': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'holder_contact_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
u'iprdisclosurebase_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['ipr.IprDisclosureBase']", 'unique': 'True', 'primary_key': 'True'}),
'patent_info': ('django.db.models.fields.TextField', [], {}),
'statement': ('django.db.models.fields.TextField', [], {})
},
u'ipr.relatedipr': {
'Meta': {'object_name': 'RelatedIpr'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'relationship': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['name.DocRelationshipName']"}),
'source': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedipr_source_set'", 'to': u"orm['ipr.IprDisclosureBase']"}),
'target': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedipr_target_set'", 'to': u"orm['ipr.IprDisclosureBase']"})
},
u'ipr.thirdpartyiprdisclosure': {
'Meta': {'object_name': 'ThirdPartyIprDisclosure', '_ormbases': [u'ipr.IprDisclosureBase']},
'has_patent_pending': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'ietfer_contact_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
'ietfer_contact_info': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'ietfer_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
u'iprdisclosurebase_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['ipr.IprDisclosureBase']", 'unique': 'True', 'primary_key': 'True'}),
'patent_info': ('django.db.models.fields.TextField', [], {})
},
u'message.message': {
'Meta': {'ordering': "['time']", 'object_name': 'Message'},
'bcc': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'body': ('django.db.models.fields.TextField', [], {}),
'by': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['person.Person']"}),
'cc': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'blank': 'True'}),
'content_type': ('django.db.models.fields.CharField', [], {'default': "'text/plain'", 'max_length': '255', 'blank': 'True'}),
'frm': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'related_docs': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['doc.Document']", 'symmetrical': 'False', 'blank': 'True'}),
'related_groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['group.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'reply_to': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'to': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
},
u'message.sendqueue': {
'Meta': {'ordering': "['time']", 'object_name': 'SendQueue'},
'by': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['person.Person']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'message': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['message.Message']"}),
'note': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'send_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'sent_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'})
},
u'name.ballotpositionname': {
'Meta': {'ordering': "['order']", 'object_name': 'BallotPositionName'},
'blocking': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.constraintname': {
'Meta': {'ordering': "['order']", 'object_name': 'ConstraintName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'penalty': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.dbtemplatetypename': {
'Meta': {'ordering': "['order']", 'object_name': 'DBTemplateTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.docrelationshipname': {
'Meta': {'ordering': "['order']", 'object_name': 'DocRelationshipName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'revname': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.docremindertypename': {
'Meta': {'ordering': "['order']", 'object_name': 'DocReminderTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.doctagname': {
'Meta': {'ordering': "['order']", 'object_name': 'DocTagName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.doctypename': {
'Meta': {'ordering': "['order']", 'object_name': 'DocTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.draftsubmissionstatename': {
'Meta': {'ordering': "['order']", 'object_name': 'DraftSubmissionStateName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'next_states': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'previous_states'", 'blank': 'True', 'to': u"orm['name.DraftSubmissionStateName']"}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.feedbacktypename': {
'Meta': {'ordering': "['order']", 'object_name': 'FeedbackTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.groupmilestonestatename': {
'Meta': {'ordering': "['order']", 'object_name': 'GroupMilestoneStateName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.groupstatename': {
'Meta': {'ordering': "['order']", 'object_name': 'GroupStateName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.grouptypename': {
'Meta': {'ordering': "['order']", 'object_name': 'GroupTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.intendedstdlevelname': {
'Meta': {'ordering': "['order']", 'object_name': 'IntendedStdLevelName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.iprdisclosurestatename': {
'Meta': {'ordering': "['order']", 'object_name': 'IprDisclosureStateName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.ipreventtypename': {
'Meta': {'ordering': "['order']", 'object_name': 'IprEventTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.iprlicensetypename': {
'Meta': {'ordering': "['order']", 'object_name': 'IprLicenseTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.liaisonstatementpurposename': {
'Meta': {'ordering': "['order']", 'object_name': 'LiaisonStatementPurposeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.meetingtypename': {
'Meta': {'ordering': "['order']", 'object_name': 'MeetingTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.nomineepositionstatename': {
'Meta': {'ordering': "['order']", 'object_name': 'NomineePositionStateName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.rolename': {
'Meta': {'ordering': "['order']", 'object_name': 'RoleName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.roomresourcename': {
'Meta': {'ordering': "['order']", 'object_name': 'RoomResourceName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.sessionstatusname': {
'Meta': {'ordering': "['order']", 'object_name': 'SessionStatusName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.stdlevelname': {
'Meta': {'ordering': "['order']", 'object_name': 'StdLevelName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.streamname': {
'Meta': {'ordering': "['order']", 'object_name': 'StreamName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.timeslottypename': {
'Meta': {'ordering': "['order']", 'object_name': 'TimeSlotTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'person.email': {
'Meta': {'object_name': 'Email'},
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'address': ('django.db.models.fields.CharField', [], {'max_length': '64', 'primary_key': 'True'}),
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['person.Person']", 'null': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'})
},
u'person.person': {
'Meta': {'object_name': 'Person'},
'address': ('django.db.models.fields.TextField', [], {'max_length': '255', 'blank': 'True'}),
'affiliation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'ascii': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'ascii_short': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['auth.User']", 'unique': 'True', 'null': 'True', 'blank': 'True'})
}
}
complete_apps = ['message', 'name', 'ipr']
symmetrical = True

View file

View file

@ -167,3 +167,199 @@ class IprDocAlias(models.Model):
verbose_name = "IPR document alias"
verbose_name_plural = "IPR document aliases"
# ===================================
# New Models
# ===================================
import datetime
from django.conf import settings
from django.core.urlresolvers import reverse
from ietf.name.models import DocRelationshipName,IprDisclosureStateName,IprLicenseTypeName,IprEventTypeName
from ietf.person.models import Person
from ietf.message.models import Message
class IprDisclosureBase(models.Model):
by = models.ForeignKey(Person) # who was logged in, or System if nobody was logged in
compliant = models.BooleanField(default=True) # complies to RFC3979
docs = models.ManyToManyField(DocAlias, through='IprDocRel')
holder_legal_name = models.CharField(max_length=255)
notes = models.TextField(blank=True)
other_designations = models.CharField(blank=True, max_length=255)
rel = models.ManyToManyField('self', through='RelatedIpr', symmetrical=False)
state = models.ForeignKey(IprDisclosureStateName)
submitter_name = models.CharField(max_length=255)
submitter_email = models.EmailField()
time = models.DateTimeField(auto_now_add=True)
title = models.CharField(blank=True, max_length=255)
def __unicode__(self):
return self.title
def get_absolute_url(self):
return settings.IDTRACKER_BASE_URL + reverse('ipr_show',kwargs={'id':self.id})
def get_child(self):
"""Returns the child instance"""
for child_class in ('genericiprdisclosure',
'holderiprdisclosure',
'nondocspecificiprdisclosure',
'thirdpartyiprdisclosure'):
try:
return getattr(self,child_class)
except IprDisclosureBase.DoesNotExist:
pass
def get_latest_event_msgout(self):
"""Returns the latest IprEvent of type msgout. For use in templates."""
return self.latest_event(type='msgout')
def has_legacy_event(self):
"""Returns True if there is one or more LegacyMigrationIprEvents
for this disclosure"""
if LegacyMigrationIprEvent.objects.filter(disclosure=self):
return True
else:
return False
def latest_event(self, *args, **filter_args):
"""Get latest event of optional Python type and with filter
arguments, e.g. d.latest_event(type="xyz") returns an IprEvent
while d.latest_event(WriteupDocEvent, type="xyz") returns a
WriteupDocEvent event."""
model = args[0] if args else IprEvent
e = model.objects.filter(disclosure=self).filter(**filter_args).order_by('-time', '-id')[:1]
return e[0] if e else None
def set_state(self, state):
"""This just sets the state, doesn't log the change. Takes a string"""
try:
statename = IprDisclosureStateName.objects.get(slug=state)
except IprDisclosureStateName.DoesNotExist:
return
self.state = statename
self.save()
@property
def updates(self):
"""Shortcut for disclosures this disclosure updates"""
return self.relatedipr_source_set.filter(relationship__slug='updates')
@property
def updated_by(self):
"""Shortcut for disclosures this disclosure is updated by"""
return self.relatedipr_target_set.filter(relationship__slug='updates')
@property
def update_notified_date(self):
"""Returns the date when the submitters of the IPR that this IPR updates
were notified"""
e = self.latest_event(type='update_notify')
if e:
return e.time
else:
return None
class HolderIprDisclosure(IprDisclosureBase):
ietfer_name = models.CharField(max_length=255, blank=True) # "Whose Personal Belief Triggered..."
ietfer_contact_email = models.EmailField(blank=True)
ietfer_contact_info = models.TextField(blank=True)
patent_info = models.TextField()
has_patent_pending = models.BooleanField(default=False)
holder_contact_email = models.EmailField()
holder_contact_name = models.CharField(max_length=255)
holder_contact_info = models.TextField(blank=True)
licensing = models.ForeignKey(IprLicenseTypeName)
licensing_comments = models.TextField(blank=True)
submitter_claims_all_terms_disclosed = models.BooleanField(default=False)
class ThirdPartyIprDisclosure(IprDisclosureBase):
ietfer_name = models.CharField(max_length=255) # "Whose Personal Belief Triggered..."
ietfer_contact_email = models.EmailField()
ietfer_contact_info = models.TextField(blank=True)
patent_info = models.TextField()
has_patent_pending = models.BooleanField(default=False)
class NonDocSpecificIprDisclosure(IprDisclosureBase):
'''A Generic IPR Disclosure w/ patent information'''
holder_contact_name = models.CharField(max_length=255)
holder_contact_email = models.EmailField()
holder_contact_info = models.TextField(blank=True)
patent_info = models.TextField()
has_patent_pending = models.BooleanField(default=False)
statement = models.TextField() # includes licensing info
class GenericIprDisclosure(IprDisclosureBase):
holder_contact_name = models.CharField(max_length=255)
holder_contact_email = models.EmailField()
holder_contact_info = models.TextField(blank=True)
statement = models.TextField() # includes licensing info
class IprDocRel(models.Model):
disclosure = models.ForeignKey(IprDisclosureBase)
document = models.ForeignKey(DocAlias)
sections = models.TextField(blank=True)
revisions = models.CharField(max_length=16,blank=True) # allows strings like 01-07
def doc_type(self):
name = self.document.name
if name.startswith("rfc"):
return "RFC"
if name.startswith("draft"):
return "Internet-Draft"
if name.startswith("slide"):
return "Meeting Slide"
def formatted_name(self):
name = self.document.name
if name.startswith("rfc"):
return name.upper()
#elif self.revisions:
# return "%s-%s" % (name, self.revisions)
else:
return name
def __unicode__(self):
if self.revisions:
return u"%s which applies to %s-%s" % (self.disclosure, self.document.name, self.revisions)
else:
return u"%s which applies to %s" % (self.disclosure, self.document.name)
class RelatedIpr(models.Model):
source = models.ForeignKey(IprDisclosureBase,related_name='relatedipr_source_set')
target = models.ForeignKey(IprDisclosureBase,related_name='relatedipr_target_set')
relationship = models.ForeignKey(DocRelationshipName) # Re-use; change to a dedicated RelName if needed
def __unicode__(self):
return u"%s %s %s" % (self.source.title, self.relationship.name.lower(), self.target.title)
class IprEvent(models.Model):
time = models.DateTimeField(auto_now_add=True)
type = models.ForeignKey(IprEventTypeName)
by = models.ForeignKey(Person)
disclosure = models.ForeignKey(IprDisclosureBase)
desc = models.TextField()
message = models.ForeignKey(Message, null=True, blank=True,related_name='msgevents')
in_reply_to = models.ForeignKey(Message, null=True, blank=True,related_name='irtoevents')
response_due= models.DateTimeField(blank=True,null=True)
def __unicode__(self):
return u"%s %s by %s at %s" % (self.disclosure.title, self.type.name.lower(), self.by.plain_name(), self.time)
def response_past_due(self):
"""Returns true if it's beyond the response_due date and no response has been
received"""
qs = IprEvent.objects.filter(disclosure=self.disclosure,in_reply_to=self.message)
if not qs and datetime.datetime.now().date() > self.response_due.date():
return True
else:
return False
class Meta:
ordering = ['-time', '-id']
class LegacyMigrationIprEvent(IprEvent):
"""A subclass of IprEvent specifically for capturing contents of legacy_url_0,
the text of a disclosure submitted by email"""
pass

View file

@ -1,346 +0,0 @@
# Copyright The IETF Trust 2007, All Rights Reserved
import re, datetime
from django.shortcuts import render_to_response as render, get_object_or_404
from django.template import RequestContext
from django.http import Http404
from django.conf import settings
from django import forms
from ietf.utils.log import log
from ietf.utils.mail import send_mail
from ietf.doc.models import Document, DocAlias
from ietf.ipr.models import IprDetail, IprDocAlias, IprContact, LICENSE_CHOICES, IprUpdate
from ietf.ipr.view_sections import section_table
# ----------------------------------------------------------------
# Create base forms from models
# ----------------------------------------------------------------
phone_re = re.compile(r'^\+?[0-9 ]*(\([0-9]+\))?[0-9 -]+( ?x ?[0-9]+)?$')
phone_error_message = """Phone numbers may have a leading "+", and otherwise only contain numbers [0-9]; dash, period or space; parentheses, and an optional extension number indicated by 'x'."""
class BaseIprForm(forms.ModelForm):
licensing_option = forms.IntegerField(widget=forms.RadioSelect(choices=LICENSE_CHOICES[1:]), required=False)
is_pending = forms.IntegerField(widget=forms.RadioSelect(choices=((1, "YES"), (2, "NO"))), required=False)
applies_to_all = forms.IntegerField(widget=forms.RadioSelect(choices=((1, "YES"), (2, "NO"))), required=False)
class Meta:
model = IprDetail
exclude = ('rfc_document', 'id_document_tag') # 'legacy_url_0','legacy_url_1','legacy_title_1','legacy_url_2','legacy_title_2')
class BaseContactForm(forms.ModelForm):
telephone = forms.RegexField(phone_re, error_message=phone_error_message, required=False)
fax = forms.RegexField(phone_re, error_message=phone_error_message, required=False)
class Meta:
model = IprContact
exclude = ('ipr', 'contact_type')
# Some subclassing:
# The contact form will be part of the IprForm, so it needs a widget.
# Define one.
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
# ----------------------------------------------------------------
# Form processing
# ----------------------------------------------------------------
def new(request, type, update=None, submitter=None):
"""Make a new IPR disclosure.
This is a big function -- maybe too big. Things would be easier if we didn't have
one form containing fields from 4 tables -- don't build something like this again...
"""
section_list = section_table[type].copy()
section_list.update({"title":False, "new_intro":False, "form_intro":True,
"form_submit":True, "form_legend": True, })
class IprForm(BaseIprForm):
holder_contact = None
rfclist = forms.CharField(required=False)
draftlist = forms.CharField(required=False)
stdonly_license = forms.BooleanField(required=False)
hold_contact_is_submitter = forms.BooleanField(required=False)
ietf_contact_is_submitter = forms.BooleanField(required=False)
if section_list.get("holder_contact", False):
holder_contact = ContactForm(prefix="hold")
if section_list.get("ietf_contact", False):
ietf_contact = ContactForm(prefix="ietf")
if section_list.get("submitter", False):
submitter = ContactForm(prefix="subm")
def __init__(self, *args, **kw):
contact_type = {1:"holder_contact", 2:"ietf_contact", 3:"submitter"}
contact_initial = {}
if update:
for contact in update.contact.all():
contact_initial[contact_type[contact.contact_type]] = contact.__dict__
if submitter:
if type == "third-party":
contact_initial["ietf_contact"] = submitter
else:
contact_initial["submitter"] = submitter
kwnoinit = kw.copy()
kwnoinit.pop('initial', None)
for contact in ["holder_contact", "ietf_contact", "submitter"]:
if section_list.get(contact, False):
setattr(self, contact, ContactForm(prefix=contact[:4], initial=contact_initial.get(contact, {}), *args, **kwnoinit))
rfclist_initial = ""
if update:
rfclist_initial = " ".join(a.doc_alias.name.upper() for a in IprDocAlias.objects.filter(doc_alias__name__startswith="rfc", ipr=update))
self.base_fields["rfclist"] = forms.CharField(required=False, initial=rfclist_initial)
draftlist_initial = ""
if update:
draftlist_initial = " ".join(a.doc_alias.name + ("-%s" % a.rev if a.rev else "") for a in IprDocAlias.objects.filter(ipr=update).exclude(doc_alias__name__startswith="rfc"))
self.base_fields["draftlist"] = forms.CharField(required=False, initial=draftlist_initial)
if section_list.get("holder_contact", False):
self.base_fields["hold_contact_is_submitter"] = forms.BooleanField(required=False)
if section_list.get("ietf_contact", False):
self.base_fields["ietf_contact_is_submitter"] = forms.BooleanField(required=False)
self.base_fields["stdonly_license"] = forms.BooleanField(required=False)
BaseIprForm.__init__(self, *args, **kw)
# Special validation code
def clean(self):
if section_list.get("ietf_doc", False):
# would like to put this in rfclist to get the error
# closer to the fields, but clean_data["draftlist"]
# isn't set yet.
rfclist = self.cleaned_data.get("rfclist", None)
draftlist = self.cleaned_data.get("draftlist", None)
other = self.cleaned_data.get("other_designations", None)
if not rfclist and not draftlist and not other:
raise forms.ValidationError("One of the Document fields below must be filled in")
return self.cleaned_data
def clean_rfclist(self):
rfclist = self.cleaned_data.get("rfclist", None)
if rfclist:
rfclist = re.sub("(?i) *[,;]? *rfc[- ]?", " ", rfclist)
rfclist = rfclist.strip().split()
for rfc in rfclist:
try:
DocAlias.objects.get(name="rfc%s" % int(rfc))
except (DocAlias.DoesNotExist, DocAlias.MultipleObjectsReturned, ValueError):
raise forms.ValidationError("Unknown RFC number: %s - please correct this." % rfc)
rfclist = " ".join(rfclist)
return rfclist
def clean_draftlist(self):
draftlist = self.cleaned_data.get("draftlist", None)
if draftlist:
draftlist = re.sub(" *[,;] *", " ", draftlist)
draftlist = draftlist.strip().split()
drafts = []
for draft in draftlist:
if draft.endswith(".txt"):
draft = draft[:-4]
if re.search("-[0-9][0-9]$", draft):
name = draft[:-3]
rev = draft[-2:]
else:
name = draft
rev = None
try:
doc = Document.objects.get(docalias__name=name)
except (Document.DoesNotExist, Document.MultipleObjectsReturned) as e:
log("Exception: %s" % e)
raise forms.ValidationError("Unknown Internet-Draft: %s - please correct this." % name)
if rev and doc.rev != rev:
raise forms.ValidationError("Unexpected revision '%s' for draft %s - the current revision is %s. Please check this." % (rev, name, doc.rev))
drafts.append("%s-%s" % (name, doc.rev))
return " ".join(drafts)
return ""
def clean_licensing_option(self):
licensing_option = self.cleaned_data['licensing_option']
if section_list.get('licensing', False):
if licensing_option in (None, ''):
raise forms.ValidationError, 'This field is required.'
return licensing_option
def is_valid(self):
if not BaseIprForm.is_valid(self):
return False
for contact in ["holder_contact", "ietf_contact", "submitter"]:
if hasattr(self, contact) and getattr(self, contact) != None and not getattr(self, contact).is_valid():
return False
return True
# If we're POSTed, but we got passed a submitter, it was the
# POST of the "get updater" form, so we don't want to validate
# this one. When we're posting *this* form, submitter is None,
# even when updating.
if request.method == 'POST' and not submitter:
data = request.POST.copy()
data["submitted_date"] = datetime.datetime.now().strftime("%Y-%m-%d")
data["third_party"] = section_list["third_party"]
data["generic"] = section_list["generic"]
data["status"] = "0"
data["comply"] = "1"
for src in ["hold", "ietf"]:
if "%s_contact_is_submitter" % src in data:
for subfield in ["name", "title", "department", "address1", "address2", "telephone", "fax", "email"]:
try:
data[ "subm_%s" % subfield ] = data[ "%s_%s" % (src,subfield) ]
except Exception:
pass
form = IprForm(data)
if form.is_valid():
# Save data :
# IprDetail, IprUpdate, IprContact+, IprDocAlias+, IprNotification
# Save IprDetail
instance = form.save(commit=False)
legal_name_genitive = data['legal_name'] + "'" if data['legal_name'].endswith('s') else data['legal_name'] + "'s"
if type == "generic":
instance.title = legal_name_genitive + " General License Statement"
elif type == "specific":
data["ipr_summary"] = get_ipr_summary(form.cleaned_data)
instance.title = legal_name_genitive + """ Statement about IPR related to %(ipr_summary)s""" % data
elif type == "third-party":
data["ipr_summary"] = get_ipr_summary(form.cleaned_data)
ietf_name_genitive = data['ietf_name'] + "'" if data['ietf_name'].endswith('s') else data['ietf_name'] + "'s"
instance.title = ietf_name_genitive + """ Statement about IPR related to %(ipr_summary)s belonging to %(legal_name)s""" % data
# A long document list can create a too-long title;
# saving a too-long title raises an exception,
# so prevent truncation in the database layer by
# performing it explicitly.
if len(instance.title) > 255:
instance.title = instance.title[:252] + "..."
instance.save()
if update:
updater = IprUpdate(ipr=instance, updated=update, status_to_be=1, processed=0)
updater.save()
contact_type = {"hold":1, "ietf":2, "subm": 3}
# Save IprContact(s)
for prefix in ["hold", "ietf", "subm"]:
# cdata = {"ipr": instance.ipr_id, "contact_type":contact_type[prefix]}
cdata = {"ipr": instance, "contact_type":contact_type[prefix]}
for item in data:
if item.startswith(prefix+"_"):
cdata[item[5:]] = data[item]
try:
del cdata["contact_is_submitter"]
except KeyError:
pass
contact = IprContact(**dict([(str(a),b) for a,b in cdata.items()]))
contact.save()
# store this contact in the instance for the email
# similar to what views.show() does
if prefix == "hold":
instance.holder_contact = contact
elif prefix == "ietf":
instance.ietf_contact = contact
elif prefix == "subm":
instance.submitter = contact
# contact = ContactForm(cdata)
# if contact.is_valid():
# contact.save()
# else:
# log("Invalid contact: %s" % contact)
# Save draft links
for draft in form.cleaned_data["draftlist"].split():
name = draft[:-3]
rev = draft[-2:]
IprDocAlias.objects.create(
doc_alias=DocAlias.objects.get(name=name),
ipr=instance,
rev=rev)
for rfcnum in form.cleaned_data["rfclist"].split():
IprDocAlias.objects.create(
doc_alias=DocAlias.objects.get(name="rfc%s" % int(rfcnum)),
ipr=instance,
rev="")
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))
else:
if 'ietf_contact_is_submitter' in data:
form.ietf_contact_is_submitter_checked = True
if 'hold_contact_is_submitter' in data:
form.hold_contact_is_submitter_checked = True
for error in form.errors:
log("Form error for field: %s: %s"%(error, form.errors[error]))
# Fall through, and let the partially bound form, with error
# indications, be rendered again.
pass
else:
if update:
form = IprForm(initial=update.__dict__)
else:
form = IprForm()
form.unbound_form = True
# log(dir(form.ietf_contact_is_submitter))
return render("ipr/details_edit.html", {"ipr": form, "section_list":section_list}, context_instance=RequestContext(request))
def update(request, ipr_id=None):
"""Update a specific IPR disclosure"""
ipr = get_object_or_404(IprDetail, ipr_id=ipr_id)
if not ipr.status in [1,3]:
raise Http404
type = "specific"
if ipr.generic:
type = "generic"
if ipr.third_party:
type = "third-party"
# We're either asking for initial permission or we're in
# the general ipr form. If the POST argument has the first
# field of the ipr form, then we must be dealing with that,
# so just pass through - otherwise, collect the updater's
# info first.
submitter = None
if not(request.POST.has_key('legal_name')):
class UpdateForm(BaseContactForm):
def __init__(self, *args, **kwargs):
super(UpdateForm, self).__init__(*args, **kwargs)
self.fields["update_auth"] = forms.BooleanField()
if request.method == 'POST':
form = UpdateForm(request.POST)
else:
form = UpdateForm()
if not(form.is_valid()):
for error in form.errors:
log("Form error for field: %s: %s"%(error, form.errors[error]))
return render("ipr/update.html", {"form": form, "ipr": ipr, "type": type}, context_instance=RequestContext(request))
else:
submitter = form.cleaned_data
return new(request, type, ipr, submitter)
def get_ipr_summary(data):
rfc_ipr = [ "RFC %s" % item for item in data["rfclist"].split() ]
draft_ipr = data["draftlist"].split()
ipr = rfc_ipr + draft_ipr
if data["other_designations"]:
ipr += [ data["other_designations"] ]
if len(ipr) == 1:
ipr = ipr[0]
elif len(ipr) == 2:
ipr = " and ".join(ipr)
else:
ipr = ", ".join(ipr[:-1]) + ", and " + ipr[-1]
return ipr

View file

@ -1,15 +0,0 @@
# Copyright The IETF Trust 2007, All Rights Reserved
def related_docs(alias):
results = list(alias.document.docalias_set.all())
rels = alias.document.all_relations_that_doc(['replaces','obs'])
for rel in rels:
rel_aliases = list(rel.target.document.docalias_set.all())
for x in rel_aliases:
x.related = rel
x.relation = rel.relationship.revname
results += rel_aliases
return list(set(results))

View file

@ -1,166 +0,0 @@
# Copyright The IETF Trust 2007, All Rights Reserved
import codecs
import re
import os.path
from django.http import HttpResponseRedirect, Http404
from django.shortcuts import render_to_response as render
from django.template import RequestContext
from django.conf import settings
from django.db.models import Q
from ietf.ipr.models import IprDocAlias, IprDetail
from ietf.ipr.related import related_docs
from ietf.utils.draft_search import normalize_draftname
from ietf.group.models import Group
from ietf.doc.models import DocAlias
def iprs_from_docs(docs):
iprs = []
for doc in docs:
disclosures = [ x.ipr for x in IprDocAlias.objects.filter(doc_alias=doc, ipr__status__in=[1,3]) ]
doc.iprs = None
if disclosures:
doc.iprs = disclosures
iprs += disclosures
iprs = list(set(iprs))
return iprs, docs
def patent_file_search(url, q):
if url:
fname = url.split("/")[-1]
fpath = os.path.join(settings.IPR_DOCUMENT_PATH, fname)
#print "*** Checking file", fpath
if os.path.isfile(fpath):
#print "*** Found file", fpath
file = codecs.open(fpath, mode='r', encoding='utf-8', errors='replace')
text = file.read()
file.close()
return q in text
return False
def search(request):
wgs = Group.objects.filter(Q(type="wg") | Q(type="rg")).select_related().order_by("acronym")
search_type = request.GET.get("option")
if search_type:
docid = request.GET.get("id") or request.GET.get("id_document_tag") or ""
q = ""
for key, value in request.GET.items():
if key.endswith("search"):
q = value
if search_type and (q or docid):
# Search by RFC number or draft-identifier
# Document list with IPRs
if search_type in ["document_search", "rfc_search"]:
doc = q
if docid:
start = DocAlias.objects.filter(name=docid)
else:
if search_type == "document_search":
q = normalize_draftname(q)
start = DocAlias.objects.filter(name__contains=q, name__startswith="draft")
elif search_type == "rfc_search":
start = DocAlias.objects.filter(name="rfc%s" % q.lstrip("0"))
if len(start) == 1:
first = start[0]
doc = str(first)
docs = related_docs(first)
iprs, docs = iprs_from_docs(docs)
iprs.sort(key=lambda x: (x.submitted_date, x.ipr_id))
return render("ipr/search_doc_result.html", {"q": q, "iprs": iprs, "docs": docs, "doc": doc },
context_instance=RequestContext(request) )
elif start:
return render("ipr/search_doc_list.html", {"q": q, "docs": start },
context_instance=RequestContext(request) )
else:
return render("ipr/search_doc_result.html", {"q": q, "iprs": {}, "docs": {}, "doc": doc },
context_instance=RequestContext(request) )
# Search by legal name
# IPR list with documents
elif search_type == "patent_search":
iprs = IprDetail.objects.filter(legal_name__icontains=q, status__in=[1,3]).order_by("-submitted_date", "-ipr_id")
count = len(iprs)
iprs = [ ipr for ipr in iprs if not ipr.updated_by.all() ]
return render("ipr/search_holder_result.html", {"q": q, "iprs": iprs, "count": count },
context_instance=RequestContext(request) )
# Search by patents field or content of emails for patent numbers
# IPR list with documents
elif search_type == "patent_info_search":
if len(q) < 3:
return render("ipr/search_error.html", {"q": q, "error": "The search string must contain at least three characters" },
context_instance=RequestContext(request) )
digits = re.search("[0-9]", q)
if not digits:
return render("ipr/search_error.html", {"q": q, "error": "The search string must contain at least one digit" },
context_instance=RequestContext(request) )
iprs = []
for ipr in IprDetail.objects.filter(status__in=[1,3]):
if ((q in ipr.patents) |
patent_file_search(ipr.legacy_url_0, q) |
patent_file_search(ipr.legacy_url_1, q) |
patent_file_search(ipr.legacy_url_2, q) ):
iprs.append(ipr)
count = len(iprs)
iprs = [ ipr for ipr in iprs if not ipr.updated_by.all() ]
iprs.sort(key=lambda x: x.ipr_id, reverse=True)
return render("ipr/search_patent_result.html", {"q": q, "iprs": iprs, "count": count },
context_instance=RequestContext(request) )
# Search by wg acronym
# Document list with IPRs
elif search_type == "wg_search":
docs = list(DocAlias.objects.filter(document__group__acronym=q))
related = []
for doc in docs:
doc.product_of_this_wg = True
related += related_docs(doc)
iprs, docs = iprs_from_docs(list(set(docs+related)))
docs = [ doc for doc in docs if doc.iprs ]
docs = sorted(docs,key=lambda x: max([ipr.submitted_date for ipr in x.iprs]),reverse=True)
count = len(iprs)
return render("ipr/search_wg_result.html", {"q": q, "docs": docs, "count": count },
context_instance=RequestContext(request) )
# Search by rfc and id title
# Document list with IPRs
elif search_type == "title_search":
docs = list(DocAlias.objects.filter(document__title__icontains=q))
related = []
for doc in docs:
related += related_docs(doc)
iprs, docs = iprs_from_docs(list(set(docs+related)))
docs = [ doc for doc in docs if doc.iprs ]
docs = sorted(docs,key=lambda x: max([ipr.submitted_date for ipr in x.iprs]),reverse=True)
count = len(iprs)
return render("ipr/search_doctitle_result.html", {"q": q, "docs": docs, "count": count },
context_instance=RequestContext(request) )
# Search by title of IPR disclosure
# IPR list with documents
elif search_type == "ipr_title_search":
iprs = IprDetail.objects.filter(title__icontains=q, status__in=[1,3]).order_by("-submitted_date", "-ipr_id")
count = iprs.count()
iprs = [ ipr for ipr in iprs if not ipr.updated_by.all() ]
return render("ipr/search_iprtitle_result.html", {"q": q, "iprs": iprs, "count": count },
context_instance=RequestContext(request) )
else:
raise Http404("Unexpected search type in IPR query: %s" % search_type)
return HttpResponseRedirect(request.path)
return render("ipr/search.html", {"wgs": wgs}, context_instance=RequestContext(request))

View file

@ -1,11 +1,11 @@
# Copyright The IETF Trust 2007, All Rights Reserved
#
from django.contrib.sitemaps import GenericSitemap
from ietf.ipr.models import IprDetail
from ietf.ipr.models import IprDisclosureBase
# changefreq is "never except when it gets updated or withdrawn"
# so skip giving one
queryset = IprDetail.objects.filter(status__in=[1,3])
archive = {'queryset':queryset, 'date_field': 'submitted_date', 'allow_empty':True }
queryset = IprDisclosureBase.objects.filter(state__in=('posted','removed'))
archive = {'queryset':queryset, 'date_field': 'time', 'allow_empty':True }
IPRMap = GenericSitemap(archive)

View file

View file

@ -0,0 +1,38 @@
# Copyright The IETF Trust 2014, All Rights Reserved
from django import template
from django.utils.safestring import mark_safe
register = template.Library()
# @register.filter
# def first_type(queryset, type):
# first = queryset.filter(type_id=type).first()
# return first.time if first else None
@register.filter
def render_message_for_history(msg):
"""Format message for display in history. Suppress the 'To' line for incoming responses
"""
if msg.to.startswith('ietf-ipr+'):
text = u'''Date: {}
From: {}
Subject: {}
Cc: {}
<pre>{}</pre>'''.format(msg.time,msg.frm,msg.subject,msg.cc,msg.body)
else:
text = u'''Date: {}
From: {}
To: {}
Subject: {}
Cc: {}
<pre>{}</pre>'''.format(msg.time,msg.frm,msg.to,msg.subject,msg.cc,msg.body)
return mark_safe(text)
@register.filter
def to_class_name(value):
return value.__class__.__name__

View file

@ -1,5 +1,4 @@
import os
import shutil
import datetime
import urllib
from pyquery import PyQuery
@ -8,42 +7,147 @@ from django.conf import settings
from django.core.urlresolvers import reverse as urlreverse
from ietf.doc.models import DocAlias
from ietf.ipr.models import IprDetail
from ietf.ipr.mail import (process_response_email, get_reply_to, get_update_submitter_emails,
get_pseudo_submitter, get_holders, get_update_cc_addrs)
from ietf.ipr.models import (IprDisclosureBase,GenericIprDisclosure,HolderIprDisclosure,
ThirdPartyIprDisclosure,RelatedIpr)
from ietf.ipr.utils import get_genitive, get_ipr_summary
from ietf.message.models import Message
from ietf.utils.test_utils import TestCase
from ietf.utils.test_data import make_test_data
class IprTests(TestCase):
def setUp(self):
# for patent number search
self.ipr_dir = os.path.abspath("tmp-ipr-dir")
if not os.path.exists(self.ipr_dir):
os.mkdir(self.ipr_dir)
settings.IPR_DOCUMENT_PATH = self.ipr_dir
pass
def tearDown(self):
shutil.rmtree(self.ipr_dir)
pass
def test_overview(self):
def test_get_genitive(self):
self.assertEqual(get_genitive("Cisco"),"Cisco's")
self.assertEqual(get_genitive("Ross"),"Ross'")
def test_get_holders(self):
make_test_data()
ipr = IprDetail.objects.get(title="Statement regarding rights")
ipr = IprDisclosureBase.objects.get(title='Statement regarding rights')
update = HolderIprDisclosure.objects.create(
by_id=1,
title="Statement regarding rights Update",
holder_legal_name="Native Martians United",
state_id='pending',
patent_info='US12345',
holder_contact_name='Update Holder',
holder_contact_email='update_holder@acme.com',
licensing_id='royalty-free',
submitter_name='George',
submitter_email='george@acme.com',
)
RelatedIpr.objects.create(target=ipr,source=update,relationship_id='updates')
result = get_holders(update)
self.assertEqual(result,['update_holder@acme.com','george@acme.com'])
def test_get_ipr_summary(self):
make_test_data()
ipr = IprDisclosureBase.objects.get(title='Statement regarding rights')
self.assertEqual(get_ipr_summary(ipr),'draft-ietf-mars-test')
def test_get_pseudo_submitter(self):
make_test_data()
ipr = IprDisclosureBase.objects.get(title='Statement regarding rights').get_child()
self.assertEqual(get_pseudo_submitter(ipr),(ipr.submitter_name,ipr.submitter_email))
ipr.submitter_name=''
ipr.submitter_email=''
self.assertEqual(get_pseudo_submitter(ipr),(ipr.holder_contact_name,ipr.holder_contact_email))
ipr.holder_contact_name=''
ipr.holder_contact_email=''
self.assertEqual(get_pseudo_submitter(ipr),('UNKNOWN NAME - NEED ASSISTANCE HERE','UNKNOWN EMAIL - NEED ASSISTANCE HERE'))
def test_get_update_cc_addrs(self):
make_test_data()
ipr = IprDisclosureBase.objects.get(title='Statement regarding rights')
update = HolderIprDisclosure.objects.create(
by_id=1,
title="Statement regarding rights Update",
holder_legal_name="Native Martians United",
state_id='pending',
patent_info='US12345',
holder_contact_name='Update Holder',
holder_contact_email='update_holder@acme.com',
licensing_id='royalty-free',
submitter_name='George',
submitter_email='george@acme.com',
)
RelatedIpr.objects.create(target=ipr,source=update,relationship_id='updates')
result = get_update_cc_addrs(update)
self.assertEqual(result,'update_holder@acme.com,george@acme.com')
def test_get_update_submitter_emails(self):
make_test_data()
ipr = IprDisclosureBase.objects.get(title='Statement regarding rights').get_child()
update = HolderIprDisclosure.objects.create(
by_id=1,
title="Statement regarding rights Update",
holder_legal_name="Native Martians United",
state_id='pending',
patent_info='US12345',
holder_contact_name='George',
holder_contact_email='george@acme.com',
licensing_id='royalty-free',
submitter_name='George',
submitter_email='george@acme.com',
)
RelatedIpr.objects.create(target=ipr,source=update,relationship_id='updates')
messages = get_update_submitter_emails(update)
self.assertEqual(len(messages),1)
self.assertTrue(messages[0].startswith('To: george@acme.com'))
def test_showlist(self):
make_test_data()
ipr = IprDisclosureBase.objects.get(title='Statement regarding rights')
r = self.client.get(urlreverse("ipr_showlist"))
self.assertEqual(r.status_code, 200)
self.assertTrue(ipr.title in r.content)
def test_ipr_details(self):
def test_show_posted(self):
make_test_data()
ipr = IprDetail.objects.get(title="Statement regarding rights")
r = self.client.get(urlreverse("ipr_show", kwargs=dict(ipr_id=ipr.pk)))
ipr = IprDisclosureBase.objects.get(title='Statement regarding rights')
r = self.client.get(urlreverse("ipr_show", kwargs=dict(id=ipr.pk)))
self.assertEqual(r.status_code, 200)
self.assertTrue(ipr.title in r.content)
def test_show_parked(self):
make_test_data()
ipr = IprDisclosureBase.objects.get(title='Statement regarding rights')
ipr.set_state('parked')
r = self.client.get(urlreverse("ipr_show", kwargs=dict(id=ipr.pk)))
self.assertEqual(r.status_code, 404)
def test_show_pending(self):
make_test_data()
ipr = IprDisclosureBase.objects.get(title='Statement regarding rights')
ipr.set_state('pending')
r = self.client.get(urlreverse("ipr_show", kwargs=dict(id=ipr.pk)))
self.assertEqual(r.status_code, 404)
def test_show_rejected(self):
make_test_data()
ipr = IprDisclosureBase.objects.get(title='Statement regarding rights')
ipr.set_state('rejected')
r = self.client.get(urlreverse("ipr_show", kwargs=dict(id=ipr.pk)))
self.assertEqual(r.status_code, 404)
def test_show_removed(self):
make_test_data()
ipr = IprDisclosureBase.objects.get(title='Statement regarding rights')
ipr.set_state('removed')
r = self.client.get(urlreverse("ipr_show", kwargs=dict(id=ipr.pk)))
self.assertEqual(r.status_code, 200)
self.assertTrue('This IPR disclosure was removed' in r.content)
def test_iprs_for_drafts(self):
draft = make_test_data()
ipr = IprDetail.objects.get(title="Statement regarding rights")
ipr = IprDisclosureBase.objects.get(title='Statement regarding rights')
r = self.client.get(urlreverse("ietf.ipr.views.iprs_for_drafts_txt"))
self.assertEqual(r.status_code, 200)
self.assertTrue(draft.name in r.content)
@ -56,27 +160,27 @@ class IprTests(TestCase):
def test_search(self):
draft = make_test_data()
ipr = IprDetail.objects.get(title="Statement regarding rights")
ipr = IprDisclosureBase.objects.get(title="Statement regarding rights").get_child()
url = urlreverse("ipr_search")
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
q = PyQuery(r.content)
self.assertTrue(q("form input[name=document_search]"))
self.assertTrue(q("form input[name=draft]"))
# find by id
r = self.client.get(url + "?option=document_search&id=%s" % draft.name)
r = self.client.get(url + "?submit=draft&id=%s" % draft.name)
self.assertEqual(r.status_code, 200)
self.assertTrue(ipr.title in r.content)
# find draft
r = self.client.get(url + "?option=document_search&document_search=%s" % draft.name)
r = self.client.get(url + "?submit=draft&draft=%s" % draft.name)
self.assertEqual(r.status_code, 200)
self.assertTrue(ipr.title in r.content)
# search + select document
r = self.client.get(url + "?option=document_search&document_search=draft")
r = self.client.get(url + "?submit=draft&draft=draft")
self.assertEqual(r.status_code, 200)
self.assertTrue(draft.name in r.content)
self.assertTrue(ipr.title not in r.content)
@ -84,77 +188,62 @@ class IprTests(TestCase):
DocAlias.objects.create(name="rfc321", document=draft)
# find RFC
r = self.client.get(url + "?option=rfc_search&rfc_search=321")
r = self.client.get(url + "?submit=rfc&rfc=321")
self.assertEqual(r.status_code, 200)
self.assertTrue(ipr.title in r.content)
# find by patent owner
r = self.client.get(url + "?option=patent_search&patent_search=%s" % ipr.legal_name)
r = self.client.get(url + "?submit=holder&holder=%s" % ipr.holder_legal_name)
self.assertEqual(r.status_code, 200)
self.assertTrue(ipr.title in r.content)
# find by patent info
r = self.client.get(url + "?option=patent_info_search&patent_info_search=%s" % ipr.patents)
r = self.client.get(url + "?submit=patent&patent=%s" % ipr.patent_info)
self.assertEqual(r.status_code, 200)
self.assertTrue(ipr.title in r.content)
# find by patent info in file
filename = "ipr1.txt"
with open(os.path.join(self.ipr_dir, filename), "w") as f:
f.write("Hello world\nPTO9876")
ipr.legacy_url_0 = "/hello/world/%s" % filename
ipr.save()
r = self.client.get(url + "?option=patent_info_search&patent_info_search=PTO9876")
r = self.client.get(url + "?submit=patent&patent=US12345")
self.assertEqual(r.status_code, 200)
self.assertTrue(ipr.title in r.content)
# must search for at least 3 characters with digit
r = self.client.get(url + "?option=patent_info_search&patent_info_search=a")
self.assertTrue("ipr search result error" in r.content.lower())
r = self.client.get(url + "?option=patent_info_search&patent_info_search=aaa")
self.assertTrue("ipr search result error" in r.content.lower())
# find by group acronym
r = self.client.get(url + "?option=wg_search&wg_search=%s" % draft.group.acronym)
r = self.client.get(url + "?submit=group&group=%s" % draft.group.pk)
self.assertEqual(r.status_code, 200)
self.assertTrue(ipr.title in r.content)
# find by doc title
r = self.client.get(url + "?option=title_search&title_search=%s" % urllib.quote(draft.title))
r = self.client.get(url + "?submit=doctitle&doctitle=%s" % urllib.quote(draft.title))
self.assertEqual(r.status_code, 200)
self.assertTrue(ipr.title in r.content)
# find by ipr title
r = self.client.get(url + "?option=ipr_title_search&ipr_title_search=%s" % urllib.quote(ipr.title))
r = self.client.get(url + "?submit=iprtitle&iprtitle=%s" % urllib.quote(ipr.title))
self.assertEqual(r.status_code, 200)
self.assertTrue(ipr.title in r.content)
def test_feed(self):
make_test_data()
ipr = IprDetail.objects.get(title="Statement regarding rights")
ipr = IprDisclosureBase.objects.get(title='Statement regarding rights')
r = self.client.get("/feed/ipr/")
self.assertEqual(r.status_code, 200)
self.assertTrue(ipr.title in r.content)
def test_sitemap(self):
make_test_data()
ipr = IprDetail.objects.get(title="Statement regarding rights")
ipr = IprDisclosureBase.objects.get(title='Statement regarding rights')
r = self.client.get("/sitemap-ipr.xml")
self.assertEqual(r.status_code, 200)
self.assertTrue("/ipr/%s/" % ipr.pk in r.content)
def test_new_generic(self):
"""Add a new generic disclosure. Note: submitter does not need to be logged in.
"""
make_test_data()
url = urlreverse("ietf.ipr.views.new", kwargs={ "type": "generic" })
url = urlreverse("ietf.ipr.new.new", kwargs={ "type": "generic" })
# faulty post
# invalid post
r = self.client.post(url, {
"legal_name": "Test Legal",
"holder_legal_name": "Test Legal",
})
self.assertEqual(r.status_code, 200)
q = PyQuery(r.content)
@ -162,128 +251,271 @@ class IprTests(TestCase):
# successful post
r = self.client.post(url, {
"legal_name": "Test Legal",
"hold_name": "Test Holder",
"hold_telephone": "555-555-0100",
"hold_email": "test.holder@example.com",
"ietf_name": "Test Participant",
"ietf_telephone": "555-555-0101",
"ietf_email": "test.participant@example.com",
"patents": "none",
"date_applied": "never",
"country": "nowhere",
"licensing_option": "5",
"subm_name": "Test Submitter",
"subm_telephone": "555-555-0102",
"subm_email": "test.submitter@example.com"
"holder_legal_name": "Test Legal",
"holder_contact_name": "Test Holder",
"holder_contact_email": "test@holder.com",
"holder_contact_info": "555-555-0100",
"submitter_name": "Test Holder",
"submitter_email": "test@holder.com",
"notes": "some notes"
})
self.assertEqual(r.status_code, 200)
self.assertTrue("Your IPR disclosure has been submitted" in r.content)
iprs = IprDetail.objects.filter(title__icontains="General License Statement")
iprs = IprDisclosureBase.objects.filter(title__icontains="General License Statement")
self.assertEqual(len(iprs), 1)
ipr = iprs[0]
self.assertEqual(ipr.legal_name, "Test Legal")
self.assertEqual(ipr.status, 0)
self.assertEqual(ipr.holder_legal_name, "Test Legal")
self.assertEqual(ipr.state.slug, 'pending')
self.assertTrue(isinstance(ipr.get_child(),GenericIprDisclosure))
def test_new_specific(self):
"""Add a new specific disclosure. Note: submitter does not need to be logged in.
"""
draft = make_test_data()
url = urlreverse("ietf.ipr.new.new", kwargs={ "type": "specific" })
url = urlreverse("ietf.ipr.views.new", kwargs={ "type": "specific" })
# successful post
r = self.client.post(url, {
"legal_name": "Test Legal",
"hold_name": "Test Holder",
"hold_telephone": "555-555-0100",
"hold_email": "test.holder@example.com",
"ietf_name": "Test Participant",
"ietf_telephone": "555-555-0101",
"ietf_email": "test.participant@example.com",
"rfclist": DocAlias.objects.filter(name__startswith="rfc")[0].name[3:],
"draftlist": "%s-%s" % (draft.name, draft.rev),
"patents": "none",
"date_applied": "never",
"country": "nowhere",
"licensing_option": "5",
"subm_name": "Test Submitter",
"subm_telephone": "555-555-0102",
"subm_email": "test.submitter@example.com"
"holder_legal_name": "Test Legal",
"holder_contact_name": "Test Holder",
"holder_contact_email": "test@holder.com",
"holder_contact_info": "555-555-0100",
"ietfer_name": "Test Participant",
"ietfer_contact_info": "555-555-0101",
"rfc-TOTAL_FORMS": 1,
"rfc-INITIAL_FORMS": 0,
"rfc-0-document": DocAlias.objects.filter(name__startswith="rfc").first().pk,
"draft-TOTAL_FORMS": 1,
"draft-INITIAL_FORMS": 0,
"draft-0-document": "%s" % draft.docalias_set.first().pk,
"draft-0-revisions": '00',
"patent_info": "none",
"has_patent_pending": False,
"licensing": "royalty-free",
"submitter_name": "Test Holder",
"submitter_email": "test@holder.com",
})
self.assertEqual(r.status_code, 200)
# print r.content
self.assertTrue("Your IPR disclosure has been submitted" in r.content)
iprs = IprDetail.objects.filter(title__icontains=draft.name)
iprs = IprDisclosureBase.objects.filter(title__icontains=draft.name)
self.assertEqual(len(iprs), 1)
ipr = iprs[0]
self.assertEqual(ipr.legal_name, "Test Legal")
self.assertEqual(ipr.status, 0)
self.assertEqual(ipr.holder_legal_name, "Test Legal")
self.assertEqual(ipr.state.slug, 'pending')
self.assertTrue(isinstance(ipr.get_child(),HolderIprDisclosure))
def test_new_thirdparty(self):
"""Add a new third-party disclosure. Note: submitter does not need to be logged in.
"""
draft = make_test_data()
url = urlreverse("ietf.ipr.new.new", kwargs={ "type": "third-party" })
url = urlreverse("ietf.ipr.views.new", kwargs={ "type": "third-party" })
# successful post
r = self.client.post(url, {
"legal_name": "Test Legal",
"hold_name": "Test Holder",
"hold_telephone": "555-555-0100",
"hold_email": "test.holder@example.com",
"ietf_name": "Test Participant",
"ietf_telephone": "555-555-0101",
"ietf_email": "test.participant@example.com",
"rfclist": "",
"draftlist": "%s-%s" % (draft.name, draft.rev),
"patents": "none",
"date_applied": "never",
"country": "nowhere",
"licensing_option": "5",
"subm_name": "Test Submitter",
"subm_telephone": "555-555-0102",
"subm_email": "test.submitter@example.com"
"holder_legal_name": "Test Legal",
"ietfer_name": "Test Participant",
"ietfer_contact_email": "test@ietfer.com",
"ietfer_contact_info": "555-555-0101",
"rfc-TOTAL_FORMS": 1,
"rfc-INITIAL_FORMS": 0,
"rfc-0-document": DocAlias.objects.filter(name__startswith="rfc").first().pk,
"draft-TOTAL_FORMS": 1,
"draft-INITIAL_FORMS": 0,
"draft-0-document": "%s" % draft.docalias_set.first().pk,
"draft-0-revisions": '00',
"patent_info": "none",
"has_patent_pending": False,
"licensing": "royalty-free",
"submitter_name": "Test Holder",
"submitter_email": "test@holder.com",
})
self.assertEqual(r.status_code, 200)
# print r.content
self.assertTrue("Your IPR disclosure has been submitted" in r.content)
iprs = IprDetail.objects.filter(title__icontains="belonging to Test Legal")
iprs = IprDisclosureBase.objects.filter(title__icontains="belonging to Test Legal")
self.assertEqual(len(iprs), 1)
ipr = iprs[0]
self.assertEqual(ipr.legal_name, "Test Legal")
self.assertEqual(ipr.status, 0)
self.assertEqual(ipr.holder_legal_name, "Test Legal")
self.assertEqual(ipr.state.slug, "pending")
self.assertTrue(isinstance(ipr.get_child(),ThirdPartyIprDisclosure))
def test_update(self):
draft = make_test_data()
original_ipr = IprDetail.objects.get(title="Statement regarding rights")
url = urlreverse("ietf.ipr.new.update", kwargs={ "ipr_id": original_ipr.pk })
original_ipr = IprDisclosureBase.objects.get(title='Statement regarding rights')
url = urlreverse("ietf.ipr.views.new", kwargs={ "type": "specific" })
# successful post
r = self.client.post(url, {
"legal_name": "Test Legal",
"hold_name": "Test Holder",
"hold_telephone": "555-555-0100",
"hold_email": "test.holder@example.com",
"ietf_name": "Test Participant",
"ietf_telephone": "555-555-0101",
"ietf_email": "test.participant@example.com",
"rfclist": "",
"draftlist": "%s-%s" % (draft.name, draft.rev),
"patents": "none",
"date_applied": "never",
"country": "nowhere",
"licensing_option": "5",
"subm_name": "Test Submitter",
"subm_telephone": "555-555-0102",
"subm_email": "test.submitter@example.com"
"updates": str(original_ipr.pk),
"holder_legal_name": "Test Legal",
"holder_contact_name": "Test Holder",
"holder_contact_email": "test@holder.com",
"holder_contact_info": "555-555-0100",
"ietfer_name": "Test Participant",
"ietfer_contact_info": "555-555-0101",
"rfc-TOTAL_FORMS": 1,
"rfc-INITIAL_FORMS": 0,
"rfc-0-document": DocAlias.objects.filter(name__startswith="rfc").first().pk,
"draft-TOTAL_FORMS": 1,
"draft-INITIAL_FORMS": 0,
"draft-0-document": "%s" % draft.docalias_set.first().pk,
"draft-0-revisions": '00',
"patent_info": "none",
"has_patent_pending": False,
"licensing": "royalty-free",
"submitter_name": "Test Holder",
"submitter_email": "test@holder.com",
})
self.assertEqual(r.status_code, 200)
self.assertTrue("Your IPR disclosure has been submitted" in r.content)
iprs = IprDetail.objects.filter(title__icontains=draft.name)
iprs = IprDisclosureBase.objects.filter(title__icontains=draft.name)
self.assertEqual(len(iprs), 1)
ipr = iprs[0]
self.assertEqual(ipr.legal_name, "Test Legal")
self.assertEqual(ipr.status, 0)
self.assertEqual(ipr.holder_legal_name, "Test Legal")
self.assertEqual(ipr.state.slug, 'pending')
self.assertTrue(ipr.updates.filter(updated=original_ipr))
self.assertTrue(ipr.relatedipr_source_set.filter(target=original_ipr))
def test_addcomment(self):
make_test_data()
ipr = IprDisclosureBase.objects.get(title='Statement regarding rights')
url = urlreverse("ipr_add_comment", kwargs={ "id": ipr.id })
self.client.login(username="secretary", password="secretary+password")
r = self.client.get(url)
self.assertEqual(r.status_code,200)
# public comment
comment = 'Test comment'
r = self.client.post(url, dict(comment=comment))
self.assertEqual(r.status_code,302)
qs = ipr.iprevent_set.filter(type='comment',desc=comment)
self.assertTrue(qs.count(),1)
# private comment
r = self.client.post(url, dict(comment='Private comment',private=True),follow=True)
self.assertEqual(r.status_code,200)
self.assertTrue('Private comment' in r.content)
self.client.logout()
r = self.client.get(url)
self.assertFalse('Private comment' in r.content)
def test_addemail(self):
make_test_data()
ipr = IprDisclosureBase.objects.get(title='Statement regarding rights')
url = urlreverse("ipr_add_email", kwargs={ "id": ipr.id })
self.client.login(username="secretary", password="secretary+password")
r = self.client.get(url)
self.assertEqual(r.status_code,200)
# post
r = self.client.post(url, {
"direction": 'incoming',
"message": """From: test@acme.com
To: ietf-ipr@ietf.org
Subject: RE: The Cisco Statement
Date: Wed, 24 Sep 2014 14:25:02 -0700
Hello,
I would like to revoke this declaration.
"""})
msg = Message.objects.get(frm='test@acme.com')
qs = ipr.iprevent_set.filter(type='msgin',message=msg)
self.assertTrue(qs.count(),1)
def test_admin_pending(self):
make_test_data()
url = urlreverse("ipr_admin",kwargs={'state':'pending'})
self.client.login(username="secretary", password="secretary+password")
# test for presence of pending ipr
ipr = IprDisclosureBase.objects.first()
ipr.state_id = 'pending'
ipr.save()
num = IprDisclosureBase.objects.filter(state='pending').count()
r = self.client.get(url)
self.assertEqual(r.status_code,200)
q = PyQuery(r.content)
x = len(q('table#pending-iprs tr')) - 1 # minus header
self.assertEqual(num,x)
def test_admin_removed(self):
make_test_data()
url = urlreverse("ipr_admin",kwargs={'state':'removed'})
self.client.login(username="secretary", password="secretary+password")
# test for presence of pending ipr
ipr = IprDisclosureBase.objects.first()
ipr.state_id = 'removed'
ipr.save()
num = IprDisclosureBase.objects.filter(state__in=('removed','rejected')).count()
r = self.client.get(url)
self.assertEqual(r.status_code,200)
q = PyQuery(r.content)
x = len(q('table#removed-iprs tr')) - 1 # minus header
self.assertEqual(num,x)
def test_admin_parked(self):
pass
def test_post(self):
make_test_data()
ipr = IprDisclosureBase.objects.get(title='Statement regarding rights')
url = urlreverse("ipr_post",kwargs={ "id": ipr.id })
# fail if not logged in
r = self.client.get(url,follow=True)
self.assertTrue("Sign In" in r.content)
# successful post
self.client.login(username="secretary", password="secretary+password")
r = self.client.get(url,follow=True)
self.assertEqual(r.status_code,200)
ipr = IprDisclosureBase.objects.get(title='Statement regarding rights')
self.assertEqual(ipr.state.slug,'posted')
def test_process_response_email(self):
# first send a mail
make_test_data()
ipr = IprDisclosureBase.objects.get(title='Statement regarding rights')
url = urlreverse("ipr_email",kwargs={ "id": ipr.id })
self.client.login(username="secretary", password="secretary+password")
yesterday = datetime.date.today() - datetime.timedelta(1)
data = dict(
to='joe@test.com',
frm='ietf-ipr@ietf.org',
subject='test',
reply_to=get_reply_to(),
body='Testing.',
response_due=yesterday.isoformat())
r = self.client.post(url,data,follow=True)
#print r.content
self.assertEqual(r.status_code,200)
q = Message.objects.filter(reply_to=data['reply_to'])
self.assertEqual(q.count(),1)
event = q[0].msgevents.first()
self.assertTrue(event.response_past_due())
# test process response uninteresting message
message_string = """To: {}
From: joe@test.com
Date: {}
Subject: test
""".format(settings.IPR_EMAIL_TO,datetime.datetime.now().ctime())
result = process_response_email(message_string)
self.assertIsNone(result)
# test process response
message_string = """To: {}
From: joe@test.com
Date: {}
Subject: test
""".format(data['reply_to'],datetime.datetime.now().ctime())
result = process_response_email(message_string)
self.assertIsInstance(result,Message)
self.assertFalse(event.response_past_due())

View file

@ -4,17 +4,26 @@ from django.conf.urls import patterns, url
from django.views.generic import RedirectView
from django.core.urlresolvers import reverse_lazy
from ietf.ipr import views, new, search
urlpatterns = patterns('',
url(r'^$', views.showlist, name='ipr_showlist'),
(r'^about/$', views.about),
(r'^by-draft/$', views.iprs_for_drafts_txt),
url(r'^(?P<ipr_id>\d+)/$', views.show, name='ipr_show'),
urlpatterns = patterns('ietf.ipr.views',
url(r'^$', 'showlist', name='ipr_showlist'),
(r'^about/$', 'about'),
url(r'^admin/$', RedirectView.as_view(url=reverse_lazy('ipr_admin',kwargs={'state':'pending'})),name="ipr_admin_main"),
url(r'^admin/(?P<state>pending|removed|parked)/$', 'admin', name='ipr_admin'),
url(r'^ajax/search/$', 'ajax_search', name='ipr_ajax_search'),
url(r'^ajax/draft-search/$', 'ajax_draft_search', name='ipr_ajax_draft_search'),
url(r'^ajax/rfc-search/$', 'ajax_rfc_search', name='ipr_ajax_rfc_search'),
(r'^by-draft/$', 'iprs_for_drafts_txt'),
url(r'^(?P<id>\d+)/$', 'show', name='ipr_show'),
url(r'^(?P<id>\d+)/addcomment/$', 'add_comment', name='ipr_add_comment'),
url(r'^(?P<id>\d+)/addemail/$', 'add_email', name='ipr_add_email'),
url(r'^(?P<id>\d+)/edit/$', 'edit', name='ipr_edit'),
url(r'^(?P<id>\d+)/email/$', 'email', name='ipr_email'),
url(r'^(?P<id>\d+)/history/$', 'history', name='ipr_history'),
url(r'^(?P<id>\d+)/notify/(?P<type>update|posted)/$', 'notify', name='ipr_notify'),
url(r'^(?P<id>\d+)/post/$', 'post', name='ipr_post'),
url(r'^(?P<id>\d+)/state/$', 'state', name='ipr_state'),
(r'^update/$', RedirectView.as_view(url=reverse_lazy('ipr_showlist'))),
(r'^update/(?P<ipr_id>\d+)/$', new.update),
(r'^new-(?P<type>specific)/$', new.new),
(r'^new-(?P<type>generic)/$', new.new),
(r'^new-(?P<type>third-party)/$', new.new),
url(r'^search/$', search.search, name="ipr_search"),
url(r'^update/(?P<id>\d+)/$', 'update', name='ipr_update'),
url(r'^new-(?P<type>(specific|generic|third-party))/$', 'new', name='ipr_new'),
url(r'^search/$', 'search', name="ipr_search"),
)

45
ietf/ipr/utils.py Normal file
View file

@ -0,0 +1,45 @@
def get_genitive(name):
"""Return the genitive form of name"""
return name + "'" if name.endswith('s') else name + "'s"
def get_ipr_summary(disclosure):
"""Return IPR related document names as a formatted string"""
names = []
for doc in disclosure.docs.all():
if doc.name.startswith('rfc'):
names.append('RFC {}'.format(doc.name[3:]))
else:
names.append(doc.name)
if disclosure.other_designations:
names.append(disclosure.other_designations)
if len(names) == 1:
return names[0]
elif len(names) == 2:
return " and ".join(names)
elif len(names) > 2:
return ", ".join(names[:-1]) + ", and " + names[-1]
def iprs_from_docs(aliases,**kwargs):
"""Returns a list of IPRs related to doc aliases"""
iprdocrels = []
for alias in aliases:
if alias.document.ipr(**kwargs):
iprdocrels += alias.document.ipr(**kwargs)
return list(set([i.disclosure for i in iprdocrels]))
def related_docs(alias):
"""Returns list of related documents"""
results = list(alias.document.docalias_set.all())
rels = alias.document.all_relations_that_doc(['replaces','obs'])
for rel in rels:
rel_aliases = list(rel.target.document.docalias_set.all())
for x in rel_aliases:
x.related = rel
x.relation = rel.relationship.revname
results += rel_aliases
return list(set(results))

View file

@ -1,51 +0,0 @@
# Copyright The IETF Trust 2007, All Rights Reserved
section_table = {
"specific": { "title": True,
"specific": 1, "generic": 0, "third_party": 0,
"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,
"disclosure_type": "Specific IPR Disclosures", "form_legend": False,
"per_rfc_disclosure": True, "also_specific": False,
},
"generic": { "title": True,
"specific": 0, "generic": 1, "third_party": 0,
"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,
"disclosure_type": "Generic IPR Disclosures", "form_legend": False,
"per_rfc_disclosure": False, "also_specific": True,
},
"third-party": {"title": True,
"specific": 0, "generic": 0, "third_party": 1,
"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,
"disclosure_type": "Notification", "form_legend": False,
"per_rfc_disclosure": False, "also_specific": False,
},
"legacy": { "title": True, "legacy": 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,
"disclosure_type": "Legacy", "form_legend": False,
"per_rfc_disclosure": False, "also_specific": False,
},
}
def section_list_for_ipr(ipr):
if ipr.legacy_url_0:
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"]

View file

@ -1,99 +1,834 @@
# Copyright The IETF Trust 2007, All Rights Reserved
import os
import datetime
import itertools
from django.shortcuts import render_to_response as render, get_object_or_404
from django.template import RequestContext
from django.http import HttpResponse, Http404
from django.conf import settings
from django.contrib import messages
from django.core.urlresolvers import reverse as urlreverse
from django.db.models import Q
from django.forms.models import inlineformset_factory
from django.forms.formsets import formset_factory
from django.http import HttpResponse, Http404, HttpResponseRedirect
from django.shortcuts import render_to_response as render, get_object_or_404, redirect
from django.template import RequestContext
from django.template.loader import render_to_string
from ietf.ipr.models import IprDetail, IprDocAlias, SELECT_CHOICES, LICENSE_CHOICES
from ietf.ipr.view_sections import section_list_for_ipr
from ietf.doc.models import DocAlias
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,
get_update_cc_addrs)
from ietf.ipr.fields import tokeninput_id_name_json
from ietf.ipr.forms import (HolderIprDisclosureForm, GenericDisclosureForm,
ThirdPartyIprDisclosureForm, DraftForm, RfcForm, SearchForm, MessageModelForm,
AddCommentForm, AddEmailForm, NotifyForm, StateForm, NonDocSpecificIprDisclosureForm,
GenericIprDisclosureForm)
from ietf.ipr.models import (IprDisclosureStateName, IprDisclosureBase,
HolderIprDisclosure, GenericIprDisclosure, ThirdPartyIprDisclosure,
NonDocSpecificIprDisclosure, IprDocRel,
RelatedIpr,IprEvent)
from ietf.ipr.utils import (get_genitive, get_ipr_summary,
iprs_from_docs, related_docs)
from ietf.message.models import Message
from ietf.message.utils import infer_message
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
# ----------------------------------------------------------------
# Globals
# ----------------------------------------------------------------
# maps string type or ipr model class to corresponding edit form
ipr_form_mapping = { 'specific':HolderIprDisclosureForm,
'generic':GenericDisclosureForm,
'third-party':ThirdPartyIprDisclosureForm,
'HolderIprDisclosure':HolderIprDisclosureForm,
'GenericIprDisclosure':GenericIprDisclosureForm,
'ThirdPartyIprDisclosure':ThirdPartyIprDisclosureForm,
'NonDocSpecificIprDisclosure':NonDocSpecificIprDisclosureForm }
class_to_type = { 'HolderIprDisclosure':'specific',
'GenericIprDisclosure':'generic',
'ThirdPartyIprDisclosure':'third-party',
'NonDocSpecificIprDisclosure':'generic' }
# ----------------------------------------------------------------
# Helper Functions
# ----------------------------------------------------------------
def get_document_emails(ipr):
"""Returns a list of messages to inform document authors that a new IPR disclosure
has been posted"""
messages = []
for rel in ipr.iprdocrel_set.all():
doc = rel.document.document
authors = doc.authors.all()
if is_draft(doc):
doc_info = 'Internet-Draft entitled "{}" ({})'.format(doc.title,doc.name)
else:
doc_info = 'RFC entitled "{}" (RFC{})'.format(doc.title,get_rfc_num(doc))
# build cc list
if doc.group.acronym == 'none':
if doc.ad and is_draft(doc):
cc_list = doc.ad.role_email('ad').address
else:
role = Role.objects.filter(group__acronym='gen',name='ad')[0]
cc_list = role.email.address
else:
cc_list = get_wg_email_list(doc.group)
author_emails = ','.join([a.address for a in authors])
author_names = ', '.join([a.person.name for a in authors])
cc_list += ", ipr-announce@ietf.org"
context = dict(
doc_info=doc_info,
to_email=author_emails,
to_name=author_names,
cc_email=cc_list,
ipr=ipr)
text = render_to_string('ipr/posted_document_email.txt',context)
messages.append(text)
return messages
def get_posted_emails(ipr):
"""Return a list of messages suitable to initialize a NotifyFormset for
the notify view when a new disclosure is posted"""
messages = []
# NOTE 1000+ legacy iprs have no submitter_email
# add submitter message
if True:
context = dict(
to_email=ipr.submitter_email,
to_name=ipr.submitter_name,
cc_email=get_update_cc_addrs(ipr),
ipr=ipr)
text = render_to_string('ipr/posted_submitter_email.txt',context)
messages.append(text)
# add email to related document authors / parties
if ipr.iprdocrel_set.all():
messages.extend(get_document_emails(ipr))
# if Generic disclosure add message for General Area AD
if isinstance(ipr, (GenericIprDisclosure,NonDocSpecificIprDisclosure)):
role = Role.objects.filter(group__acronym='gen',name='ad').first()
context = dict(
to_email=role.email.address,
to_name=role.person.name,
ipr=ipr)
text = render_to_string('ipr/posted_generic_email.txt',context)
messages.append(text)
return messages
def get_wg_email_list(group):
"""Returns a string of comman separated email addresses for the Area Directors and WG Chairs
"""
result = []
roles = itertools.chain(Role.objects.filter(group=group.parent,name='ad'),
Role.objects.filter(group=group,name='chair'))
for role in roles:
result.append(role.email.address)
if group.list_email:
result.append(group.list_email)
return ', '.join(result)
def set_disclosure_title(disclosure):
"""Set the title of the disclosure"""
if isinstance(disclosure, HolderIprDisclosure):
ipr_summary = get_ipr_summary(disclosure)
title = get_genitive(disclosure.holder_legal_name) + ' Statement about IPR related to {}'.format(ipr_summary)
elif isinstance(disclosure, (GenericIprDisclosure,NonDocSpecificIprDisclosure)):
title = get_genitive(disclosure.holder_legal_name) + ' General License Statement'
elif isinstance(disclosure, ThirdPartyIprDisclosure):
ipr_summary = get_ipr_summary(disclosure)
title = get_genitive(disclosure.ietfer_name) + ' Statement about IPR related to {} belonging to {}'.format(ipr_summary,disclosure.holder_legal_name)
# truncate for db
if len(title) > 255:
title = title[:252] + "..."
disclosure.title = title
# ----------------------------------------------------------------
# Ajax Views
# ----------------------------------------------------------------
def ajax_search(request):
q = [w.strip() for w in request.GET.get('q', '').split() if w.strip()]
if not q:
objs = IprDisclosureBase.objects.none()
else:
query = Q()
for t in q:
query &= Q(title__icontains=t)
objs = IprDisclosureBase.objects.filter(query)
objs = objs.distinct()[:10]
return HttpResponse(tokeninput_id_name_json(objs), content_type='application/json')
def ajax_draft_search(request):
q = [w.strip() for w in request.GET.get('q', '').split() if w.strip()]
if not q:
objs = DocAlias.objects.none()
else:
query = Q()
for t in q:
query &= Q(name__icontains=t)
objs = DocAlias.objects.filter(name__startswith='draft').filter(query)
objs = objs.distinct()[:10]
return HttpResponse(tokeninput_id_name_json(objs), content_type='application/json')
def ajax_rfc_search(request):
# expects one numeric term
q = [w.strip() for w in request.GET.get('q', '').split() if w.strip()]
if not q:
objs = DocAlias.objects.none()
else:
query = Q()
query &= Q(name__startswith='rfc%s' % q[0])
objs = DocAlias.objects.filter(query)
objs = objs.distinct()[:10]
return HttpResponse(tokeninput_id_name_json(objs), content_type='application/json')
# ----------------------------------------------------------------
# Views
# ----------------------------------------------------------------
def about(request):
return render("ipr/disclosure.html", {}, context_instance=RequestContext(request))
def showlist(request):
disclosures = IprDetail.objects.all().prefetch_related("updates__updated", "updated_by__ipr")
generic_disclosures = disclosures.filter(status__in=[1,3], generic=1)
specific_disclosures = disclosures.filter(status__in=[1,3], generic=0, third_party=0)
thirdpty_disclosures = disclosures.filter(status__in=[1,3], generic=0, third_party=1)
@role_required('Secretariat',)
def add_comment(request, id):
"""Add comment to disclosure history"""
ipr = get_object_or_404(IprDisclosureBase, id=id)
login = request.user.person
return render("ipr/list.html",
{
'generic_disclosures' : generic_disclosures.order_by(* ['-submitted_date', ] ),
'specific_disclosures': specific_disclosures.order_by(* ['-submitted_date', ] ),
'thirdpty_disclosures': thirdpty_disclosures.order_by(* ['-submitted_date', ] ),
}, context_instance=RequestContext(request) )
if request.method == 'POST':
form = AddCommentForm(request.POST)
if form.is_valid():
if form.cleaned_data.get('private'):
type_id = 'private_comment'
else:
type_id = 'comment'
IprEvent.objects.create(
by=login,
type_id=type_id,
disclosure=ipr,
desc=form.cleaned_data['comment']
)
messages.success(request, 'Comment added.')
return redirect("ipr_history", id=ipr.id)
else:
form = AddCommentForm()
return render('ipr/add_comment.html',dict(ipr=ipr,form=form),
context_instance=RequestContext(request))
def show(request, ipr_id=None, removed=None):
"""Show a specific IPR disclosure"""
assert ipr_id != None
ipr = get_object_or_404(IprDetail, ipr_id=ipr_id)
if ipr.status == 3 and not removed:
return render("ipr/removed.html", {"ipr": ipr},
context_instance=RequestContext(request))
if removed and ipr.status != 3:
raise Http404
if ipr.status != 1 and not removed:
raise Http404
section_list = section_list_for_ipr(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 (%s) in ipr_contacts for ipr_id=%s" % (contact.contact_type, ipr.ipr_id))
if ipr.licensing_option:
text = dict(LICENSE_CHOICES)[ipr.licensing_option]
# Very hacky way to get rid of the last part of option 'd':
cut = text.find(" (")
if cut > 0:
text = text[:cut] + "."
# get rid of the "a) ", "b) ", etc.
ipr.licensing_option = text[3:]
if ipr.is_pending:
ipr.is_pending = dict(SELECT_CHOICES)[ipr.is_pending]
if ipr.applies_to_all:
ipr.applies_to_all = dict(SELECT_CHOICES)[ipr.applies_to_all]
if ipr.legacy_url_0 and ipr.legacy_url_0.startswith("http://www.ietf.org/") and not ipr.legacy_url_0.endswith((".pdf",".doc",".html")):
try:
file = open(os.path.join(settings.IPR_DOCUMENT_PATH, os.path.basename(ipr.legacy_url_0)))
ipr.legacy_text = file.read().decode("latin-1")
file.close()
except:
# if file does not exist, iframe is used instead
pass
iprdocs = IprDocAlias.objects.filter(ipr=ipr).order_by("id").select_related("doc_alias", "doc_alias__document")
ipr.drafts = [x for x in iprdocs if not x.doc_alias.name.startswith("rfc")]
ipr.rfcs = [x for x in iprdocs if x.doc_alias.name.startswith("rfc")]
@role_required('Secretariat',)
def add_email(request, id):
"""Add email to disclosure history"""
ipr = get_object_or_404(IprDisclosureBase, id=id)
return render("ipr/details.html", {"ipr": ipr, "section_list": section_list},
context_instance=RequestContext(request))
if request.method == 'POST':
button_text = request.POST.get('submit', '')
if button_text == 'Cancel':
return redirect("ipr_history", id=ipr.id)
form = AddEmailForm(request.POST,ipr=ipr)
if form.is_valid():
message = form.cleaned_data['message']
in_reply_to = form.cleaned_data['in_reply_to']
# create Message
msg = message_from_message(message,request.user.person)
# create IprEvent
if form.cleaned_data['direction'] == 'incoming':
type_id = 'msgin'
else:
type_id = 'msgout'
IprEvent.objects.create(
type_id = type_id,
by = request.user.person,
disclosure = ipr,
message = msg,
in_reply_to = in_reply_to
)
messages.success(request, 'Email added.')
return redirect("ipr_history", id=ipr.id)
else:
form = AddEmailForm(ipr=ipr)
return render('ipr/add_email.html',dict(ipr=ipr,form=form),
context_instance=RequestContext(request))
@role_required('Secretariat',)
def admin(request,state):
"""Administrative disclosure listing. For non-posted disclosures"""
if state == 'removed':
states = ('removed','rejected')
else:
states = [state]
iprs = IprDisclosureBase.objects.filter(state__in=states).order_by('-time')
tabs = [('Pending','pending',urlreverse('ipr_admin',kwargs={'state':'pending'}),True),
('Removed','removed',urlreverse('ipr_admin',kwargs={'state':'removed'}),True),
('Parked','parked',urlreverse('ipr_admin',kwargs={'state':'parked'}),True)]
template = 'ipr/admin_' + state + '.html'
return render(template, {
'iprs': iprs,
'tabs': tabs,
'selected': state},
context_instance=RequestContext(request)
)
@role_required('Secretariat',)
def edit(request, id, updates=None):
"""Secretariat only edit disclosure view"""
ipr = get_object_or_404(IprDisclosureBase, id=id).get_child()
type = class_to_type[ipr.__class__.__name__]
# only include extra when initial formset is empty
if ipr.iprdocrel_set.filter(document__name__startswith='draft'):
draft_extra = 0
else:
draft_extra = 1
if ipr.iprdocrel_set.filter(document__name__startswith='rfc'):
rfc_extra = 0
else:
rfc_extra = 1
DraftFormset = inlineformset_factory(IprDisclosureBase, IprDocRel, form=DraftForm, can_delete=True, extra=draft_extra)
RfcFormset = inlineformset_factory(IprDisclosureBase, IprDocRel, form=RfcForm, can_delete=True, extra=rfc_extra)
if request.method == 'POST':
form = ipr_form_mapping[ipr.__class__.__name__](request.POST,instance=ipr)
if not type == 'generic':
draft_formset = DraftFormset(request.POST, instance=ipr, prefix='draft')
rfc_formset = RfcFormset(request.POST, instance=ipr, prefix='rfc')
else:
draft_formset = None
rfc_formset = None
if request.user.is_anonymous():
person = Person.objects.get(name="(System)")
else:
person = request.user.person
# check formset validity
if not type == 'generic':
valid_formsets = draft_formset.is_valid() and rfc_formset.is_valid()
else:
valid_formsets = True
if form.is_valid() and valid_formsets:
updates = form.cleaned_data.get('updates')
disclosure = form.save(commit=False)
disclosure.save()
if not type == 'generic':
# clear and recreate IprDocRels
# IprDocRel.objects.filter(disclosure=ipr).delete()
draft_formset = DraftFormset(request.POST, instance=disclosure, prefix='draft')
draft_formset.save()
rfc_formset = RfcFormset(request.POST, instance=disclosure, prefix='rfc')
rfc_formset.save()
set_disclosure_title(disclosure)
disclosure.save()
# clear and recreate IPR relationships
RelatedIpr.objects.filter(source=ipr).delete()
if updates:
for target in updates:
RelatedIpr.objects.create(source=disclosure,target=target,relationship_id='updates')
# create IprEvent
IprEvent.objects.create(
type_id='changed_disclosure',
by=person,
disclosure=disclosure,
desc="Changed disclosure metadata")
messages.success(request,'Disclosure modified')
return redirect("ipr_show", id=ipr.id)
else:
# assert False, form.errors
pass
else:
if ipr.updates:
form = ipr_form_mapping[ipr.__class__.__name__](instance=ipr,initial={'updates':[ x.target for x in ipr.updates ]})
else:
form = ipr_form_mapping[ipr.__class__.__name__](instance=ipr)
#disclosure = IprDisclosureBase() # dummy disclosure for inlineformset
dqs=IprDocRel.objects.filter(document__name__startswith='draft')
rqs=IprDocRel.objects.filter(document__name__startswith='rfc')
draft_formset = DraftFormset(instance=ipr, prefix='draft',queryset=dqs)
rfc_formset = RfcFormset(instance=ipr, prefix='rfc',queryset=rqs)
return render("ipr/details_edit.html", {
'form': form,
'draft_formset':draft_formset,
'rfc_formset':rfc_formset,
'type':type},
context_instance=RequestContext(request)
)
@role_required('Secretariat',)
def email(request, id):
"""Send an email regarding this disclosure"""
ipr = get_object_or_404(IprDisclosureBase, id=id).get_child()
if request.method == 'POST':
button_text = request.POST.get('submit', '')
if button_text == 'Cancel':
return redirect("ipr_show", id=ipr.id)
form = MessageModelForm(request.POST)
if form.is_valid():
# create Message
msg = Message.objects.create(
by = request.user.person,
subject = form.cleaned_data['subject'],
frm = form.cleaned_data['frm'],
to = form.cleaned_data['to'],
cc = form.cleaned_data['cc'],
bcc = form.cleaned_data['bcc'],
reply_to = form.cleaned_data['reply_to'],
body = form.cleaned_data['body']
)
# create IprEvent
IprEvent.objects.create(
type_id = 'msgout',
by = request.user.person,
disclosure = ipr,
response_due = form.cleaned_data['response_due'],
message = msg,
)
# send email
send_mail_message(None,msg)
messages.success(request, 'Email sent.')
return redirect('ipr_show', id=ipr.id)
else:
reply_to = get_reply_to()
initial = {
'to': ipr.submitter_email,
'frm': settings.IPR_EMAIL_TO,
'subject': 'Regarding {}'.format(ipr.title),
'reply_to': reply_to,
}
form = MessageModelForm(initial=initial)
return render("ipr/email.html", {
'ipr': ipr,
'form':form},
context_instance=RequestContext(request)
)
def history(request, id):
"""Show the history for a specific IPR disclosure"""
ipr = get_object_or_404(IprDisclosureBase, id=id).get_child()
events = ipr.iprevent_set.all().order_by("-time", "-id").select_related("by")
if not has_role(request.user, "Secretariat"):
events = events.exclude(type='private_comment')
tabs = [('Disclosure','disclosure',urlreverse('ipr_show',kwargs={'id':id}),True),
('History','history',urlreverse('ipr_history',kwargs={'id':id}),True)]
return render("ipr/details_history.html", {
'events':events,
'ipr': ipr,
'tabs':tabs,
'selected':'history'},
context_instance=RequestContext(request)
)
def iprs_for_drafts_txt(request):
docipr = {}
for o in IprDocAlias.objects.filter(ipr__status=1).select_related("doc_alias"):
name = o.doc_alias.name
for o in IprDocRel.objects.filter(disclosure__state='posted').select_related('document'):
name = o.document.name
if name.startswith("rfc"):
name = name.upper()
if not name in docipr:
docipr[name] = []
docipr[name].append(o.ipr_id)
docipr[name].append(o.disclosure_id)
lines = [ u"# Machine-readable list of IPR disclosures by draft name" ]
for name, iprs in docipr.iteritems():
lines.append(name + "\t" + "\t".join(unicode(ipr_id) for ipr_id in sorted(iprs)))
return HttpResponse("\n".join(lines), content_type="text/plain")
def new(request, type, updates=None):
"""Submit a new IPR Disclosure. If the updates field != None, this disclosure
updates one or more other disclosures."""
DraftFormset = inlineformset_factory(IprDisclosureBase, IprDocRel, form=DraftForm, can_delete=False, extra=1)
RfcFormset = inlineformset_factory(IprDisclosureBase, IprDocRel, form=RfcForm, can_delete=False, extra=1)
if request.method == 'POST':
form = ipr_form_mapping[type](request.POST)
if not type == 'generic':
draft_formset = DraftFormset(request.POST, instance=IprDisclosureBase(), prefix='draft')
rfc_formset = RfcFormset(request.POST, instance=IprDisclosureBase(), prefix='rfc')
else:
draft_formset = None
rfc_formset = None
if request.user.is_anonymous():
person = Person.objects.get(name="(System)")
else:
person = request.user.person
# check formset validity
if not type == 'generic':
valid_formsets = draft_formset.is_valid() and rfc_formset.is_valid()
else:
valid_formsets = True
if form.is_valid() and valid_formsets:
updates = form.cleaned_data.get('updates')
disclosure = form.save(commit=False)
disclosure.by = person
disclosure.state = IprDisclosureStateName.objects.get(slug='pending')
disclosure.save()
if not type == 'generic':
draft_formset = DraftFormset(request.POST, instance=disclosure, prefix='draft')
draft_formset.save()
rfc_formset = RfcFormset(request.POST, instance=disclosure, prefix='rfc')
rfc_formset.save()
set_disclosure_title(disclosure)
disclosure.save()
if updates:
for ipr in updates:
RelatedIpr.objects.create(source=disclosure,target=ipr,relationship_id='updates')
# create IprEvent
IprEvent.objects.create(
type_id='submitted',
by=person,
disclosure=disclosure,
desc="Disclosure Submitted")
# send email notification
send_mail(request, settings.IPR_EMAIL_TO, ('IPR Submitter App', 'ietf-ipr@ietf.org'),
'New IPR Submission Notification',
"ipr/new_update_email.txt",
{"ipr": disclosure,})
return render("ipr/submitted.html", context_instance=RequestContext(request))
else:
if updates:
form = ipr_form_mapping[type](initial={'updates':str(updates)})
else:
form = ipr_form_mapping[type]()
disclosure = IprDisclosureBase() # dummy disclosure for inlineformset
draft_formset = DraftFormset(instance=disclosure, prefix='draft')
rfc_formset = RfcFormset(instance=disclosure, prefix='rfc')
return render("ipr/details_edit.html", {
'form': form,
'draft_formset':draft_formset,
'rfc_formset':rfc_formset,
'type':type},
context_instance=RequestContext(request)
)
@role_required('Secretariat',)
def notify(request, id, type):
"""Send email notifications.
type = update: send notice to old ipr submitter(s)
type = posted: send notice to submitter, etc. that new IPR was posted
"""
ipr = get_object_or_404(IprDisclosureBase, id=id).get_child()
NotifyFormset = formset_factory(NotifyForm,extra=0)
if request.method == 'POST':
formset = NotifyFormset(request.POST)
if formset.is_valid():
for form in formset.forms:
message = infer_message(form.cleaned_data['text'])
message.by = request.user.person
message.save()
send_mail_message(None,message)
IprEvent.objects.create(
type_id = form.cleaned_data['type'],
by = request.user.person,
disclosure = ipr,
response_due = datetime.datetime.now().date() + datetime.timedelta(days=30),
message = message,
)
messages.success(request,'Notifications send')
return redirect("ipr_show", id=ipr.id)
else:
if type == 'update':
initial = [ {'type':'update_notify','text':m} for m in get_update_submitter_emails(ipr) ]
else:
initial = [ {'type':'msgout','text':m} for m in get_posted_emails(ipr) ]
formset = NotifyFormset(initial=initial)
return render("ipr/notify.html", {
'formset': formset,
'ipr': ipr},
context_instance=RequestContext(request)
)
@role_required('Secretariat',)
def post(request, id):
"""Post the disclosure and redirect to notification view"""
ipr = get_object_or_404(IprDisclosureBase, id=id).get_child()
person = request.user.person
ipr.state = IprDisclosureStateName.objects.get(slug='posted')
ipr.save()
# create event
IprEvent.objects.create(
type_id='posted',
by=person,
disclosure=ipr,
desc="Disclosure Posted")
messages.success(request, 'Disclosure Posted')
return redirect("ipr_notify", id=ipr.id, type='posted')
def search(request):
search_type = request.GET.get("submit")
if search_type:
form = SearchForm(request.GET)
docid = request.GET.get("id") or request.GET.get("id_document_tag") or ""
docs = doc = None
iprs = []
# set states
states = request.GET.getlist('state',('posted','removed'))
if states == ['all']:
states = IprDisclosureStateName.objects.values_list('slug',flat=True)
# get query field
q = ''
if request.GET.get(search_type):
q = request.GET.get(search_type)
if q or docid:
# Search by RFC number or draft-identifier
# Document list with IPRs
if search_type in ["draft", "rfc"]:
doc = q
if docid:
start = DocAlias.objects.filter(name=docid)
else:
if search_type == "draft":
q = normalize_draftname(q)
start = DocAlias.objects.filter(name__contains=q, name__startswith="draft")
elif search_type == "rfc":
start = DocAlias.objects.filter(name="rfc%s" % q.lstrip("0"))
# one match
if len(start) == 1:
first = start[0]
doc = str(first)
docs = related_docs(first)
iprs = iprs_from_docs(docs,states=states)
template = "ipr/search_doc_result.html"
# multiple matches, select just one
elif start:
docs = start
template = "ipr/search_doc_list.html"
# no match
else:
template = "ipr/search_doc_result.html"
# Search by legal name
# IPR list with documents
elif search_type == "holder":
iprs = IprDisclosureBase.objects.filter(holder_legal_name__icontains=q, state_id__in=states)
template = "ipr/search_holder_result.html"
# Search by patents field or content of emails for patent numbers
# IPR list with documents
elif search_type == "patent":
iprs = IprDisclosureBase.objects.filter(state_id__in=states)
iprs = iprs.filter(Q(holderiprdisclosure__patent_info__icontains=q) |
Q(thirdpartyiprdisclosure__patent_info__icontains=q) |
Q(nondocspecificiprdisclosure__patent_info__icontains=q))
template = "ipr/search_patent_result.html"
# Search by wg acronym
# Document list with IPRs
elif search_type == "group":
docs = list(DocAlias.objects.filter(document__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)
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(document__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)
template = "ipr/search_doctitle_result.html"
# Search by title of IPR disclosure
# IPR list with documents
elif search_type == "iprtitle":
iprs = IprDisclosureBase.objects.filter(title__icontains=q, state_id__in=states)
template = "ipr/search_iprtitle_result.html"
else:
raise Http404("Unexpected search type in IPR query: %s" % search_type)
# sort and render response
# convert list of IprDocRel to iprs
if iprs and isinstance(iprs[0],IprDocRel):
iprs = [ x.disclosure for x in iprs ]
# don't remove updated, per Robert
# iprs = [ ipr for ipr in iprs if not ipr.updated_by.all() ]
if has_role(request.user, "Secretariat"):
iprs = sorted(iprs, key=lambda x: (x.time, x.id), reverse=True)
iprs = sorted(iprs, key=lambda x: x.state.order)
else:
iprs = sorted(iprs, key=lambda x: (x.time, x.id), reverse=True)
return render(template, {
"q": q,
"iprs": iprs,
"docs": docs,
"doc": doc,
"form":form},
context_instance=RequestContext(request)
)
return HttpResponseRedirect(request.path)
else:
form = SearchForm(initial={'state':['all']})
return render("ipr/search.html", {"form":form }, context_instance=RequestContext(request))
def show(request, id):
"""View of individual declaration"""
ipr = get_object_or_404(IprDisclosureBase, id=id).get_child()
if not has_role(request.user, 'Secretariat'):
if ipr.state.slug == 'removed':
return render("ipr/removed.html", {
'ipr': ipr},
context_instance=RequestContext(request)
)
elif ipr.state.slug != 'posted':
raise Http404
tabs = [('Disclosure','disclosure',urlreverse('ipr_show',kwargs={'id':id}),True),
('History','history',urlreverse('ipr_history',kwargs={'id':id}),True)]
return render("ipr/details_view.html", {
'ipr': ipr,
'tabs':tabs,
'selected':'disclosure'},
context_instance=RequestContext(request)
)
def showlist(request):
"""List all disclosures by type, posted only"""
generic = GenericIprDisclosure.objects.filter(state__in=('posted','removed')).prefetch_related('relatedipr_source_set__target','relatedipr_target_set__source').order_by('-time')
specific = HolderIprDisclosure.objects.filter(state__in=('posted','removed')).prefetch_related('relatedipr_source_set__target','relatedipr_target_set__source').order_by('-time')
thirdpty = ThirdPartyIprDisclosure.objects.filter(state__in=('posted','removed')).prefetch_related('relatedipr_source_set__target','relatedipr_target_set__source').order_by('-time')
nondocspecific = NonDocSpecificIprDisclosure.objects.filter(state__in=('posted','removed')).prefetch_related('relatedipr_source_set__target','relatedipr_target_set__source').order_by('-time')
# combine nondocspecific with generic and re-sort
generic = itertools.chain(generic,nondocspecific)
generic = sorted(generic, key=lambda x: x.time,reverse=True)
return render("ipr/list.html", {
'generic_disclosures' : generic,
'specific_disclosures': specific,
'thirdpty_disclosures': thirdpty},
context_instance=RequestContext(request)
)
@role_required('Secretariat',)
def state(request, id):
"""Change the state of the disclosure"""
ipr = get_object_or_404(IprDisclosureBase, id=id)
login = request.user.person
if request.method == 'POST':
form = StateForm(request.POST)
if form.is_valid():
ipr.state = form.cleaned_data.get('state')
ipr.save()
IprEvent.objects.create(
by=login,
type_id=ipr.state.pk,
disclosure=ipr,
desc="State Changed to %s" % ipr.state.name
)
if form.cleaned_data.get('comment'):
if form.cleaned_data.get('private'):
type_id = 'private_comment'
else:
type_id = 'comment'
IprEvent.objects.create(
by=login,
type_id=type_id,
disclosure=ipr,
desc=form.cleaned_data['comment']
)
messages.success(request, 'State Changed')
return redirect("ipr_show", id=ipr.id)
else:
form = StateForm(initial={'state':ipr.state.pk,'private':True})
return render('ipr/state.html',dict(ipr=ipr,form=form),
context_instance=RequestContext(request))
# use for link to update specific IPR
def update(request, id):
"""Calls the 'new' view with updates parameter = ipd.id"""
# determine disclosure type
ipr = get_object_or_404(IprDisclosureBase,id=id)
child = ipr.get_child()
type = class_to_type[child.__class__.__name__]
return new(request, type, updates=id)

View file

@ -12,6 +12,7 @@ def infer_message(s):
m.subject = parsed.get("Subject", "").decode("utf-8")
m.frm = parsed.get("From", "").decode("utf-8")
m.to = parsed.get("To", "").decode("utf-8")
m.cc = parsed.get("Cc", "").decode("utf-8")
m.bcc = parsed.get("Bcc", "").decode("utf-8")
m.reply_to = parsed.get("Reply-to", "").decode("utf-8")
m.body = parsed.get_payload().decode("utf-8")

View file

@ -3916,5 +3916,185 @@
"slug": "approve",
"order": 3
}
},
{
"pk": "parked",
"model": "name.iprdisclosurestatename",
"fields": {
"order": 0,
"used": true,
"name": "Parked",
"desc": ""
}
},
{
"pk": "pending",
"model": "name.iprdisclosurestatename",
"fields": {
"order": 0,
"used": true,
"name": "Pending",
"desc": ""
}
},
{
"pk": "posted",
"model": "name.iprdisclosurestatename",
"fields": {
"order": 0,
"used": true,
"name": "Posted",
"desc": ""
}
},
{
"pk": "rejected",
"model": "name.iprdisclosurestatename",
"fields": {
"order": 0,
"used": true,
"name": "Rejected",
"desc": ""
}
},
{
"pk": "removed",
"model": "name.iprdisclosurestatename",
"fields": {
"order": 0,
"used": true,
"name": "Removed",
"desc": ""
}
},
{
"pk": "unknown",
"model": "name.iprdisclosurestatename",
"fields": {
"order": 0,
"used": true,
"name": "Unknown",
"desc": ""
}
},
{
"pk": "provided-later",
"model": "name.iprlicensetypename",
"fields": {
"order": 4,
"used": true,
"name": "Provided Later",
"desc": "d) Licensing Declaration to be Provided Later (implies a willingness to commit to the provisions of a), b), or c) above to all implementers; otherwise, the next option 'Unwilling to Commit to the Provisions of a), b), or c) Above'. - must be selected)"
}
},
{
"pk": "no-license",
"model": "name.iprlicensetypename",
"fields": {
"order": 1,
"used": true,
"name": "No License",
"desc": "a) No License Required for Implementers"
}
},
{
"pk": "none-selected",
"model": "name.iprlicensetypename",
"fields": {
"order": 0,
"used": true,
"name": "None Selected",
"desc": ""
}
},
{
"pk": "reasonable",
"model": "name.iprlicensetypename",
"fields": {
"order": 3,
"used": true,
"name": "Reasonable",
"desc": "c) Reasonable and Non-Discriminatory License to All Implementers with Possible Royalty/Fee"
}
},
{
"pk": "royalty-free",
"model": "name.iprlicensetypename",
"fields": {
"order": 2,
"used": true,
"name": "Royalty Free",
"desc": "b) Royalty-Free, Reasonable and Non-Discriminatory License to All Implementers"
}
},
{
"pk": "see-below",
"model": "name.iprlicensetypename",
"fields": {
"order": 6,
"used": true,
"name": "See Below",
"desc": "f) See Text Below for Licensing Declaration"
}
},
{
"pk": "unwilling-to-commit",
"model": "name.iprlicensetypename",
"fields": {
"order": 5,
"used": true,
"name": "Unwilling to Commit",
"desc": "e) Unwilling to Commit to the Provisions of a), b), or c) Above"
}
},
{
"pk": "comment",
"model": "name.ipreventtypename",
"fields": {
"order": 0,
"used": true,
"name": "Comment",
"desc": ""
}
},
{
"pk": "disclose",
"model": "name.ipreventtypename",
"fields": {
"order": 0,
"used": true,
"name": "Disclosure",
"desc": ""
}
},
{
"pk": "legacy",
"model": "name.ipreventtypename",
"fields": {
"order": 0,
"used": true,
"name": "Legacy",
"desc": ""
}
},
{
"pk": "msgin",
"model": "name.ipreventtypename",
"fields": {
"order": 0,
"used": true,
"name": "MsgIn",
"desc": ""
}
},
{
"pk": "msgout",
"model": "name.ipreventtypename",
"fields": {
"order": 0,
"used": true,
"name": "MsgOut",
"desc": ""
}
}
]

View file

@ -0,0 +1,257 @@
# -*- coding: utf-8 -*-
from south.db import db
from south.v2 import SchemaMigration
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model 'IprLicenseTypeName'
db.create_table(u'name_iprlicensetypename', (
('slug', self.gf('django.db.models.fields.CharField')(max_length=32, primary_key=True)),
('name', self.gf('django.db.models.fields.CharField')(max_length=255)),
('desc', self.gf('django.db.models.fields.TextField')(blank=True)),
('used', self.gf('django.db.models.fields.BooleanField')(default=True)),
('order', self.gf('django.db.models.fields.IntegerField')(default=0)),
))
db.send_create_signal(u'name', ['IprLicenseTypeName'])
# Adding model 'IprDisclosureStateName'
db.create_table(u'name_iprdisclosurestatename', (
('slug', self.gf('django.db.models.fields.CharField')(max_length=32, primary_key=True)),
('name', self.gf('django.db.models.fields.CharField')(max_length=255)),
('desc', self.gf('django.db.models.fields.TextField')(blank=True)),
('used', self.gf('django.db.models.fields.BooleanField')(default=True)),
('order', self.gf('django.db.models.fields.IntegerField')(default=0)),
))
db.send_create_signal(u'name', ['IprDisclosureStateName'])
# Adding model 'IprEventTypeName'
db.create_table(u'name_ipreventtypename', (
('slug', self.gf('django.db.models.fields.CharField')(max_length=32, primary_key=True)),
('name', self.gf('django.db.models.fields.CharField')(max_length=255)),
('desc', self.gf('django.db.models.fields.TextField')(blank=True)),
('used', self.gf('django.db.models.fields.BooleanField')(default=True)),
('order', self.gf('django.db.models.fields.IntegerField')(default=0)),
))
db.send_create_signal(u'name', ['IprEventTypeName'])
def backwards(self, orm):
# Deleting model 'IprLicenseTypeName'
db.delete_table(u'name_iprlicensetypename')
# Deleting model 'IprDisclosureStateName'
db.delete_table(u'name_iprdisclosurestatename')
# Deleting model 'IprEventTypeName'
db.delete_table(u'name_ipreventtypename')
models = {
u'name.ballotpositionname': {
'Meta': {'ordering': "['order']", 'object_name': 'BallotPositionName'},
'blocking': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.constraintname': {
'Meta': {'ordering': "['order']", 'object_name': 'ConstraintName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'penalty': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.dbtemplatetypename': {
'Meta': {'ordering': "['order']", 'object_name': 'DBTemplateTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.docrelationshipname': {
'Meta': {'ordering': "['order']", 'object_name': 'DocRelationshipName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'revname': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.docremindertypename': {
'Meta': {'ordering': "['order']", 'object_name': 'DocReminderTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.doctagname': {
'Meta': {'ordering': "['order']", 'object_name': 'DocTagName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.doctypename': {
'Meta': {'ordering': "['order']", 'object_name': 'DocTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.draftsubmissionstatename': {
'Meta': {'ordering': "['order']", 'object_name': 'DraftSubmissionStateName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'next_states': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'previous_states'", 'blank': 'True', 'to': u"orm['name.DraftSubmissionStateName']"}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.feedbacktypename': {
'Meta': {'ordering': "['order']", 'object_name': 'FeedbackTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.groupmilestonestatename': {
'Meta': {'ordering': "['order']", 'object_name': 'GroupMilestoneStateName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.groupstatename': {
'Meta': {'ordering': "['order']", 'object_name': 'GroupStateName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.grouptypename': {
'Meta': {'ordering': "['order']", 'object_name': 'GroupTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.intendedstdlevelname': {
'Meta': {'ordering': "['order']", 'object_name': 'IntendedStdLevelName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.iprdisclosurestatename': {
'Meta': {'ordering': "['order']", 'object_name': 'IprDisclosureStateName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.ipreventtypename': {
'Meta': {'ordering': "['order']", 'object_name': 'IprEventTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.iprlicensetypename': {
'Meta': {'ordering': "['order']", 'object_name': 'IprLicenseTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.liaisonstatementpurposename': {
'Meta': {'ordering': "['order']", 'object_name': 'LiaisonStatementPurposeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.meetingtypename': {
'Meta': {'ordering': "['order']", 'object_name': 'MeetingTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.nomineepositionstatename': {
'Meta': {'ordering': "['order']", 'object_name': 'NomineePositionStateName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.rolename': {
'Meta': {'ordering': "['order']", 'object_name': 'RoleName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.roomresourcename': {
'Meta': {'ordering': "['order']", 'object_name': 'RoomResourceName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.sessionstatusname': {
'Meta': {'ordering': "['order']", 'object_name': 'SessionStatusName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.stdlevelname': {
'Meta': {'ordering': "['order']", 'object_name': 'StdLevelName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.streamname': {
'Meta': {'ordering': "['order']", 'object_name': 'StreamName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.timeslottypename': {
'Meta': {'ordering': "['order']", 'object_name': 'TimeSlotTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
}
}
complete_apps = ['name']

View file

@ -0,0 +1,249 @@
# -*- coding: utf-8 -*-
from south.v2 import DataMigration
class Migration(DataMigration):
def forwards(self, orm):
orm.IprDisclosureStateName.objects.create(slug="pending",name="Pending",order=0)
orm.IprDisclosureStateName.objects.create(slug="parked",name="Parked",order=1)
orm.IprDisclosureStateName.objects.create(slug="posted",name="Posted",order=2)
orm.IprDisclosureStateName.objects.create(slug="rejected",name="Rejected",order=3)
orm.IprDisclosureStateName.objects.create(slug="removed",name="Removed",order=4)
orm.IprLicenseTypeName.objects.create(slug="no-license",name="No License",desc="a) No License Required for Implementers", order=1)
orm.IprLicenseTypeName.objects.create(slug="royalty-free",name="Royalty Free",desc="b) Royalty-Free, Reasonable and Non-Discriminatory License to All Implementers", order=2)
orm.IprLicenseTypeName.objects.create(slug="reasonable",name="Reasonable",desc="c) Reasonable and Non-Discriminatory License to All Implementers with Possible Royalty/Fee", order=3)
orm.IprLicenseTypeName.objects.create(slug="provided-later",name="Provided Later",desc="d) Licensing Declaration to be Provided Later (implies a willingness to commit to the provisions of a), b), or c) above to all implementers; otherwise, the next option 'Unwilling to Commit to the Provisions of a), b), or c) Above'. - must be selected)", order=4)
orm.IprLicenseTypeName.objects.create(slug="unwilling-to-commit",name="Unwilling to Commit",desc="e) Unwilling to Commit to the Provisions of a), b), or c) Above", order=5)
orm.IprLicenseTypeName.objects.create(slug="see-below",name="See Below",desc="f) See Text Below for Licensing Declaration", order=6)
orm.IprLicenseTypeName.objects.create(slug="none-selected",name="None Selected")
orm.IprEventTypeName.objects.create(slug="submitted",name="Submitted")
orm.IprEventTypeName.objects.create(slug="posted",name="Posted")
orm.IprEventTypeName.objects.create(slug="removed",name="Removed")
orm.IprEventTypeName.objects.create(slug="rejected",name="Rejected")
orm.IprEventTypeName.objects.create(slug="pending",name="Pending")
orm.IprEventTypeName.objects.create(slug="parked",name="Parked")
orm.IprEventTypeName.objects.create(slug="msgin",name="MsgIn")
orm.IprEventTypeName.objects.create(slug="msgout",name="MsgOut")
orm.IprEventTypeName.objects.create(slug="comment",name="Comment")
orm.IprEventTypeName.objects.create(slug="private_comment",name="Private Comment")
orm.IprEventTypeName.objects.create(slug="legacy",name="Legacy")
orm.IprEventTypeName.objects.create(slug="update_notify",name="Update Notify")
orm.IprEventTypeName.objects.create(slug="changed_disclosure",name="Changed disclosure metadata")
def backwards(self, orm):
orm.IprDisclosureStateName.objects.all().delete()
orm.IprLicenseTypeName.objects.all().delete()
orm.IprEventTypeName.objects.all().delete()
#raise RuntimeError("Cannot reverse this migration.")
models = {
u'name.ballotpositionname': {
'Meta': {'ordering': "['order']", 'object_name': 'BallotPositionName'},
'blocking': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.constraintname': {
'Meta': {'ordering': "['order']", 'object_name': 'ConstraintName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'penalty': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.dbtemplatetypename': {
'Meta': {'ordering': "['order']", 'object_name': 'DBTemplateTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.docrelationshipname': {
'Meta': {'ordering': "['order']", 'object_name': 'DocRelationshipName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'revname': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.docremindertypename': {
'Meta': {'ordering': "['order']", 'object_name': 'DocReminderTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.doctagname': {
'Meta': {'ordering': "['order']", 'object_name': 'DocTagName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.doctypename': {
'Meta': {'ordering': "['order']", 'object_name': 'DocTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.draftsubmissionstatename': {
'Meta': {'ordering': "['order']", 'object_name': 'DraftSubmissionStateName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'next_states': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'previous_states'", 'blank': 'True', 'to': u"orm['name.DraftSubmissionStateName']"}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.feedbacktypename': {
'Meta': {'ordering': "['order']", 'object_name': 'FeedbackTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.groupmilestonestatename': {
'Meta': {'ordering': "['order']", 'object_name': 'GroupMilestoneStateName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.groupstatename': {
'Meta': {'ordering': "['order']", 'object_name': 'GroupStateName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.grouptypename': {
'Meta': {'ordering': "['order']", 'object_name': 'GroupTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.intendedstdlevelname': {
'Meta': {'ordering': "['order']", 'object_name': 'IntendedStdLevelName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.iprdisclosurestatename': {
'Meta': {'ordering': "['order']", 'object_name': 'IprDisclosureStateName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.ipreventtypename': {
'Meta': {'ordering': "['order']", 'object_name': 'IprEventTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.iprlicensetypename': {
'Meta': {'ordering': "['order']", 'object_name': 'IprLicenseTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.liaisonstatementpurposename': {
'Meta': {'ordering': "['order']", 'object_name': 'LiaisonStatementPurposeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.meetingtypename': {
'Meta': {'ordering': "['order']", 'object_name': 'MeetingTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.nomineepositionstatename': {
'Meta': {'ordering': "['order']", 'object_name': 'NomineePositionStateName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.rolename': {
'Meta': {'ordering': "['order']", 'object_name': 'RoleName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.roomresourcename': {
'Meta': {'ordering': "['order']", 'object_name': 'RoomResourceName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.sessionstatusname': {
'Meta': {'ordering': "['order']", 'object_name': 'SessionStatusName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.stdlevelname': {
'Meta': {'ordering': "['order']", 'object_name': 'StdLevelName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.streamname': {
'Meta': {'ordering': "['order']", 'object_name': 'StreamName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
u'name.timeslottypename': {
'Meta': {'ordering': "['order']", 'object_name': 'TimeSlotTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
}
}
complete_apps = ['name']
symmetrical = True

View file

@ -73,3 +73,11 @@ class DraftSubmissionStateName(NameModel):
next_states = models.ManyToManyField('DraftSubmissionStateName', related_name="previous_states", blank=True)
class RoomResourceName(NameModel):
"Room resources: Audio Stream, Meetecho, . . ."
class IprDisclosureStateName(NameModel):
"""Pending, Parked, Posted, Rejected, Removed"""
class IprLicenseTypeName(NameModel):
"""choices a-f from the current form made admin maintainable"""
class IprEventTypeName(NameModel):
"""submitted,posted,parked,removed,rejected,msgin,msgoutcomment,private_comment,
legacy,update_notify,change_disclosure"""

View file

@ -1,331 +0,0 @@
from copy import deepcopy
import json
from form_utils.forms import BetterModelForm
from django import forms
from django.utils.safestring import mark_safe
from django.forms.formsets import formset_factory
from ietf.ipr.models import IprDetail, IprContact, LICENSE_CHOICES, IprUpdate, IprDocAlias
from ietf.doc.models import DocAlias
from ietf.secr.utils.document import get_rfc_num
def mytest(val):
if val == '1':
return True
class IprContactForm(forms.ModelForm):
contact_type = forms.ChoiceField(widget=forms.HiddenInput, choices=IprContact.TYPE_CHOICES)
name = forms.CharField(required=False, max_length=255)
telephone = forms.CharField(required=False, max_length=25)
email = forms.CharField(required=False, max_length=255)
class Meta:
model = IprContact
fields = [ 'name', 'title', 'department', 'address1', 'address2', 'telephone', 'fax', 'email' ,
'contact_type',]
def clean_contact_type(self):
return str(self.cleaned_data['contact_type'])
@property
def _empty(self):
fields = deepcopy(self._meta.fields)
fields.remove("contact_type")
for field in fields:
if self.cleaned_data[field].strip():
return False
return True
def save(self, ipr_detail, *args, **kwargs):
#import ipdb; ipdb.set_trace()
if(self.cleaned_data['contact_type'] != 1 and self._empty):
return None
contact = super(IprContactForm, self).save(*args, commit=False, **kwargs)
contact.ipr = ipr_detail
contact.save()
return contact
IPRContactFormset = formset_factory(IprContactForm, extra=0)
class IprDetailForm(BetterModelForm):
IS_PENDING_CHOICES = DOCUMENT_SECTIONS_CHOICES = (
("0", "no"),
("1", "yes"))
title = forms.CharField(required=True)
updated = forms.IntegerField(
required=False, label='IPR ID that is updated by this IPR')
remove_old_ipr = forms.BooleanField(required=False, label='Remove old IPR')
rfc_num = forms.CharField(required=False, label='RFC Number', widget=forms.HiddenInput)
id_filename = forms.CharField(
max_length=512, required=False,
label='I-D Filename (draft-ietf...)',
widget=forms.HiddenInput)
#is_pending = forms.ChoiceField(choices=IS_PENDING_CHOICES,required=False, label="B. Does your disclosure relate to an unpublished pending patent application?", widget=forms.RadioSelect)
#is_pending = forms.BooleanField(required=False, label="B. Does your disclosure relate to an unpublished pending patent application?")
licensing_option = forms.ChoiceField(
widget=forms.RadioSelect, choices=LICENSE_CHOICES, required=False)
patents = forms.CharField(widget=forms.Textarea, required=False)
date_applied = forms.CharField(required=False)
country = forms.CharField(required=False)
submitted_date = forms.DateField(required=True)
#lic_opt_c_sub = forms.BooleanField(required=False,widget=forms.CheckboxInput)
'''
FIXME: (stalled - comply is bool in model)
comply = forms.MultipleChoiceField(
choices = (('YES', 'YES'), ('NO', 'NO'), ('N/A', 'N/A')),
widget = forms.RadioSelect()
)
'''
def clean_lic_opt_sub(self, val):
return int(val)
def clean(self):
#print self.data, "\n\n", self.cleaned_data
#import ipdb;ipdb.set_trace()
lic_opt = self.cleaned_data['licensing_option']
for num, ltr in (('1', 'a'), ('2', 'b'), ('3', 'c')):
opt_sub = 'lic_opt_'+ltr+'_sub'
self._meta.fields.append(opt_sub)
if lic_opt == num and opt_sub in self.data:
self.cleaned_data[opt_sub] = 1
else:
self.cleaned_data[opt_sub] = 0
#self.cleaned_data['lic_opt_a_sub'] = self.clean_lic_opt_sub(self.data['lic_opt_a_sub'])
return self.cleaned_data
def __init__(self, *args, **kwargs):
formtype = kwargs.get('formtype')
if formtype:
del kwargs['formtype']
super(IprDetailForm, self).__init__(*args, **kwargs)
self.fields['legacy_url_0'].label='Old IPR Url'
self.fields['title'].label='IPR Title'
self.fields['legacy_title_1'].label='Text for Update Link'
self.fields['legacy_url_1'].label='URL for Update Link'
self.fields['legacy_title_2'].label='Additional Old Title 2'
self.fields['legacy_url_2'].label='Additional Old URL 2'
self.fields['document_sections'].label='C. If an Internet-Draft or RFC includes multiple parts and it is not reasonably apparent which part of such Internet-Draft or RFC is alleged to be covered by the patent information disclosed in Section V(A) or V(B), it is helpful if the discloser identifies here the sections of the Internet-Draft or RFC that are alleged to be so covered.'
self.fields['patents'].label='Patent, Serial, Publication, Registration, or Application/File number(s)'
self.fields['date_applied'].label='Date(s) granted or applied for (YYYY-MM-DD)'
self.fields['comments'].label='Licensing information, comments, notes or URL for further information'
self.fields['lic_checkbox'].label='The individual submitting this template represents and warrants that all terms and conditions that must be satisfied for implementers of any covered IETF specification to obtain a license have been disclosed in this IPR disclosure statement.'
self.fields['third_party'].label='Third Party Notification?'
self.fields['generic'].label='Generic IPR?'
self.fields['comply'].label='Complies with RFC 3979?'
self.fields['is_pending'].label="B. Does your disclosure relate to an unpublished pending patent application?"
# textarea sizes
self.fields['patents'].widget.attrs['rows'] = 2
self.fields['patents'].widget.attrs['cols'] = 70
self.fields['notes'].widget.attrs['rows'] = 3
self.fields['notes'].widget.attrs['cols'] = 70
self.fields['document_sections'].widget.attrs['rows'] = 3
self.fields['document_sections'].widget.attrs['cols'] = 70
self.fields['comments'].widget.attrs['rows'] = 3
self.fields['comments'].widget.attrs['cols'] = 70
self.fields['other_notes'].widget.attrs['rows'] = 5
self.fields['other_notes'].widget.attrs['cols'] = 70
#self.fields['is_pending'].widget.check_test = mytest
self.fields['is_pending'].widget = forms.Select(choices=self.IS_PENDING_CHOICES)
if formtype == 'update':
if self.instance.generic:
self.fields['document_sections'] = forms.ChoiceField(
widget=forms.RadioSelect,
choices=self.DOCUMENT_SECTIONS_CHOICES,
required=False,
label='C. Does this disclosure apply to all IPR owned by the submitter?')
legacy_url = self.instance.legacy_url_0
self.fields['legacy_url_0'].label = mark_safe(
'<a href="%s">Old IPR Url</a>' % legacy_url
)
updates = self.instance.updates.all()
if updates:
self.fields['updated'].initial = updates[0].updated.ipr_id
rfcs = {}
for rfc in self.instance.docs().filter(doc_alias__name__startswith='rfc'):
rfcs[rfc.doc_alias.id] = get_rfc_num(rfc.doc_alias.document)+" "+rfc.doc_alias.document.title
drafts = {}
for draft in self.instance.docs().exclude(doc_alias__name__startswith='rfc'):
drafts[draft.doc_alias.id] = draft.doc_alias.document.name
self.initial['rfc_num'] = json.dumps(rfcs)
self.initial['id_filename'] = json.dumps(drafts)
else:
# if this is a new IPR hide status field
self.fields['status'].widget = forms.HiddenInput()
def _fields(self, lst):
''' pass in list of titles, get back a list of form fields '''
return [self.fields[k] for k in lst]
def _fetch_objects(self, data, model):
if data:
ids = [int(x) for x in json.loads(data)]
else:
return []
objects = []
for id in ids:
try:
objects.append(model.objects.get(pk=id))
except model.DoesNotExist:
raise forms.ValidationError("%s not found for id %d" %(model._meta.verbose_name, id))
return objects
#def clean_document_sections(self):
# import ipdb; ipdb.set_trace()
# if self.data['document_sections'] not in self.fields['document_sections'].choices:
# return ''
# else:
# return self.data['document_sections']
def clean_rfc_num(self):
return self._fetch_objects(
self.cleaned_data['rfc_num'].strip(), DocAlias)
def clean_licensing_option(self):
data = self.cleaned_data['licensing_option']
if data == "":
return 0
return data
def clean_id_filename(self):
return self._fetch_objects(
self.cleaned_data['id_filename'].strip(), DocAlias)
def clean_is_pending(self):
data = self.cleaned_data['is_pending']
if data == "":
return 0
return data
def clean_updated(self):
id = self.cleaned_data['updated']
if id == None:
return None
try:
old_ipr = IprDetail.objects.get(pk=id)
except IprDetail.DoesNotExist:
raise forms.ValidationError("old IPR not found for id %d" % id)
return old_ipr
def clean_status(self):
status = self.cleaned_data['status']
return 0 if status == None else status
def save(self, *args, **kwargs):
#import ipdb; ipdb.set_trace()
ipr_detail = super(IprDetailForm, self).save(*args, **kwargs)
ipr_detail.rfc_document_tag = ipr_detail.rfc_number = None
# Force saving lic_opt_sub to override model editable=False
lic_opt = self.cleaned_data['licensing_option']
for num, ltr in (('1', 'a'), ('2', 'b'), ('3', 'c')):
opt_sub = 'lic_opt_'+ltr+'_sub'
self._meta.fields.append(opt_sub)
if lic_opt == num and opt_sub in self.data:
exec('ipr_detail.'+opt_sub+' = 1')
else:
exec('ipr_detail.'+opt_sub+' = 0')
ipr_detail.save()
old_ipr = self.cleaned_data['updated']
if old_ipr:
if self.cleaned_data['remove_old_ipr']:
old_ipr.status = 3
old_ipr.save()
obj,created = IprUpdate.objects.get_or_create(ipr=ipr_detail,updated=old_ipr)
if created:
obj.status_to_be = old_ipr.status
obj.processed = 0
obj.save()
IprDocAlias.objects.filter(ipr=ipr_detail).delete()
for doc in self.cleaned_data['rfc_num']:
IprDocAlias.objects.create(ipr=ipr_detail,doc_alias=doc)
for doc in self.cleaned_data['id_filename']:
#doc_alias = DocAlias.objects.get(id=doc)
IprDocAlias.objects.create(ipr=ipr_detail,doc_alias=doc)
return ipr_detail
class Meta:
model = IprDetail
fieldsets = [
('basic', {
'fields': [
'title',
'legacy_url_0',
'legacy_title_1',
'legacy_url_1',
'legacy_title_2',
'legacy_url_2',
'submitted_date',
],
}),
('booleans', {
'fields': [
'third_party',
'generic',
'comply',
],
}),
('old_ipr', {
'fields': [
'status',
'updated',
'remove_old_ipr',
],
}),
('legal_name', {
'legend': 'I. Patent Holder/Applicant ("Patent Holder")',
'fields': [
'legal_name',
],
}),
('rfc', {
'legend': 'IV. IETF Document or Working Group Contribution to Which Patent Disclosure Relates',
'fields': [
'rfc_num',
'id_filename',
'other_designations',
],
}),
('disclosure', {
'legend': 'V. Disclosure of Patent Information (i.e., patents or patent applications required to be disclosed by Section 6 of RFC 3979)',
'description': 'A. For granted patents or published pending patent applications, please provide the following information',
'fields': [
'patents',
'date_applied',
'country',
'notes',
'is_pending',
'document_sections',
],
}),
('other_notes', {
'legend': 'VIII. Other Notes',
'fields': [
'other_notes',
],
}),
('licensing_declaration', {
'fields': [
'lic_checkbox',
'licensing_option',
'comments',
],
}),
]
fields = []
for n, d in fieldsets:
fields += d["fields"]

View file

@ -1,28 +0,0 @@
from ietf.ipr.models import IprDetail
class _IprDetailManager(object):
def queue_ipr(self):
# qq{select document_title, ipr_id, submitted_date,status from ipr_detail where status = 0 order by submitted_date desc};
return IprDetail.objects.filter(status=0).order_by('-submitted_date')
def generic_ipr(self):
#qq{select document_title, ipr_id, submitted_date,status,additional_old_title1,additional_old_url1,additional_old_title2,additional_old_url2 from ipr_detail where status = 1 and generic=1 and third_party=0 order by submitted_date desc};
return IprDetail.objects.filter(status=1, generic=True, third_party=False).order_by('-submitted_date')
def third_party_notifications(self):
#qq{select document_title, ipr_id, submitted_date,status,additional_old_title1,additional_old_url1,additional_old_title2,additional_old_url2 from ipr_detail where status = 1 and third_party=1 order by submitted_date desc};
return IprDetail.objects.filter(status=1, third_party=True).order_by('-submitted_date')
def specific_ipr(self):
# qq{select document_title, ipr_id, submitted_date,status,additional_old_title1,additional_old_url1,additional_old_title2,additional_old_url2 from ipr_detail where status = 1 and generic=0 and third_party=0 order by submitted_date desc};
return IprDetail.objects.filter(status=1, generic=False, third_party=False).order_by('-submitted_date')
def admin_removed_ipr(self):
#qq{select document_title, ipr_id, submitted_date,status,additional_old_title1,additional_old_url1,additional_old_title2,additional_old_url2 from ipr_detail where status = 2 order by submitted_date desc};
return IprDetail.objects.filter(status=2).order_by('-submitted_date')
def request_removed_ipr(self):
#qq{select document_title, ipr_id, submitted_date,status,additional_old_title1,additional_old_url1,additional_old_title2,additional_old_url2 from ipr_detail where status = 3 order by submitted_date desc};
return IprDetail.objects.filter(status=3).order_by('-submitted_date')
IprDetailManager = _IprDetailManager()

View file

@ -1 +0,0 @@

View file

@ -1,26 +0,0 @@
from django.core.urlresolvers import reverse
from ietf.utils.test_utils import TestCase
from ietf.utils.test_data import make_test_data
SECR_USER='secretary'
class MainTestCase(TestCase):
def test_main(self):
"Main Test"
make_test_data()
url = reverse('ipradmin')
self.client.login(username="secretary", password="secretary+password")
response = self.client.get(url)
self.assertEqual(response.status_code, 301)
"""
def test_view(self):
"View Test"
draft = make_test_data()
drafts = Document.objects.filter(type='draft')
url = reverse('drafts_view', kwargs={'id':drafts[0].name})
self.client.login(username="secretary", password="secretary+password")
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
"""

View file

@ -1,25 +0,0 @@
from django.conf.urls import patterns, url
from django.views.generic import RedirectView
urlpatterns = patterns('ietf.secr.ipradmin.views',
url(r'^$', RedirectView.as_view(url='admin/'), name="ipradmin"),
url(r'^admin/?$', 'admin_list', name="ipradmin_admin_list"),
url(r'^admin/detail/(?P<ipr_id>\d+)/?$', 'admin_detail', name="ipradmin_admin_detail"),
url(r'^admin/create/?$', 'admin_create', name="ipradmin_admin_create"),
url(r'^admin/update/(?P<ipr_id>\d+)/?$', 'admin_update', name="ipradmin_admin_update"),
url(r'^admin/notify/(?P<ipr_id>\d+)/?$', 'admin_notify', name="ipradmin_admin_notify"),
url(r'^admin/old_submitter_notify/(?P<ipr_id>\d+)/?$', 'old_submitter_notify', name="ipradmin_old_submitter_notify"),
url(r'^admin/post/(?P<ipr_id>\d+)/?$', 'admin_post', name="ipradmin_admin_post"),
url(r'^admin/delete/(?P<ipr_id>\d+)/?$', 'admin_delete', name="ipradmin_admin_delete"),
url(r'^ajax/rfc_num/?$', 'ajax_rfc_num', name="ipradmin_ajax_rfc_num"),
url(r'^ajax/internet_draft/?$', 'ajax_internet_draft', name="ipradmin_ajax_internet_draft"),
)

View file

@ -1,820 +0,0 @@
import re
import itertools
from datetime import datetime
from textwrap import TextWrapper
from smtplib import SMTPException
from django.core.exceptions import ImproperlyConfigured
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.utils.safestring import mark_safe
from django.shortcuts import redirect
from ietf.secr.lib.template import template, jsonapi
from ietf.secr.ipradmin.managers import IprDetailManager
from ietf.secr.ipradmin.forms import IprDetailForm, IPRContactFormset
from ietf.secr.utils.document import get_rfc_num, is_draft
from ietf.ietfauth.utils import role_required
from ietf.ipr.models import IprDetail, IprUpdate, IprContact, LICENSE_CHOICES, STDONLY_CHOICES, IprNotification
from ietf.utils.mail import send_mail_text
from ietf.doc.models import DocAlias
from ietf.group.models import Role
@role_required('Secretariat')
@template('ipradmin/list.html')
def admin_list(request):
queue_ipr = IprDetailManager.queue_ipr()
generic_ipr = IprDetailManager.generic_ipr()
specific_ipr = IprDetailManager.specific_ipr()
admin_removed_ipr = IprDetailManager.admin_removed_ipr()
request_removed_ipr = IprDetailManager.request_removed_ipr()
third_party_notifications = IprDetailManager.third_party_notifications()
return dict ( queue_ipr = queue_ipr,
generic_ipr = generic_ipr,
specific_ipr = specific_ipr,
admin_removed_ipr = admin_removed_ipr,
request_removed_ipr = request_removed_ipr,
third_party_notifications = third_party_notifications)
@role_required('Secretariat')
def admin_post(request, ipr_id, from_page, command):
ipr_dtl = IprDetail.objects.get(ipr_id=ipr_id)
ipr_dtl.status = 1
#assert False, (ipr_dtl.ipr_id, ipr_dtl.is_pending)
ipr_dtl.save()
updates = ipr_dtl.updates.filter(processed=0)
for update in updates:
old_ipr = IprDetail.objects.get(ipr_id=update.updated.ipr_id)
updated_title = re.sub(r' \(\d\)$', '', old_ipr.title)
lc_updated_title = updated_title.lower()
lc_this_title = ipr_dtl.title.lower()
if lc_updated_title == lc_this_title:
doc_number = IprDetail.objects.filter(title__istartswith=lc_this_title+' (', title__iendswith=')').count()
if doc_number == 0: # No same ipr title before - number the orginal ipr
old_ipr.title = "%s (1)" % ipr_dtl.title
ipr_dtl.title = "%s (2)" % ipr_dtl.title
else: # Second or later update, increment
ipr_dtl.title = "%s (%d)" % (ipr_dtl.title, doc_number+1)
old_ipr.status = update.status_to_be
update.processed = 1
old_ipr.save()
update.save()
ipr_dtl.save()
#assert False, (ipr_dtl.ipr_id, ipr_dtl.is_pending)
redirect_url = '/secr/ipradmin/admin/notify/%s?from=%s' % (ipr_id, from_page)
return HttpResponseRedirect(redirect_url)
# end admin_post
def send_notifications(post_data, ipr_id, update=False):
for field in post_data:
if 'notify' in field:
str_msg = re.sub(r'\r', '', post_data[field])
msg_lines = str_msg.split('\n')
body = '\n'.join(msg_lines[4:])
headers = msg_lines[:4]
to = re.sub('To:', '', headers[0]).strip()
frm = re.sub('From:', '', headers[1]).strip()
subject = re.sub('Subject:', '', headers[2]).strip()
cc = re.sub('Cc:', '', headers[3]).strip()
'''
not required, send_mail_text handles this
try:
if settings.DEVELOPMENT:
to = cc = settings.TEST_EMAIL
frm = 'test@amsl.com'
except AttributeError:
pass
'''
try:
send_mail_text(None, to, frm, subject, body, cc)
except (ImproperlyConfigured, SMTPException) as e:
return e
now = datetime.now()
IprNotification(
ipr_id=ipr_id,
notification=str_msg,
date_sent=now.date(),
time_sent=now.time()
)
if update:
ipr_dtl = IprDetail.objects.get(ipr_id=ipr_id)
today = datetime.today().date()
ipr_dtl.update_notified_date = today
ipr_dtl.save()
return None
@role_required('Secretariat')
@template('ipradmin/notify.html')
def admin_notify(request, ipr_id):
if request.POST and 'command' in request.POST and 'do_send_notifications' == request.POST['command']:
send_result = send_notifications(request.POST, ipr_id)
if send_result:
request.session['send_result'] = 'Some messages failed to send'
else:
request.session['send_result'] = 'Messages sent successfully'
return redirect('ipradmin_old_submitter_notify', ipr_id=ipr_id)
if 'send_result' in request.session:
result = request.session['send_result']
del request.session['send_result']
return dict(
page_id = 'send_result',
result = result
)
if request.GET and 'from' in request.GET:
from_page = request.GET['from']
page_id = from_page + '_post'
ipr_dtl = IprDetail.objects.get(ipr_id=ipr_id)
generic_ad = ''
if ipr_dtl.generic:
generic_ad = get_generic_ad_text(ipr_id)
updated_ipr = ipr_dtl.updates.filter(processed=0)
updated_ipr_id = updated_ipr[0].ipr_id if updated_ipr else 0
submitter_text = get_submitter_text(ipr_id, updated_ipr_id, from_page)
document_relatives = ''
for iprdocalias in ipr_dtl.docs():
document_relatives += get_document_relatives(ipr_dtl, iprdocalias.doc_alias)
return dict(
page_id = page_id,
ipr_id = ipr_id,
submitter_text = submitter_text,
document_relatives = document_relatives,
generic_ad = generic_ad
)
def get_generic_ad_text(id):
'''
This function builds an email to the General Area, Area Director
'''
text = ''
role = Role.objects.filter(group__acronym='gen',name='ad')[0]
gen_ad_name = role.person.name
gen_ad_email = role.email.address
ipr_dtl = IprDetail.objects.get(ipr_id=id)
submitted_date, ipr_title = ipr_dtl.submitted_date, ipr_dtl.title
email_body = TextWrapper(width=80, break_long_words=False).fill(
'A generic IPR disclosure was submitted to the IETF Secretariat on %s and has been posted on the "IETF Page of Intellectual Property Rights Disclosures" (https://datatracker.ietf.org/public/ipr_list.cgi). The title of the IPR disclosure is "%s."' % (submitted_date, ipr_title)
)
text = '''
<h4>Generic IPR notification to GEN AD, %s</h4>
<textarea name="notify_gen_ad" rows=25 cols=80>
To: %s
From: IETF Secretariat <ietf-ipr@ietf.org>
Subject: Posting of IPR Disclosure
Cc:
Dear %s:
%s
The IETF Secretariat
</textarea>
<br><br>
<br>
''' % (gen_ad_name, gen_ad_email, gen_ad_name, email_body)
return text
def get_submitter_text(ipr_id, updated_ipr_id, from_page):
text = ''
ipr_dtl = IprDetail.objects.get(ipr_id=ipr_id)
c3, c2, c1 = [ipr_dtl.contact.filter(contact_type=x) for x in [3,2,1]]
if c3:
to_email, to_name = c3[0].email, c3[0].name
elif c2:
to_email, to_name = c2[0].email, c2[0].name
elif c1:
to_email, to_name = c1[0].email, c1[0].name
else:
to_email = "UNKNOWN EMAIL - NEED ASSISTANCE HERE"
to_name = "UNKNOWN NAME - NEED ASSISTANCE HERE"
ipr_title = IprDetail.objects.get(ipr_id=ipr_id).title
wrapper = TextWrapper(width=80, break_long_words=False)
if from_page == 'detail':
email_body = 'Your IPR disclosure entitled "%s" has been posted on the "IETF Page of Intellectual Property Rights Disclosures" (https://datatracker.ietf.org/public/ipr_list.cgi).' % (ipr_title)
subject = "Posting of IPR Disclosure";
elif from_page == 'update':
email_body = 'On DATE, UDPATE NAME submitted an update to your 3rd party disclosure -- entitled "%s". The update has been posted on the "IETF Page of Intellectual Property Rights Disclosures" (https://datatracker.ietf.org/ipr/%s/)' % (ipr_title, ipr_id)
subject = "IPR disclosure Update Notification"
email_body = wrapper.fill(email_body)
cc_list = [];
if updated_ipr_id > 0:
subject = "Posting of Updated IPR Disclosure"
updated_ipr_dtl = IprDetail.objects.get(ipr_id=updated_ipr_id)
old_submitted_date, old_title = updated_ipr_dtl.submitted_date, updated_ipr_dtl.old_title
email_body = 'Your IPR disclosure entitled "%s" has been posted on the "IETF Page of Intellectual Property Rights Disclosures" (https://datatracker.ietf.org/public/ipr_list.cgi). Your IPR disclosure updates IPR disclosure ID #$updated_ipr_id, "%s," which was posted on $old_submitted_date' % (ipr_title, updated_ipr_id, old_title, old_submitted_date)
updated_contacts = updated_ipr_dtl.contact.all()
c3, c2, c1 = [updated_contacts.filter(contact_type=x) for x in [3,2,1]]
if c3:
cc_list.append(c3[0].email)
elif c2:
cc_list.append(c2[0].email)
for idx in range(10):
cc_list.append(c1[0].email)
updated_ipr = IprUpdate.objects.filter(ipr_id=updated_ipr_id)
if updated_ipr:
c1 = IprContact.objects.filter(ipr_id=updated_ipr[0].updated, contact_type=1)
if not updated_ipr or not c1:
break
cc_list.append(ipr_dtl.contacts.filter(contact_type=1)[0].email)
cc_list = ','.join(list(set(cc_list)))
text = '''To: %s
From: IETF Secretariat <ietf-ipr@ietf.org>
Subject: %s
Cc: %s
Dear %s:
%s
The IETF Secretariat
''' % (to_email, subject, cc_list, to_name, email_body)
return text
# end get_submitter_text
def get_document_relatives(ipr_dtl, docalias):
'''
This function takes a IprDetail object and a DocAlias object and returns an email.
'''
text = ''
doc = docalias.document
doc_info, author_names, author_emails, cc_list = '', '', '', ''
authors = doc.authors.all()
if is_draft(doc):
doc_info = 'Internet-Draft entitled "%s" (%s)' \
% (doc.title, doc.name)
updated_id = doc.pk
else: # not i-draft, therefore rfc
rfc_num = get_rfc_num(doc)
doc_info = 'RFC entitled "%s" (RFC%s)' \
% (doc.title, rfc_num)
updated_id = rfc_num
# if the document is not associated with a group copy job owner or Gernal Area Director
if doc.group.acronym == 'none':
if doc.ad and is_draft(doc):
cc_list = doc.ad.role_email('ad').address
else:
role = Role.objects.filter(group__acronym='gen',name='ad')[0]
cc_list = role.email.address
else:
cc_list = get_wg_email_list(doc.group)
author_emails = ','.join([a.address for a in authors])
author_names = ', '.join([a.person.name for a in authors])
cc_list += ", ipr-announce@ietf.org"
submitted_date = ipr_dtl.submitted_date
ipr_title = ipr_dtl.title
email_body = '''
An IPR disclosure that pertains to your %s was submitted to the IETF Secretariat on %s and has been posted on the "IETF Page of Intellectual Property Rights Disclosures" (https://datatracker.ietf.org/ipr/%s/). The title of the IPR disclosure is "%s."");
''' % (doc_info, submitted_date, ipr_dtl.ipr_id, ipr_title)
wrapper = TextWrapper(width=80, break_long_words=False)
email_body = wrapper.fill(email_body)
text = '''
<h4>Notification for %s</h4>
<textarea name="notify_%s" rows=25 cols=80>
To: %s
From: IETF Secretariat <ietf-ipr@ietf.org>
Subject: IPR Disclosure: %s
Cc: %s
Dear %s:
%s
The IETF Secretariat
</textarea>
<br><br>
''' % (doc_info, updated_id, author_emails, ipr_title, cc_list, author_names, email_body)
# FIXME: why isn't this working - done in template now, also
return mark_safe(text)
# end get_document_relatives
def get_wg_email_list(group):
'''This function takes a Working Group object and returns a string of comman separated email
addresses for the Area Directors and WG Chairs
'''
result = []
roles = itertools.chain(Role.objects.filter(group=group.parent,name='ad'),
Role.objects.filter(group=group,name='chair'))
for role in roles:
result.append(role.email.address)
if group.list_email:
result.append(group.list_email)
return ', '.join(result)
@role_required('Secretariat')
@template('ipradmin/delete.html')
def admin_delete(request, ipr_id):
ipr_dtl = IprDetail.objects.get(ipr_id=ipr_id)
ipr_dtl.status = 2
ipr_dtl.save()
return redirect('ipradmin_admin_list')
@role_required('Secretariat')
@template('ipradmin/notify.html')
def old_submitter_notify(request, ipr_id):
if request.POST and 'command' in request.POST \
and 'do_send_update_notification' == request.POST['command']:
send_result = send_notifications(request.POST, ipr_id, update=True)
if send_result:
#assert False, send_result
request.session['send_result'] = 'Some messages failed to send'
else:
request.session['send_result'] = 'Messages sent successfully'
return redirect('ipradmin_old_submitter_notify', ipr_id=ipr_id)
if 'send_result' in request.session:
result = request.session['send_result']
del request.session['send_result']
return dict(
page_id = 'send_result',
result = result
)
contact_three = IprContact.objects.filter(ipr__ipr_id=ipr_id, contact_type=3)
if contact_three:
submitter_email, submitter_name = contact_three[0].email, contact_three[0].name
else:
contact_two = IprContact.objects.filter(ipr__ipr_id=ipr_id, contact_type=2)
if contact_two:
submitter_email, submitter_name = contact_two[0].email, contact_two[0].name
else:
submitter_email = submitter_name = ''
try:
ipr_update = IprUpdate.objects.get(ipr__ipr_id=ipr_id, processed=0)
except IprUpdate.DoesNotExist:
# import ipdb; ipdb.set_trace()
pass
old_ipr_id = ipr_update.updated.ipr_id
old_ipr = IprDetail.objects.get(ipr_id=old_ipr_id)
old_contact_three = IprContact.objects.filter(ipr__ipr_id=old_ipr_id, contact_type=3)
if old_contact_three:
to_email, to_name = old_contact_three[0].email, old_contact_three[0].name
else:
old_contact_two = IprContact.objects.filter(ipr__ipr_id=old_ipr_id, contact_type=2)
if old_contact_two:
to_email, to_name = old_contact_two[0].email, old_contact_two[0].name
else:
to_email = to_name = ''
updated_document_title, orig_submitted_date = old_ipr.title, old_ipr.submitted_date
return dict(
page_id = 'detail_notify',
ipr_id = ipr_id,
updated_ipr_id = old_ipr_id,
submitter_email = submitter_email,
submitter_name = submitter_name,
to_email = to_email,
to_name = to_name,
updated_document_title = updated_document_title,
orig_submitted_date = orig_submitted_date,
)
# end old_submitter_notify
@role_required('Secretariat')
@template('ipradmin/detail.html')
def admin_detail(request, ipr_id):
if request.POST and request.POST['command']:
command = request.POST['command']
if command == 'post':
return admin_post(request, ipr_id, 'detail', 'post')
elif command == 'notify':
return redirect('ipradmin_old_submitter_notify', ipr_id=ipr_id)
elif command == 'delete':
return redirect('ipradmin_admin_delete', ipr_id=ipr_id)
header_text = possible = temp_name = footer_text = ''
contact_one_data, contact_two_data, document_data, licensing_data,\
disclosure_data, designations_data, contact_three_data,\
notes_data, controls = [], [], [], [], [], [], [], [], []
ipr_dtl = IprDetail.objects.get(ipr_id=ipr_id)
ipr_updates = IprUpdate.objects.filter(processed=0, ipr__ipr_id=ipr_id)
contact_one, contact_two, contact_three = [
ipr_dtl.contact.filter(contact_type=x) for x in (1,2,3)
]
if ipr_updates:
if ipr_dtl.update_notified_date:
footer_text = mark_safe('<span class="alert">This update was notifed to the submitter of the IPR that is being updated on %s.</span>' % ipr_dtl.update_notified_date)
else:
controls = ['notify']
if not ipr_updates or ipr_dtl.update_notified_date:
controls = ['post']
controls.append('delete')
if ipr_dtl.third_party:
temp_name = 'Notification'
possible = 'Possible '
displaying_section = "I, II, and III"
header_text = '''This form is used to let the IETF know about patent information regarding an IETF document or contribution when the person letting the IETF know about the patent has no relationship with the patent owners.<br>
Click <a href="./ipr.cgi"> here</a> if you want to disclose information about patents or patent applications where you do have a relationship to the patent owners or patent applicants.'''
elif ipr_dtl.generic:
temp_name = "Generic IPR Disclosures"
displaying_section = "I and II"
header_text = '''This document is an IETF IPR Patent Disclosure and Licensing Declaration
Template and is submitted to inform the IETF of a) patent or patent application information that is not related to a specific IETF document or contribution, 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.'''
else:
temp_name = "Specific IPR Disclosures"
displaying_section = "I, II, and IV"
header_text = '''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.'''
legacy_links = (
(ipr_dtl.legacy_url_1 or '', ipr_dtl.legacy_title_1 or ''),
(ipr_dtl.legacy_url_2 or '', ipr_dtl.legacy_title_2 or ''),
)
comply_statement = '' if ipr_dtl.comply else mark_safe('<div class="alert">This IPR disclosure does not comply with the formal requirements of Section 6, "IPR Disclosures," of RFC 3979, "Intellectual Property Rights in IETF Technology."</div>')
# FIXME: header_text is assembled in perl code but never printed
if ipr_dtl.legacy_url_0:
#header_text = header_text + '''
header_text = '''
This IPR disclosure was submitted by e-mail.<br>
%s
Sections %s of "The Patent Disclosure and Licensing Declaration Template for %s" have been completed for this IPR disclosure. Additional information may be available in the original submission.<br>
Click <a href="%s">here</a> to view the content of the original IPR disclosure.''' % (comply_statement, displaying_section, temp_name, ipr_dtl.legacy_url_0)
else:
#header_text = header_text + '''
header_text = '''
Only those sections of the "Patent Disclosure and Licensing Declaration Template for %s" where the submitter provided information are displayed.''' % temp_name
if not ipr_dtl.generic or not (not ipr_dtl.legacy_url_0 and (ipr_dtl.notes or ipr_dtl.patents)):
# FIXME: behavior as perl, but is quite confusing and seems wrong
if contact_one and contact_one[0].name:
contact_one = contact_one[0]
contact_one_data = [
('II. Patent Holder\'s Contact for License Application:'),
('Name:', contact_one.name),
('Title:', contact_one.title),
('Department:', contact_one.department),
('Address1:', contact_one.address1),
('Address2:', contact_one.address2),
('Telephone:', contact_one.telephone),
('Fax:', contact_one.fax),
('Email:', contact_one.email)
]
if not ipr_dtl.generic:
if contact_two and contact_two[0].name:
contact_two = contact_two[0]
contact_two_data = [
('III. Contact Information for the IETF Participant Whose Personal Belief Triggered this Disclosure:'),
('Name:', contact_two.name),
('Title:', contact_two.title),
('Department:', contact_two.department),
('Address1:', contact_two.address1),
('Address2:', contact_two.address2),
('Telephone:', contact_two.telephone),
('Fax:', contact_two.fax),
('Email:', contact_two.email)
]
# conversion
#rfcs = ipr_dtl.rfcs.all()
#drafts = ipr_dtl.drafts.all()
rfcs = ipr_dtl.docs().filter(doc_alias__name__startswith='rfc')
drafts = ipr_dtl.docs().exclude(doc_alias__name__startswith='rfc')
titles_data, rfcs_data, drafts_data, designations_data = (), (), (), ()
rfc_titles, draft_titles = [], []
if rfcs:
rfc_titles = [
rfc.doc_alias.document.title for rfc in rfcs
]
rfcs_data = tuple([
'RFC Number:',
[get_rfc_num(rfc.doc_alias.document) for rfc in rfcs]
])
if drafts:
draft_titles = [
draft.doc_alias.document.title for draft in drafts
]
drafts_data = tuple([
'ID Filename:',
[draft.doc_alias.document.name+'.txt' for draft in drafts]
])
if ipr_dtl.other_designations:
designations_data = tuple([
'Designations for Other Contributions:',
ipr_dtl.other_designations
])
if drafts or rfcs:
titles_data = tuple([
'Title:',
rfc_titles + draft_titles
])
if rfcs_data or drafts_data or designations_data:
document_data = [
('IV. IETF Document or Other Contribution to Which this IPR Disclosure Relates'),
titles_data,
rfcs_data,
drafts_data,
designations_data,
]
if not ipr_dtl.legacy_url_0 and (ipr_dtl.notes or ipr_dtl.patents):
if ipr_dtl.generic:
disclosure_c = (
'C. Does this disclosure apply to all IPR owned by the submitter?',
'YES' if ipr_dtl.applies_to_all else 'NO'
)
else:
disclosure_c = (
'''C. If an Internet-Draft or RFC includes multiple parts and it is not
reasonably apparent which part of such Internet-Draft or RFC is alleged
to be covered by the patent information disclosed in Section
V(A) or V(B), it is helpful if the discloser identifies here the sections of
the Internet-Draft or RFC that are alleged to be so
covered.''',
ipr_dtl.document_sections
)
disclosure_data = [
('V. Disclosure of Patent Information (i.e., patents or patent applications required to be disclosed by Section 6 of RFC 3979)'),
('A. For granted patents or published pending patent applications, please provide the following information', ''),
('Patent, Serial, Publication, Registration, or Application/File number(s):', ipr_dtl.patents),
('Date(s) granted or applied for:', ipr_dtl.date_applied),
('Country:', ipr_dtl.country),
('Additional Notes:', ipr_dtl.notes),
#('B. Does your disclosure relate to an unpublished pending patent application?', 'YES' if ipr_dtl.applies_to_all else 'NO'),
('B. Does your disclosure relate to an unpublished pending patent application?', 'YES' if ipr_dtl.is_pending == 1 else 'NO'),
disclosure_c
]
if not ipr_dtl.third_party and ipr_dtl.licensing_option:
lic_idx = ipr_dtl.licensing_option
chosen_declaration = LICENSE_CHOICES[lic_idx-1][1]
sub_opt = bool(
lic_idx == 0 and ipr_dtl.lic_opt_a_sub
or lic_idx == 1 and ipr_dtl.lic_opt_b_sub
or lic_idx == 2 and ipr_dtl.lic_opt_c_sub
)
chosen_declaration += STDONLY_CHOICES[1][1] if sub_opt else ''
chosen_declaration = (mark_safe("<strong>%s</strong>" % chosen_declaration), '')
comments = ipr_dtl.comments or None
lic_checkbox = ipr_dtl.lic_checkbox or None
if comments or lic_checkbox:
comments_notes_label = ('Licensing information, comments, notes or URL for further information:'),
comments_notes = (mark_safe(
"<strong>%s<br /><br />%s</strong>" % (
comments,
'The individual submitting this template represents and warrants that all terms and conditions that must be satisfied for implementers of any covered IETF specification to obtain a license have been disclosed in this IPR disclosure statement.' if lic_checkbox else ''
)),
''
)
else:
comments_notes_label = comments_notes = ''
licensing_data = [
('VI. Licensing Declaration:'),
('The Patent Holder states that its position with respect to licensing any patent claims contained in the patent(s) or patent application(s) disclosed above that would necessarily be infringed by implementation of the technology required by the relevant IETF specification ("Necessary Patent Claims"), for the purpose of implementing such specification, is as follows(select one licensing declaration option only):', ''),
chosen_declaration,
comments_notes_label,
comments_notes
]
if contact_three and contact_three[0].name:
contact_three = contact_three[0]
contact_three_data = [
('VII. Contact Information of Submitter of this Form (if different from IETF Participant in Section III above):'),
('Name:', contact_three.name),
('Title:', contact_three.title),
('Department:', contact_three.department),
('Address1:', contact_three.address1),
('Address2:', contact_three.address2),
('Telephone:', contact_three.telephone),
('Fax:', contact_three.fax),
('Email:', contact_three.email)
]
if ipr_dtl.other_notes:
notes_data = (
('VIII. Other Notes:'),
(mark_safe("<strong>%s</strong>" % ipr_dtl.other_notes), '')
)
if not (not ipr_dtl.legacy_url_0 and (ipr_dtl.notes or ipr_dtl.patents)):
# FIXME: behavior as perl, but is quite confusing and seems wrong
licensing_data = contact_three_data = notes_data = ()
page_data = [
[
('I. %sPatent Holder/Applicant ("Patent Holder"):' % possible),
('Legal Name:', ipr_dtl.legal_name),
],
contact_one_data,
contact_two_data,
document_data,
disclosure_data,
licensing_data,
contact_three_data,
notes_data,
]
return dict(
ipr_title = ipr_dtl.title,
header_text = header_text,
legacy_links = legacy_links,
submitted_date = ipr_dtl.submitted_date,
page_data = page_data,
footer_text = footer_text,
controls = controls,
)
# end admin_detail
@role_required('Secretariat')
@template('ipradmin/create.html')
def admin_create(request):
if request.method == 'POST':
ipr_detail_form = IprDetailForm(request.POST, request.FILES, formtype='create')
ipr_contact_formset = IPRContactFormset(request.POST)
if ipr_detail_form.is_valid() and \
ipr_contact_formset.forms[0].is_valid():
ipr_detail = ipr_detail_form.save()
ipr_contact_formset.forms[0].save(ipr_detail)
if ipr_contact_formset.forms[1].is_valid():
ipr_contact_formset.forms[1].save(ipr_detail)
if ipr_contact_formset.forms[2].is_valid():
ipr_contact_formset.forms[2].save(ipr_detail)
return redirect('ipradmin_admin_list')
else:
ipr_detail_form = IprDetailForm(formtype='create')
ipr_contact_formset = IPRContactFormset(initial=[
{'contact_type' : 1, 'legend' : "II. Patent Holder's Contact for License Application "},
{'contact_type' : 2, 'legend' : "III. Contact Information for the IETF Participant Whose Personal Belief Triggered the Disclosure in this Template (Optional): "},
{'contact_type' : 3, 'legend' : "VII. Contact Information of Submitter of this Form (if different from IETF Participant in Section III above)"}])
return dict(licensing_option_labels = ('a', 'b', 'c', 'd', 'e', 'f'),
ipr_detail_form = ipr_detail_form,
ipr_contact_formset = ipr_contact_formset)
# end admin_create
@role_required('Secretariat')
@template('ipradmin/update.html')
def admin_update(request, ipr_id):
if request.method == 'POST':
ipr_detail_form = IprDetailForm(
request.POST,
request.FILES,
formtype='update',
instance=IprDetail.objects.get(ipr_id=ipr_id)
)
ipr_contact_formset = IPRContactFormset(
request.POST,
)
if ipr_detail_form.is_valid() and \
ipr_contact_formset.forms[0].is_valid():
ipr_detail = ipr_detail_form.save(commit=False)
if 'update_ipr' in request.POST:
if ipr_detail.third_party:
return HttpResponseRedirect('/secr/ipradmin/admin/notify/%s?from=update' % ipr_id)
else:
redirect_url = ''
else: # remove
redirect_url = reverse('ipradmin_admin_list')
if 'admin_remove_ipr' in request.POST:
ipr_detail.status = 2
elif 'request_remove_ipr' in request.POST:
ipr_detail.status = 3
ipr_detail.save()
ipr_contact_formset.forms[0].save(ipr_detail)
if ipr_contact_formset.forms[1].is_valid():
ipr_contact_formset.forms[1].save(ipr_detail)
if ipr_contact_formset.forms[2].is_valid():
ipr_contact_formset.forms[2].save(ipr_detail)
return HttpResponseRedirect(redirect_url)
else:
pass
else: # GET
ipr_detail_form = IprDetailForm(
formtype='update',
instance=IprDetail.objects.get(ipr_id=ipr_id)
)
ipr_contact_formset = IPRContactFormset(
initial = get_contact_initial_data(ipr_id)
)
return dict(licensing_option_labels = ('a', 'b', 'c', 'd', 'e', 'f'),
ipr_detail_form = ipr_detail_form,
ipr_contact_formset = ipr_contact_formset)
# end admin_update
def get_contact_initial_data(ipr_id):
c1_data, c2_data, c3_data = (
{'contact_type' : '1', 'legend' : "II. Patent Holder's Contact for License Application "},
{'contact_type' : '2', 'legend' : "III. Contact Information for the IETF Participant Whose Personal Belief Triggered the Disclosure in this Template (Optional): "},
{'contact_type' : '3', 'legend' : "VII. Contact Information of Submitter of this Form (if different from IETF Participant in Section III above)"}
)
ipr_dtl = IprDetail.objects.get(ipr_id=ipr_id)
c1, c2, c3 = [ipr_dtl.contact.filter(contact_type=x).order_by('-pk') for x in [1,2,3]]
if c1:
c1 = c1[0]
c1_data.update({
'name': c1.name,
'title': c1.title,
'department': c1.department,
'address1': c1.address1,
'address2': c1.address2,
'telephone': c1.telephone,
'fax': c1.fax,
'email': c1.email
})
if c2:
c2 = c2[0]
c2_data.update({
'name': c2.name,
'title': c2.title,
'department': c2.department,
'address1': c2.address1,
'address2': c2.address2,
'telephone': c2.telephone,
'fax': c2.fax,
'email': c2.email
})
if c3:
c3 = c3[0]
c3_data.update({
'name': c3.name,
'title': c3.title,
'department': c3.department,
'address1': c3.address1,
'address2': c3.address2,
'telephone': c3.telephone,
'fax': c3.fax,
'email': c3.email
})
return [c1_data, c2_data, c3_data]
@jsonapi
def ajax_rfc_num(request):
if request.method != 'GET' or not request.GET.has_key('term'):
return { 'success' : False, 'error' : 'No term submitted or not GET' }
q = request.GET.get('term')
results = DocAlias.objects.filter(name__startswith='rfc%s' % q)
if results.count() > 20:
results = results[:20]
elif results.count() == 0:
return { 'success' : False, 'error' : "No results" }
response = [ dict(id=r.id, label=unicode(r.name)+" "+r.document.title) for r in results ]
return response
@jsonapi
def ajax_internet_draft(request):
if request.method != 'GET' or not request.GET.has_key('term'):
return { 'success' : False, 'error' : 'No term submitted or not GET' }
q = request.GET.get('term')
results = DocAlias.objects.filter(name__icontains=q)
if results.count() > 20:
results = results[:20]
elif results.count() == 0:
return { 'success' : False, 'error' : "No results" }
response = [dict(id=r.id, label = r.name) for r in results]
return response

View file

@ -0,0 +1,33 @@
#import logging
from django.db import connection
from django.utils.log import getLogger
logger = getLogger(__name__)
#logger.setLevel(logging.DEBUG)
#logger.addHandler(logging.FileHandler(settings.SECR_LOG_FILE))
class QueryCountDebugMiddleware(object):
"""
This middleware will log the number of queries run
and the total time taken for each request (with a
status code of 200). It does not currently support
multi-db setups.
"""
def process_response(self, request, response):
#assert False, request.path
logger.debug('called middleware. %s:%s' % (request.path,len(connection.queries)))
if response.status_code == 200:
total_time = 0
#for query in connection.queries:
# query_time = query.get('time')
# if query_time is None:
# django-debug-toolbar monkeypatches the connection
# cursor wrapper and adds extra information in each
# item in connection.queries. The query time is stored
# under the key "duration" rather than "time" and is
# in milliseconds, not seconds.
# query_time = query.get('duration', 0) / 1000
# total_time += float(query_time)
logger.debug('%s: %s queries run, total %s seconds' % (request.path,len(connection.queries), total_time))
return response

View file

@ -1,292 +0,0 @@
{% extends 'base_secr.html' %}
{% load form_utils_tags %}
{% block title %}
IPR Admin Internal Page
{% endblock %}
{% block extrahead %}
<script type="text/javascript" src="{{ SECR_STATIC_URL }}js/jquery-1.5.1.min.js"></script>
<script type="text/javascript" src="{{ SECR_STATIC_URL }}js/jquery-ui-1.8.9.min.js"></script>
<script type="text/javascript" src="{{ SECR_STATIC_URL }}js/jquery.json-2.2.min.js"></script>
<link rel="stylesheet" href="{{ SECR_STATIC_URL }}css/redmond/jquery-ui-1.8.9.custom.css" type="text/css" media="screen" charset="utf-8" />
<link rel="stylesheet" type="text/css" href="{{ SECR_STATIC_URL }}css/jquery.ui.autocomplete.css" />
<link rel="stylesheet" href="{{ SECR_STATIC_URL }}css/ipr.css" type="text/css" media="screen" charset="utf-8" />
<script type="text/javascript">
$(function() {
$("input").keydown(function(event) {
if (event.keyCode == '13') {
event.preventDefault();
// go to next form field
}
});
function add_to_list(list, id, label) {
list.append('<li><a href="' + id + '"><img src="{{ SECR_STATIC_URL }}img/delete.png" alt="delete"></a> ' + label + '</li>');
}
function setup_ajax(field, list, searchfield, url) {
var datastore = {};
if(field.val() != '')
datastore = $.evalJSON(field.val())
$.each(datastore, function(k, v) {
add_to_list(list, k, v);
});
searchfield.autocomplete({
source: url,
minLength: 1,
select: function( event, ui ) {
datastore[ui.item.id] = ui.item.label;
field.val($.toJSON(datastore));
searchfield.val('');
add_to_list(list, ui.item.id, ui.item.label);
return false;
}
});
list.delegate("a", "click", function() {
delete datastore[$(this).attr("href")];
field.val($.toJSON(datastore));
$(this).closest("li").remove();
return false;
});
}
setup_ajax($("#id_rfc_num"), $("#rfc_num_list"), $("#id_rfc_num_search"), "{% url "ipradmin_ajax_rfc_num" %}");
setup_ajax($("#id_id_filename"), $("#id_filename_list"), $("#id_id_filename_search"), "{% url "ipradmin_ajax_internet_draft" %}");
});
</script>
{% endblock %}
{% block breadcrumbs %}{{ block.super }}
&raquo; <a href="{% url "ipradmin_admin_list" %}">IPR Admin</a>
&raquo; Create
{% endblock %}
{% block content %}
<div class="module ipr-container">
<form method="post">{% csrf_token %}
{{ ipr_contact_formset.management_form }}
<h2>Add New IPR</h2>
{% if ipr_detail_form.non_field_errors %}{{ ipr_detail_form.non_field_errors }}{% endif %}
{{ ipr_detail_form.errors }}
<!-- <fieldset> -->
<ul>
{% for field in ipr_detail_form.fieldsets.basic %}
<li>
{% if field.name == "title" %}
<label for="id_title">IPR Title<span class="required"> *</span></label>
{% else %}
{% if field.name == "submitted_date" %}
<label for="id_submitted_date">Submitted Date<span class="required"> *</span></label>
{% else %}
{{ field.label_tag }}
{% endif %}
{% endif %}
{{ field }}
</li>
{% endfor %}
</ul>
<!-- </fieldset> -->
<hr>
<!-- <fieldset> -->
<ul>
{% for field in ipr_detail_form.fieldsets.booleans %}
<li>
{{ field.label_tag }}
{{ field }}
</li>
{% endfor %}
</ul>
<!-- </fieldset> -->
<hr>
<!-- <fieldset> -->
<ul>
{% for field in ipr_detail_form.fieldsets.old_ipr %}
{% if field.is_hidden %}{% else %}
<li>
{{ field.label_tag }}
{{ field }}
</li>
{% endif %}
{% endfor %}
</ul>
<!-- </fieldset> -->
<!-- <fieldset> -->
<h2>{{ ipr_detail_form.fieldsets.legal_name.legend }}</h2>
<ul>
{% for field in ipr_detail_form.fieldsets.legal_name %}
<li>
{% if field.name == "legal_name" %}
<label for="id_legal_name">Legal Name<span class="required"> *</span></label>
{% else %}
{{ field.label_tag }}
{% endif %}
{{ field }}
</li>
{% endfor %}
</ul>
<!-- </fieldset> -->
{% with ipr_contact_formset.forms.0 as form %}
<!-- <fieldset> -->
<h2>II. Patent Holder's Contact for License Application</h2>
<ul>
{{ form.as_ul }}
</ul>
<!-- </fieldset> -->
{% endwith %}
{% with ipr_contact_formset.forms.1 as form %}
<!-- <fieldset> -->
<h2>III. Contact Information for the IETF Participant Whose Personal Belief Triggered the Disclosure in this Template (Optional)</h2>
<ul>
{{ form.as_ul }}
</ul>
<!-- </fieldset> -->
{% endwith %}
<div class="autocompletes">
<h2>{{ ipr_detail_form.fieldsets.rfc.legend }}</h2>
<ul>
<li>
{{ ipr_detail_form.rfc_num.label_tag }}
<input type="text" id="id_rfc_num_search">
{{ ipr_detail_form.rfc_num }}
<ul id="rfc_num_list"></ul>
</li>
<li>
{{ ipr_detail_form.id_filename.label_tag }}
<input type="text" id="id_id_filename_search">
{{ ipr_detail_form.id_filename }}
<ul id="id_filename_list"></ul>
</li>
<li>
{{ ipr_detail_form.other_designations.label_tag }}
{{ ipr_detail_form.other_designations }}
</li>
</ul>
</div> <!-- autocompletes -->
<!-- <fieldset> -->
<h2>{{ ipr_detail_form.fieldsets.disclosure.legend }}</h2>
<ul>
<li>
{{ ipr_detail_form.fieldsets.disclosure.description }}
</li>
{% for field in ipr_detail_form.fieldsets.disclosure %}
<li>
{{ field.label_tag }}
{{ field }}
</li>
{% endfor %}
</ul>
<!-- </fieldset> -->
<!-- <fieldset> -->
<h2>VI. Licensing Declaration</h2>
<p>The Patent Holder states that its position with respect to licensing any patent claims contained in the patent(s) or patent application(s) disclosed above that would necessarily be infringed by implementation of the technology required by the relevant IETF specification ("Necessary Patent Claims"), for the purpose of implementing such specification, is as follows(select one licensing declaration option only):</p>
<ol>
<li>{{ licensing_option_labels.0 }})
<label for="id_licensing_option_0">
<input id="id_licensing_option_0" name="licensing_option" value="1" type="radio">
No License Required for Implementers.
</label>
<ul>
<li>
<input id="lic_opt_a_sub" name="id_lic_opt_a_sub" type="checkbox">
<label for="lic_opt_a_sub">This licensing declaration is limited solely to standards-track IETF documents.</label>
</li>
</ul>
</li>
<li>{{ licensing_option_labels.1 }})
<label for="id_licensing_option_1">
<input id="id_licensing_option_1" value="2" name="licensing_option" type="radio">
Royalty-Free, Reasonable and Non-Discriminatory License to All Implementers.
</label>
<ul>
<li>
<input id="lic_opt_b_sub" name="id_lic_opt_b_sub" type="checkbox">
<label for="lic_opt_b_sub">This licensing declaration is limited solely to standards-track IETF documents.</label>
</li>
</ul>
</li>
<li>{{ licensing_option_labels.2 }})
<label for="id_licensing_option_2">
<input id="id_licensing_option_2" value="3" name="licensing_option" type="radio">
Reasonable and Non-Discriminatory License to All Implementers with Possible Royalty/Fee.
</label>
<ul>
<li>
<input id="lic_opt_c_sub" name="id_lic_opt_c_sub" type="checkbox">
<label for="lic_opt_c_sub">This licensing declaration is limited solely to standards-track IETF documents.</label>
</li>
</ul>
</li>
<li>{{ licensing_option_labels.3 }})
<label for="id_licensing_option_3">
<input id="id_licensing_option_3" value="4" name="licensing_option" type="radio">
Licensing Declaration to be Provided Later (implies a willingness to commit to the provisions of a), b), or c) above to all implementers; otherwise, the next option "Unwilling to Commit to the Provisions of a), b), or c) Above" - must be selected)
</label>
</li>
<li>{{ licensing_option_labels.4 }})
<label for="id_licensing_option_4">
<input id="id_licensing_option_4" value="5" name="licensing_option" type="radio">
Unwilling to Commit to the Provisions of a), b), or c) Above
</label>
</li>
<li>{{ licensing_option_labels.5 }})
<label for="id_licensing_option_5">
<input id="id_licensing_option_5" value="6" name="licensing_option" type="radio">
See text box below for licensing declaration.
</label>
</li>
</ol>
<ul>
<li>
{{ ipr_detail_form.comments.label_tag }}
{{ ipr_detail_form.comments }}
</li>
<li>
{{ ipr_detail_form.lic_checkbox }}
{{ ipr_detail_form.lic_checkbox.label_tag }}
</li>
</ul>
<!-- </fieldset> -->
{% with ipr_contact_formset.forms.2 as form %}
<!-- <fieldset> -->
<h2>VII. Contact Information of Submitter of this Form (if different from IETF Participant in Section III above)</h2>
<ul>
{{ form.as_ul }}
</ul>
<!-- </fieldset> -->
{% endwith %}
<!-- <fieldset> -->
<h2>{{ ipr_detail_form.fieldsets.other_notes.legend }}</h2>
<ul>
{% for field in ipr_detail_form.fieldsets.other_notes %}
<li>
{{ field.label_tag }}
{{ field }}
</li>
{% endfor %}
</ul>
<!-- </fieldset> -->
{% include "includes/buttons_submit.html" %}
</form>
</div> <!-- module -->
{% endblock %}

View file

@ -1,98 +0,0 @@
{% extends 'base_secr.html' %}
{% block title %}
IPR Admin Detail Page
{% endblock %}
{% block extrahead %}
<link rel="stylesheet" href="{{ SECR_STATIC_URL }}css/ipr.css" type="text/css" media="screen" charset="utf-8" />
{% endblock %}
{% block breadcrumbs %}{{ block.super }}
&raquo; <a href="{% url "ipradmin_admin_list" %}">IPR Admin</a>
&raquo; Detail
{% endblock %}
{% block content %}
<!-- this form is a kludge to apply the style from previously created update/create pages -->
<form action="" method="post">{% csrf_token %}
<h3>{{ ipr_title }}</h3>
{{ header_text|safe }}
<br />
{% for url_title in legacy_links %}
{% if url_title %}
<a href="{{ url_title.0 }}">{{ url_title.1 }}</a>
{% endif %}
{% endfor %}
<br />
<br />
<b>Submitted date: {{ submitted_date }}</b>
<br />
<div class="module ipr-container">
{% for section in page_data %}
{#{ forloop.counter }#}
{% if section %}
<!-- <fieldset> -->
<h2>{{ section.0 }}</h2>
<ul>
{% for line in section %}
{% if forloop.counter != 1 %}
{# related documents #}
{% if forloop.parentloop.counter == 4 %}
<li>
<table><tr>
<td>{{ line.0 }}</td>
<td>
{# 'Designations for other contributions' #}
{% if 5 == forloop.counter %}
<strong>{{ line.1 }}</strong>
{% else %}
<ul>
{% for item in line.1 %}
<li><strong>{{ item }}</strong></li>
{% endfor %}
</ul>
{% endif %}
</td>
</tr></table>
</li>
{% else %}
<li>{{ line.0 }} <strong>{{ line.1 }}</strong></li>
{% endif %}
{% endif %}
{% endfor %}
</ul>
<!-- </fieldset> -->
{% endif %}
{% endfor %}
</form>
{{ footer_text }}
</div> <!-- module -->
{% for c in controls %}
{% if c == 'notify' %}
<form action="" method="post">{% csrf_token %}
<input type="hidden" name="ipr_id" value="$ipr_id">
<input type="hidden" name="command" value="notify">
<input type="submit" name="notice_it" value="Notify the submitter of IPR that is being updated">
</form>
{% endif %}
{% if c == 'post' %}
<form action="" method="post">{% csrf_token %}
<input type="hidden" name="ipr_id" value="$ipr_id">
<input type="hidden" name="command" value="post">
<input type="submit" name="post_it" value="Post It">
</form>
{% endif %}
{% if c == 'delete' %}
<form action="" method="post">{% csrf_token %}
<input type="hidden" name="ipr_id" value="$ipr_id">
<input type="hidden" name="command" value="delete">
<input type="submit" name="do_delete" value="Delete">
</form>
{% endif %}
{% endfor %}
{% endblock %}

View file

@ -1,131 +0,0 @@
{% extends 'base_secr.html' %}
{% block title %}
IPR Administrate Page
{% endblock %}
{% block extrahead %}
<link rel="stylesheet" href="{{ SECR_STATIC_URL }}css/ipr.css" type="text/css" media="screen" charset="utf-8" />
{% endblock %}
{% block breadcrumbs %}{{ block.super }}
&raquo; IPR Admin
{% endblock %}
{% block content %}
<center><h2>IPR Admin Page</h2></center><br>
<div class="module">
<div class="button-group">
<ul>
<li><button onclick="window.location='{% url "ipradmin_admin_create" %}'">Create new IPR</button></li>
<li><button onclick="window.location='https://datatracker.ietf.org/public/ipr_disclosure.cgi'">IPR Disclosure Page</button></li>
</ul>
</div>
<h2>Current List in the Queue</h2>
<table>
{% for ipr in queue_ipr %}
<tr class="{% cycle 'row1' 'row2' %}">
<td><a href="{% url "ipradmin_admin_detail" ipr.ipr_id %}">{{ipr.title }}</a></td>
</tr>
{% endfor %}
</table>
<h2>Current Active IPR List</h2><br>
<h3>Generic IPR</h3>
<table>
{% for ipr in generic_ipr %}
<tr class="{% cycle 'row1' 'row2' %}">
<td><a href="{% url "ipradmin_admin_update" ipr.ipr_id %}">{{ipr.title }}</a>
{% if ipr.legacy_title_1 %}
<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
<a href="{{ipr.legacy_url_1}}">{{ipr.legacy_title_1}},</a>
{% endif %}
{% if ipr.legacy_title_2 %}
<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
<a href="{{ipr.legacy_url_2}}">{{ipr.legacy_title_2}}</a>
{% endif %}
</td>
{% endfor %}
</table>
<br><br>
<hr>
<h3>Third Party Notification</h3>
<table>
{% for ipr in third_party_notifications %}
<tr class="{% cycle 'row1' 'row2' %}">
<td><a href="{% url "ipradmin_admin_update" ipr.ipr_id %}">{{ipr.title }}</a>
{% if ipr.legacy_title_1 %}
<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
<a href="{{ipr.legacy_url_1}}">{{ipr.legacy_title_1}},</a>
{% endif %}
{% if ipr.legacy_title_2 %}
<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
<a href="{{ipr.legacy_url_2}}">{{ipr.legacy_title_2}}</a>
{% endif %}
</td>
{% endfor %}
</table>
<br><br>
<hr>
<h3>Specific IPR</h3>
<table>
{% for ipr in specific_ipr %}
<tr class="{% cycle 'row1' 'row2' %}">
<td><a href="{% url "ipradmin_admin_update" ipr.ipr_id %}">{{ipr.title }}</a>
{% if ipr.legacy_title_1 %}
<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
<a href="{{ipr.legacy_url_1}}">{{ipr.legacy_title_1}},</a>
{% endif %}
{% if ipr.legacy_title_2 %}
<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
<a href="{{ipr.legacy_url_2}}">{{ipr.legacy_title_2}}</a>
{% endif %}
</td>
{% endfor %}
</table>
<br><br>
<hr>
<center><h2>IPR Removed by IPR Admin list</h2></center><br>
<table>
{% for ipr in admin_removed_ipr %}
<tr class="{% cycle 'row1' 'row2' %}">
<td><a href="{% url "ipradmin_admin_update" ipr.ipr_id %}">{{ipr.title }}</a>
{% if ipr.legacy_title_1 %}
<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
<a href="{{ipr.legacy_url_1}}">{{ipr.legacy_title_1}},</a>
{% endif %}
{% if ipr.legacy_title_2 %}
<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
<a href="{{ipr.legacy_url_2}}">{{ipr.legacy_title_2}}</a>
{% endif %}
</td>
{% endfor %}
</table>
<br><br>
<hr>
<center><h2>IPR Removed by Request list</h2></center><br>
<table>
{% for ipr in request_removed_ipr %}
<tr class="{% cycle 'row1' 'row2' %}">
<td><a href="{% url "ipradmin_admin_update" ipr.ipr_id %}">{{ipr.title }}</a>
{% if ipr.legacy_title_1 %}
<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
<a href="{{ipr.legacy_url_1}}">{{ipr.legacy_title_1}},</a>
{% endif %}
{% if ipr.legacy_title_2 %}
<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
<a href="{{ipr.legacy_url_2}}">{{ipr.legacy_title_2}}</a>
{% endif %}
</td>
{% endfor %}
</table>
<hr>
<br><br>
</div> <!-- module -->
{% endblock %}

View file

@ -1,105 +0,0 @@
{% extends 'base_secr.html' %}
{% block title %}
IPR Admin Notify Page
{% endblock %}
{% block extrahead %}
<link rel="stylesheet" href="{{ SECR_STATIC_URL }}css/ipr.css" type="text/css" media="screen" charset="utf-8" />
{% endblock %}
{% block breadcrumbs %}{{ block.super }}
&raquo; <a href="{% url "ipradmin_admin_list" %}">IPR Admin</a>
&raquo; Notify
{% endblock %}
{% block content %}
{% if page_id == 'send_result' %}
<div class="module">
{% if result %}
{{ result }}
{% else %}
<span class="errormsg">{{ result }}</span>
{% endif %}
<div class="button-group">
<ul>
<li><button onClick="window.location='../../'">Continue</button></li>
</ul>
</div> <!-- button-group -->
</div> <!-- module -->
{% endif %}
{% if page_id == 'detail_notify' %}
<form action="" method="post">{% csrf_token %}
<input type="hidden" name="command" value="do_send_update_notification">
<input type="hidden" name="ipr_id" value="{{ ipr_id }}">
<h4>Notification to the submitter of IPR that's being updated</h4>
<textarea name="notify_original_submitter" rows=25 cols=74>
To: {{ to_email }}
From: IETF Secretariat <ietf-ipr@ietf.org>
Subject: IPR update notification
Dear {{ to_name }}:
We have just received a request to update the IPR disclosure,
{{ updated_document_title }} (https://datatracker.ietf.org/public/ipr_detail_show.cgi?ipr_id={{ updated_ipr_id }}),
which was submitted by you on {{ orig_submitted_date }}. The name and email
address of the person who submitted the update to your IPR disclosure are:
{{ submitter_name }}, {{ submitter_email }}.
We will not post this update unless we receive positive confirmation from you that
{{ submitter_name }} is authorized to update your disclosure.
Please send confirmation to ietf-ipr@ietf.org.
If we do not hear from you within 30 days, we will inform {{ submitter_name }}
that we were not able to secure approval for posting and that we are therefore rejecting
the update until we can be assured it is authorized.
Thank you
IETF Secretariat
</textarea>
<br><br>
<input type="submit" value=" Send notifications NOW ">
</form>
<br><br>
{% endif %}
{% if page_id == 'detail_post' %}
<form action="" method="post">{% csrf_token %}
<input type="hidden" name="command" value="do_send_notifications">
<input type="hidden" name="ipr_id" value="{{ ipr_id }}">
<h4>Notification to Submitter(s)</h4>
<textarea name="notify_submitter" rows=25 cols=80>
{{ submitter_text }}
</textarea>
<br><br>
{{ document_relatives|safe }}
{{ generic_ad|safe }}
<input type="submit" value=" Send notifications NOW ">
</form>
<br><br>
{% endif %}
{% if page_id == 'update_post' %}
<form action="" method="post">{% csrf_token %}
<input type="hidden" name="command" value="do_send_notifications">
<input type="hidden" name="ipr_id" value="{{ ipr_id }}">
<h4> Notification to the submitter of IPR that's being updated</h4>
<h4> Please change the DATE and UPDATE NAME<h4>
<textarea name="notify_submitter" rows=25 cols=80>
{{ submitter_text }}
</textarea>
<br><br>
{{ document_relatives|safe }}
{{ notify_wg|safe }}
<input type="submit" value=" Send notifications NOW ">
</form>
<br><br>
</form>
{% endif %}
{% endblock content %}

View file

@ -1,282 +0,0 @@
{% extends 'base_secr.html' %}
{% load form_utils_tags %}
{% block title %}
IPR Admin Update Page
{% endblock %}
{% block extrahead %}
<script type="text/javascript" src="{{ SECR_STATIC_URL }}js/jquery-1.5.1.min.js"></script>
<script type="text/javascript" src="{{ SECR_STATIC_URL }}js/jquery-ui-1.8.9.min.js"></script>
<script type="text/javascript" src="{{ SECR_STATIC_URL }}js/jquery.json-2.2.min.js"></script>
<link rel="stylesheet" href="{{ SECR_STATIC_URL }}css/redmond/jquery-ui-1.8.9.custom.css" type="text/css" media="screen" charset="utf-8" />
<link rel="stylesheet" href="{{ SECR_STATIC_URL }}css/ipr.css" type="text/css" media="screen" charset="utf-8" />
<script type="text/javascript">
$(function() {
$("input").keydown(function(event) {
if (event.keyCode == '13') {
event.preventDefault();
// go to next form field
}
});
function add_to_list(list, id, label) {
list.append('<li><a href="' + id + '"><img src="{{ SECR_STATIC_URL }}img/delete.png" alt="delete"></a> ' + label + '</li>');
}
function setup_ajax(field, list, searchfield, url) {
var datastore = {};
window.field = field;
if(field.val() != '')
datastore = $.evalJSON(field.val())
$.each(datastore, function(k, v) {
add_to_list(list, k, v);
});
searchfield.autocomplete({
source: url,
minLength: 1,
select: function( event, ui ) {
datastore[ui.item.id] = ui.item.label;
field.val($.toJSON(datastore));
searchfield.val('');
add_to_list(list, ui.item.id, ui.item.label);
return false;
}
});
list.delegate("a", "click", function() {
delete datastore[$(this).attr("href")];
field.val($.toJSON(datastore));
$(this).closest("li").remove();
return false;
});
}
setup_ajax($("#id_rfc_num"), $("#rfc_num_list"), $("#id_rfc_num_search"), "{% url "ipradmin_ajax_rfc_num" %}");
setup_ajax($("#id_id_filename"), $("#id_filename_list"), $("#id_id_filename_search"), "{% url "ipradmin_ajax_internet_draft" %}");
});
</script>
{% endblock %}
{% block breadcrumbs %}{{ block.super }}
&raquo; <a href="{% url "ipradmin_admin_list" %}">IPR Admin</a>
&raquo; Update
{% endblock %}
{% block content %}
<div class="module ipr-container">
<form method="post" action="">{% csrf_token %}
{{ ipr_contact_formset.management_form }}
<h2>{{ ipr_detail_form.instance.title }}</h2>
{% if ipr_detail_form.non_field_errors %}{{ ipr_detail_form.non_field_errors }}{% endif %}
{{ ipr_detail_form.errors }}
{{ ipr_detail_from.fieldsets.legal_name.0 }}
{% for field in ipr_detail_form.fieldsets.legal_name %}
{% if field.errors %}
<ul class="errorlist"><li>Legal Name field is required</li></ul>
{% endif %}
{% endfor %}
<!-- <fieldset> -->
<ul>
{% for field in ipr_detail_form.fieldsets.basic %}
<li>
{{ field.label_tag }}
{{ field }}
</li>
{% endfor %}
</ul>
<!-- </fieldset> -->
<hr>
<!-- <fieldset> -->
<ul>
{% for field in ipr_detail_form.fieldsets.booleans %}
<li>
{{ field.label_tag }}
{{ field }}
</li>
{% endfor %}
</ul>
<!-- </fieldset> -->
<hr>
<!-- <fieldset> -->
<ul>
{% for field in ipr_detail_form.fieldsets.old_ipr %}
<li>
{{ field.label_tag }}
{{ field }}
</li>
{% endfor %}
</ul>
<!-- </fieldset> -->
<!-- <fieldset> -->
<h2>{{ ipr_detail_form.fieldsets.legal_name.legend }}</h2>
<ul>
{% for field in ipr_detail_form.fieldsets.legal_name %}
<li>
{{ field.errors }}
{{ field.label_tag }}
{{ field }}
</li>
{% endfor %}
</ul>
<!-- </fieldset> -->
{% with ipr_contact_formset.forms.0 as form %}
<!-- <fieldset> -->
<h2>{{form.initial.legend }}</h2>
<ul>
{{ form.as_ul }}
</ul>
<!-- </fieldset> -->
{% endwith %}
{% with ipr_contact_formset.forms.1 as form %}
<!-- <fieldset> -->
<h2>{{form.initial.legend }}</h2>
<ul>
{{ form.as_ul }}
</ul>
<!-- </fieldset> -->
{% endwith %}
<div class="autocompletes">
<h2>{{ ipr_detail_form.fieldsets.rfc.legend }}</h2>
<ul>
<li>
{{ ipr_detail_form.rfc_num.label_tag }}
<input type="text" id="id_rfc_num_search">
{{ ipr_detail_form.rfc_num }}
<ul id="rfc_num_list"></ul>
</li>
<li>
{{ ipr_detail_form.id_filename.label_tag }}
<input type="text" id="id_id_filename_search">
{{ ipr_detail_form.id_filename }}
<ul id="id_filename_list"></ul>
</li>
<li>
{{ ipr_detail_form.other_designations.label_tag }}
{{ ipr_detail_form.other_designations }}
</li>
</ul>
</div> <!-- autocompletes -->
<!-- <fieldset> -->
<h2>{{ ipr_detail_form.fieldsets.disclosure.legend }}</h2>
<ul>
<li>
{{ ipr_detail_form.fieldsets.disclosure.description }}
</li>
{% for field in ipr_detail_form.fieldsets.disclosure %}
<li>
{{ field.label_tag }}
{{ field }}
</li>
{% endfor %}
</ul>
<!-- </fieldset> -->
<!-- <fieldset id="update_license_declaration"> -->
<h2>VI. Licensing Declaration</h2>
<p>The Patent Holder states that its position with respect to licensing any patent claims contained in the patent(s) or patent application(s) disclosed above that would necessarily be infringed by implementation of the technology required by the relevant IETF specification ("Necessary Patent Claims"), for the purpose of implementing such specification, is as follows(select one licensing declaration option only):</p>
{% with ipr_detail_form.instance.licensing_option as opt %}
<ol>
<li>{{ licensing_option_labels.0 }})
<label for="id_licensing_option_0">
<input id="id_licensing_option_0" name="licensing_option" value="1" type="radio"{% if opt == 1 %} checked{% endif %}>
No License Required for Implementers.
</label>
<br>
<input id="id_lic_opt_a_sub" name="lic_opt_a_sub" type="checkbox"{% if ipr_detail_form.instance.lic_opt_a_sub %} checked{% endif %}>
<label for="lic_opt_a_sub">This licensing declaration is limited solely to standards-track IETF documents.</label>
</li>
<li>{{ licensing_option_labels.1 }})
<label for="id_licensing_option_1">
<input id="id_licensing_option_1" value="2" name="licensing_option" type="radio"{% if opt == 2 %} checked{% endif %}>
Royalty-Free, Reasonable and Non-Discriminatory License to All Implementers.
</label>
<br>
<input id="id_lic_opt_b_sub" name="lic_opt_b_sub" type="checkbox"{% if ipr_detail_form.instance.lic_opt_b_sub %} checked{% endif %}>
<label for="lic_opt_b_sub">This licensing declaration is limited solely to standards-track IETF documents.</label>
</li>
<li>{{ licensing_option_labels.2 }})
<label for="id_licensing_option_2">
<input id="id_licensing_option_2" value="3" name="licensing_option" type="radio"{% if opt == 3 %} checked{% endif %}>
Reasonable and Non-Discriminatory License to All Implementers with Possible Royalty/Fee.
</label>
<br>
<input id="id_lic_opt_c_sub" name="lic_opt_c_sub" type="checkbox"{% if ipr_detail_form.instance.lic_opt_c_sub %} checked{% endif %}>
<label for="lic_opt_c_sub">This licensing declaration is limited solely to standards-track IETF documents.</label>
</li>
<li>{{ licensing_option_labels.3 }})
<label for="id_licensing_option_3">
<input id="id_licensing_option_3" value="4" name="licensing_option" type="radio"{% if opt == 4 %} checked{% endif %}>
Licensing Declaration to be Provided Later (implies a willingness to commit to the provisions of a), b), or c) above to all implementers; otherwise, the next option "Unwilling to Commit to the Provisions of a), b), or c) Above" - must be selected)
</label>
</li>
<li>{{ licensing_option_labels.4 }})
<label for="id_licensing_option_4">
<input id="id_licensing_option_4" value="5" name="licensing_option" type="radio"{% if opt == 5 %} checked{% endif %}>
Unwilling to Commit to the Provisions of a), b), or c) Above
</label>
</li>
<li>{{ licensing_option_labels.5 }})
<label for="id_licensing_option_5">
<input id="id_licensing_option_5" value="6" name="licensing_option" type="radio"{% if opt == 6 %} checked{% endif %}>
See text box below for licensing declaration.
</label>
</li>
</ol>
{% endwith %}
<ul>
<li>
{{ ipr_detail_form.comments.label_tag }}
{{ ipr_detail_form.comments }}
</li>
<li>
{{ ipr_detail_form.lic_checkbox }}
{{ ipr_detail_form.lic_checkbox.label_tag }}
</li>
</ul>
<!-- </fieldset> -->
{% with ipr_contact_formset.forms.2 as form %}
<!-- <fieldset> -->
<h2>{{form.initial.legend }}</h2>
<ul>
{{ form.as_ul }}
</ul>
<!-- </fieldset> -->
{% endwith %}
<!-- <fieldset> -->
<h2>{{ ipr_detail_form.fieldsets.other_notes.legend }}</h2>
<ul>
{% for field in ipr_detail_form.fieldsets.other_notes %}
<li>
{{ field.label_tag }}
{{ field }}
</li>
{% endfor %}
</ul>
<!-- </fieldset> -->
<div class="button-group">
<ul>
<li><input type="submit" name="update_ipr" id="id_update_ipr" value="Update IPR" /></li>
<li><input type="submit" name="admin_remove_ipr" id="id_admin_remove_ipr" value="Remove by Admin" /></li>
<li><input type="submit" name="request_remove_ipr" id="id_request_remove_ipr" value="Remove by Request" /></li>
</ul>
</div> <!-- button-group -->
</form>
</div> <!-- module -->
{% endblock %}

View file

@ -34,7 +34,7 @@
</td>
<td>
<h3>IPR</h3>
<li> <a href="{% url "ipradmin" %}"><b>IPR Admin</b></a></li><br>
<li> <a href="{% url "ipr_admin_main" %}"><b>IPR Admin</b></a></li><br>
</td>
</tr>
</table>

View file

@ -8,7 +8,6 @@ urlpatterns = patterns('',
(r'^console/', include('ietf.secr.console.urls')),
(r'^drafts/', include('ietf.secr.drafts.urls')),
(r'^groups/', include('ietf.secr.groups.urls')),
(r'^ipradmin/', include('ietf.secr.ipradmin.urls')),
(r'^meetings/', include('ietf.secr.meetings.urls')),
(r'^proceedings/', include('ietf.secr.proceedings.urls')),
(r'^roles/', include('ietf.secr.roles.urls')),

View file

@ -224,7 +224,6 @@ INSTALLED_APPS = (
'ietf.secr.areas',
'ietf.secr.drafts',
'ietf.secr.groups',
'ietf.secr.ipradmin',
'ietf.secr.meetings',
'ietf.secr.proceedings',
'ietf.secr.roles',
@ -325,7 +324,7 @@ CACHES = {
}
}
IPR_EMAIL_TO = ['ietf-ipr@ietf.org', ]
IPR_EMAIL_TO = 'ietf-ipr@ietf.org'
DOC_APPROVAL_EMAIL_CC = ["RFC Editor <rfc-editor@rfc-editor.org>", ]
IANA_EVAL_EMAIL = "drafts-eval@icann.org"
@ -476,4 +475,3 @@ if SERVER_MODE != 'production':
if 'SECRET_KEY' not in locals():
SECRET_KEY = 'PDwXboUq!=hPjnrtG2=ge#N$Dwy+wn@uivrugwpic8mxyPfHka'
ALLOWED_HOSTS = ['*',]

View file

@ -0,0 +1,26 @@
{% extends "base.html" %}
{% block title %}Add comment on {{ ipr.title }}{% endblock %}
{% block pagehead %}
<link rel="stylesheet" type="text/css" href="/css/ipr.css"></link>
{% endblock %}
{% block content %}
<h1>Add comment on {{ ipr }}</h1>
<p>The comment will be added to the history trail.</p>
<form class="add-comment" action="" method="post">{% csrf_token %}
<table>
{{ form.as_table }}
<tr>
<td></td>
<td class="actions">
<a href="{% url "ipr_history" id=ipr.id %}">Back</a>
<input type="submit" value="Add comment"/>
</td>
</tr>
</table>
</form>
{% endblock %}

View file

@ -0,0 +1,26 @@
{% extends "base.html" %}
{% block title %}Add email on {{ ipr.title }}{% endblock %}
{% block pagehead %}
<link rel="stylesheet" type="text/css" href="/css/ipr.css"></link>
{% endblock %}
{% block content %}
<h1>Add email on {{ ipr }}</h1>
<p>The email will be added to the history trail.</p>
<form class="add-email" action="" method="post">{% csrf_token %}
<table>
{{ form.as_table }}
<tr>
<td></td>
<td class="actions">
<a href="{% url "ipr_history" id=ipr.id %}">Back</a>
<input type="submit" value="Add email"/>
</td>
</tr>
</table>
</form>
{% endblock %}

View file

@ -0,0 +1,30 @@
{% extends "base.html" %}
{# Copyright The IETF Trust 2007, All Rights Reserved #}
{% block title %}IPR Admin{% endblock %}
{% block pagehead %}
<link rel="stylesheet" type="text/css" href="/css/ipr.css"></link>
{% endblock %}
{% block content %}
{% load ietf_filters %}
<h1>IPR Admin Page</h1>
<a href="{% url "ietf.ipr.views.showlist" %}">Back to IPR Disclosure Page</a><br><br>
<div id="mytabs" class="yui-navset">
<ul class="yui-nav">
{% for name, t, url, active, tooltip in tabs %}
<li {% if t == selected %}class="selected"{% endif %}{% if tooltip %}title="{{tooltip}}"{% endif %}{% if not active %}class="disabled"{% endif %}><a{% if active %} href="{{ url }}"{% endif %}><em>{{ name }}</em></a></li>
{% endfor %}
</ul>
</div>
{% block tab_content %}
{% endblock %} <!-- tab_content -->
{% endblock %}

View file

@ -0,0 +1,33 @@
{% load ietf_filters %}
{# Copyright The IETF Trust 2007, All Rights Reserved #}
<tr class="{{ forloop.counter|divisibleby:2|yesno:"oddrow,evenrow" }}">
<td class="date-column">{{ ipr.time|date:"Y-m-d" }}</td>
<td class="id-column">{{ ipr.id }}</td>
<td class="title-column">
<a href="{% url "ietf.ipr.views.show" ipr.id %}">{{ ipr.title }}</a>
<br />
{% for item in ipr.relatedipr_source_set.all %}
{% if item.target.state_id == 'posted' %}
Updates ID <a href="{% url "ietf.ipr.views.show" item.target.id %}">#{{ item.target.id }}</a>.<br/>
{% endif %}
{% endfor %}
{% for item in ipr.relatedipr_target_set.all %}
{% comment %}{% if item.processed == 1 and item.ipr.status != 2 %}{% endcomment %}
{% if item.source.state_id == "posted" %}
Updated by ID <a href="{% url "ietf.ipr.views.show" item.source.id %}">#{{ item.source.id }}</a>.<br/>
{% endif %}
{% endfor %}
</td>
{% if selected == 'pending' %}
<td class="column-four">{{ ipr.get_latest_event_msgout.time|date:"Y-m-d" }}</td>
<td class="column-five">
{% if ipr.get_latest_event_msgout.response_due %}
{{ ipr.get_latest_event_msgout.response_due|date:"Y-m-d" }}
{% if ipr.get_latest_event_msgout.response_past_due %}
<img src="/images/warning.png" title="Response overdue"/>
{% endif %}
{% endif %}
</td>
{% endif %}
</tr>

View file

@ -0,0 +1,16 @@
{% extends "ipr/admin_base.html" %}
{# Copyright The IETF Trust 2007, All Rights Reserved #}
{% load ietf_filters %}
{% block tab_content %}
<h2>Parked Disclosures</h2>
<table id="parked-iprs" class="ietf-table" width="820">
<tr><th class="date-column">Submitted</th><th class="id-column">ID #</th><th class="title-column">Title of IPR Disclosure</th></tr>
{% for ipr in iprs %}
{% include "ipr/admin_item.html" %}
{% endfor %}
</table>
{% endblock %} <!-- tab_content -->

View file

@ -0,0 +1,16 @@
{% extends "ipr/admin_base.html" %}
{# Copyright The IETF Trust 2007, All Rights Reserved #}
{% load ietf_filters %}
{% block tab_content %}
<h2>Pending Disclosures</h2>
<table id="pending-iprs" class="ietf-table" width="820">
<tr><th class="date-column">Submitted</th><th class="id-column">ID #</th><th class="title-column">Title of IPR Disclosure</th><th>Query</th><th>Response Due</th></tr>
{% for ipr in iprs %}
{% include "ipr/admin_item.html" %}
{% endfor %}
</table>
{% endblock %} <!-- tab_content -->

View file

@ -0,0 +1,16 @@
{% extends "ipr/admin_base.html" %}
{# Copyright The IETF Trust 2007, All Rights Reserved #}
{% load ietf_filters %}
{% block tab_content %}
<h2>Removed / Rejected Disclosures</h2>
<table id="removed-iprs" class="ietf-table" width="820">
<tr><th class="date-column">Submitted</th><th class="id-column">ID #</th><th class="title-column">Title of IPR Disclosure</th></tr>
{% for ipr in iprs %}
{% include "ipr/admin_item.html" %}
{% endfor %}
</table>
{% endblock %} <!-- tab_content -->

View file

@ -1,402 +0,0 @@
{% extends "base.html" %}
{# Copyright The IETF Trust 2007, All Rights Reserved #}
{% block title %}IPR Details - {{ ipr.title }}{% endblock %}
{% block pagehead %}
<meta name="description" content="IPR disclosure #{{ipr.ipr_id}}: {{ ipr.title }} ({{ ipr.submitted_date|date:"Y" }})" />
{% endblock %}
{% block morecss %}
table.ipr { margin-top: 1em; }
.ipr .light td { background: #eeeeee; }
.ipr .dark td { background: #dddddd; }
.ipr th { background: #2647a0; color: white; }
.ipr { width: 101ex; border: 0; border-collapse: collapse; }
.ipr th, .ipr td { padding: 3px 6px; text-align: left; }
.ipr tr { vertical-align: top; }
.ipr td.iprlabel { width: 18ex; }
.iprdata { font-weight: bold; }
{% endblock %}
{% block content %}
{% load ietf_filters %}
{% if section_list.title %}
<h1>{{ ipr.title }}</h1>
{% endif %}
{% if section_list.legacy_intro %}
<p>This IPR disclosure was submitted by e-mail.</p>
{% if not ipr.comply %}
<p style="color:red;">
This IPR disclosure does not comply with the formal requirements of Section 6,
"IPR Disclosures," of RFC 3979, "Intellectual Property Rights in IETF Technology."
</p>
{% endif %}
<p>Sections {% block legacy_sections %}I, II, and IV{% endblock %} of "The Patent Disclosure and Licensing Declaration Template
for {{ section_list.disclosure_type }}" have been completed for this IPR disclosure.
Additional information may be available in the original submission.</p>
<p>The text of the original IPR disclosure is available further down, and also here:<br />
<a href="{{ipr.legacy_url_0}}">{{ipr.legacy_url_0}}</a>.</p>
{% endif %}
{% if section_list.new_intro %}
<p>Only those sections of the "Patent Disclosure and Licensing Declaration
Template for {{ section_list.disclosure_type }}" where the submitter provided
information are displayed.</p>
{% endif %}
{% if section_list.new_intro or section_list.legacy_intro %}
{% if ipr.legacy_title_1 %}
<p><a href="{{ ipr.legacy_url_1 }}">{{ ipr.legacy_title_1 }}</a></p>
{% endif %}
{% if ipr.legacy_title_2 %}
<p><a href="{{ ipr.legacy_url_2 }}">{{ ipr.legacy_title_2 }}</a></p>
{% endif %}
{% for item in ipr.updates.all %}
<p>This IPR disclosure updates IPR disclosure ID #{{ item.updated.ipr_id }},
{% if item.updated.status == 0 %}
"<a href="{% url "ietf.ipr.views.show" item.updated.ipr_id %}">{{ item.updated.title }}</a>".
{% else %}
{% if item.updated.status == 1 %}
"<a href="{% url "ietf.ipr.views.show" item.updated.ipr_id %}">{{ item.updated.title }}</a>".
{% else %}
"{{ item.updated.title }}", which was removed at the request of the submitter.
{% endif %}
{% endif %}
</p>
{% endfor %}
{% for item in ipr.updated_by.all %}
{% if item.processed == 1 and item.ipr.status != 2 %}
<p>
This IPR disclosure has been updated by IPR disclosure ID #{{ item.ipr.ipr_id }},
{% if item.status_to_be == 1 %}
"<a href="{% url "ietf.ipr.views.show" item.ipr.ipr_id %}">{{ item.ipr.title }}</a>".
{% else %}
"{{ item.ipr.title }}", which was removed at the request of the submitter.
{% endif %}
</p>
{% endif %}
{% endfor %}
<p><a href="{% url "ietf.ipr.new.update" ipr.ipr_id %}" rel="nofollow">Update this IPR disclosure</a>. Note: Updates to IPR disclosures must only be made by authorized
representatives of the original submitters. Updates will automatically
be forwarded to the current Patent Holder's Contact and to the Submitter
of the original IPR disclosure.</p>
<!-- tag 1 -->
<p><strong>Submitted Date: {{ ipr.submitted_date|date:"F j, Y" }}</strong></p>
{% endif %}
{% if section_list.holder %}
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}">
<th colspan="2">
{% cycle I,II,III,IV,V,VI,VII,VIII as section %}.
{% if section_list.third_party %}Possible{% endif %}
Patent Holder/Applicant ("Patent Holder")
</th>
</tr>
<tr class="{% cycle row_parity %}">
<td class="iprlabel">Legal Name:</td> <td class="iprdata">{{ ipr.legal_name }}</td>
</tr>
</table>
{% endif %}
{% if section_list.holder_contact %}
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}"><th colspan="2">
{% cycle section %}.
Patent Holder's Contact for License Application
</th>
</tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Name:</td> <td class="iprdata">{{ ipr.holder_contact.name }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Title:</td> <td class="iprdata">{{ ipr.holder_contact.title }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Department:</td> <td class="iprdata">{{ ipr.holder_contact.department }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Address1:</td> <td class="iprdata">{{ ipr.holder_contact.address1 }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Address2:</td> <td class="iprdata">{{ ipr.holder_contact.address2 }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Telephone:</td> <td class="iprdata">{{ ipr.holder_contact.telephone }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Fax:</td> <td class="iprdata">{{ ipr.holder_contact.fax }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Email:</td> <td class="iprdata">{{ ipr.holder_contact.email }}</td></tr>
</table>
{% endif %}
{% if section_list.ietf_contact %}
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}">
<th colspan="2" >
{% cycle section %}.
Contact Information for the IETF Participant Whose Personal Belief Triggered this Disclosure:
</th>
</tr>
{% if ipr.ietf_contact.name %}
<tr class="{% cycle row_parity %}"><td class="iprlabel">Name:</td> <td class="iprdata">{{ ipr.ietf_contact.name }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Title:</td> <td class="iprdata">{{ ipr.ietf_contact.title }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Department:</td> <td class="iprdata">{{ ipr.ietf_contact.department }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Address1:</td> <td class="iprdata">{{ ipr.ietf_contact.address1 }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Address2:</td> <td class="iprdata">{{ ipr.ietf_contact.address2 }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Telephone:</td> <td class="iprdata">{{ ipr.ietf_contact.telephone }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Fax:</td> <td class="iprdata">{{ ipr.ietf_contact.fax }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Email:</td> <td class="iprdata">{{ ipr.ietf_contact.email }}</td></tr>
{% else %}
<tr class="{% cycle row_parity %}"><td colspan="2"><i>No information submitted</i></td></tr>
{% endif %}
</table>
{% endif %}
{% if section_list.ietf_doc %}
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}">
<th colspan="2" >
{% cycle section %}.
IETF Document or Other Contribution to Which this IPR Disclosure Relates:
</th>
</tr>
{% if ipr.rfclist %}
<tr class="{% cycle row_parity %}"><td class="iprlabel">RFC Numbers:</td><td class="iprdata">{{ ipr.rfclist }}</td></tr>
{% else %}
{% for iprdocalias in ipr.rfcs %}
<tr class="{% cycle row_parity %}"><td class="iprlabel iprdata">{{ iprdocalias.formatted_name|rfcspace }}:</td><td class="iprdata">"{{ iprdocalias.doc_alias.document.title }}"</td></tr>
{% endfor %}
{% endif %}
{% if ipr.draftlist %}
<tr class="{% cycle row_parity %}"><td class="iprlabel">I-D Filenames (draft-...):</td><td class="iprdata">{{ ipr.draftlist }}</td></tr>
{% else %}
{% for iprdocalias in ipr.drafts %}
<tr class="{% cycle row_parity %}"><td class="iprlabel">Internet-Draft:</td><td class="iprdata">"{{ iprdocalias.doc_alias.document.title }}"<br />({{ iprdocalias.formatted_name }})</td></tr>
{% endfor %}
{% endif %}
{% if ipr.other_designations %}
<tr class="{% cycle row_parity %}"><td class="iprlabel">Designations for Other Contributions:</td><td class="iprdata">{{ ipr.other_designations }}</td></tr>
{% endif %}
</table>
{% endif %}
{% if section_list.patent_info %}
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}">
<th colspan="2" >
{% cycle section %}.
Disclosure of Patent Information (i.e., patents or patent
applications required to be disclosed by Section 6 of RFC 3979)
</th>
</tr>
{% if ipr.patents or ipr.notes %}
<tbody class="{% cycle row_parity %}">
<tr>
<td colspan="2">
A. For granted patents or published pending patent applications,
please provide the following information:</td>
</tr>
<tr><td class="iprlabel">Patent, Serial, Publication, Registration,
or Application/File number(s): </td><td class="iprdata">{{ ipr.patents }}</td></tr>
</tbody>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Date(s) granted or applied for: </td><td class="iprdata">{{ ipr.date_applied }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Country: </td><td class="iprdata">{{ ipr.country }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Additional Notes:</td><td class="iprdata">{{ ipr.notes|linebreaks }}</td></tr>
<tr class="{% cycle row_parity %}">
<td colspan="2">
B. Does this disclosure relate to an unpublished pending patent application?:
<span class="iprdata">{{ ipr.is_pending }}</span>
</td>
</tr>
<tbody class="{% cycle row_parity %}">
{% if section_list.generic %}
<tr class="{% cycle row_parity %}">
<td colspan="2">
C. Does this disclosure apply to all IPR owned by
the submitter?:
<span class="iprdata">{{ ipr.applies_to_all }}</span>
</td>
</tr>
{% else %}
<tr class="{% cycle row_parity %}">
<td colspan="2">
C. If an Internet-Draft or RFC includes multiple parts and it is not
reasonably apparent which part of such Internet-Draft or RFC is alleged
to be covered by the patent information disclosed in Section
V(A) or V(B), it is helpful if the discloser identifies here the sections of
the Internet-Draft or RFC that are alleged to be so
covered:
</td>
</tr>
{% if ipr.document_sections %}
<tr class="{% cycle row_parity %}"><td class="iprlabel"></td><td class="iprdata">{{ ipr.document_sections|linebreaks }}</td></tr>
{% else %}
<tr class="{% cycle row_parity %}"><td class="iprlabel"></td><td><i>No information submitted</i></td></tr>
{% endif %}
{% endif %}
</tbody>
{% else %}
<tr class="{% cycle row_parity %}"><td class="iprlabel"></td><td class="iprdata">This disclosure relates to an unpublished pending patent application.</td></tr>
{% endif %}
</table>
{% endif %}
{% if section_list.licensing %}
<!-- Not to be shown for third-party disclosures -->
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}">
<th colspan="2" >
{% cycle section %}.
Licensing Declaration
</th>
</tr>
<tbody class="{% cycle row_parity %}">
<tr>
<td colspan="2">
The Patent Holder states that its position with respect
to licensing any patent claims contained in the patent(s) or patent
application(s) disclosed above that would necessarily be infringed by
implementation of the technology required by the relevant IETF specification
("Necessary Patent Claims"), for the purpose of implementing such
specification, is as follows(select one licensing declaration option only):
</td>
</tr>
<tr>
<td colspan="2">
<span class="iprdata">{{ ipr.licensing_option }}</span>
</td>
</tr>
</tbody>
{% if ipr.stdonly_license %}
<tr class="{% cycle row_parity %}">
<td></td><td>
{{ ipr.stdonly_license }}
Above licensing declaration is limited solely to standards-track IETF documents.
</td>
</tr>
{% endif %}
<tbody class="{% cycle row_parity %}">
<tr>
<td colspan="2">
Licensing information, comments, notes, or URL for further information:
</td>
</tr>
{% if ipr.comments %}
<tr ><td class="iprlabel"> </td><td class="iprdata">{{ ipr.comments|linebreaks }}</td></tr>
{% else %}
<tr ><td class="iprlabel"> </td><td><i>No information submitted</i></td></tr>
{% endif %}
</tbody>
{% if ipr.lic_checkbox %}
<tr class="{% cycle row_parity %}">
<td colspan="2">
<p>
{% if ipr.lic_checkbox != 1 %}{{ ipr.lic_checkbox }}{% endif %}
The individual submitting this template represents and warrants that all
terms and conditions that must be satisfied for implementers of any
covered IETF specification to obtain a license have been disclosed in this
IPR disclosure statement.
</p>
{% if section_list.generic %}
<p>
Note: According to
<a href="http://www.ietf.org/rfc/rfc3979.txt?number=3979">RFC 3979</a>,
Section 6.4.3, unless you check the box
above, and choose either option a) or b), you must still file specific
IPR disclosures as appropriate.
</p>
{% endif %}
</td>
</tr>
{% endif %}
<tr class="{% cycle row_parity %}">
<td colspan="2">
<span class="iprdata">Note: The individual submitting this template represents and warrants
that he or she is authorized by the Patent Holder to agree to the
above-selected licensing declaration.</span>
</td>
</tr>
</table>
{% endif %}
{% if section_list.submitter %}
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}">
<th colspan="2" >
{% cycle section %}.
Contact Information of Submitter of this Form (if different from the
Contact Information above)
</th>
</tr>
{% if ipr.submitter.name %}
{% if ipr.ietf_contact_is_submitter %}
<tbody class="{% cycle row_parity %}">
{% if section_list.holder_contact %}
<tr>
<td colspan="2">
Same as in Section II above:
<input type="checkbox" name="hold_contact_is_submitter" onChange="toggle_submitter_info('holder');" {{ ipr.hold_contact_is_submitter_checked }} >
</td>
</tr>
{% endif %}
{% if section_list.ietf_contact %}
<tr>
<td colspan="2">
Same as in Section III above:
<input type="checkbox" name="ietf_contact_is_submitter" onChange="toggle_submitter_info('ietf');" {{ ipr.ietf_contact_is_submitter_checked }} />
</td>
</tr>
{% endif %}
</tbody>
{% endif %}
<tr class="{% cycle row_parity %}"><td class="iprlabel">Name:</td> <td class="iprdata">{{ ipr.submitter.name }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Title:</td> <td class="iprdata">{{ ipr.submitter.title }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Department:</td> <td class="iprdata">{{ ipr.submitter.department }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Address1:</td> <td class="iprdata">{{ ipr.submitter.address1 }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Address2:</td> <td class="iprdata">{{ ipr.submitter.address2 }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Telephone:</td> <td class="iprdata">{{ ipr.submitter.telephone }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Fax:</td> <td class="iprdata">{{ ipr.submitter.fax }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Email:</td> <td class="iprdata">{{ ipr.submitter.email }}</td></tr>
{% else %}
<tr class="{% cycle row_parity %}"><td colspan="2"><i>No information submitted</i></td></tr>
{% endif %}
</table>
{% endif %}
{% if section_list.notes %}
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}">
<th colspan="2" >
{% cycle section %}.
Other Notes:
</th>
</tr>
{% if ipr.other_notes %}
<tr class="{% cycle row_parity %}"><td class="iprlabel"> </td><td class="iprdata">{{ ipr.other_notes|linebreaks }}</td></tr>
{% else %}
<tr class="{% cycle row_parity %}"><td colspan="2"><i>No information submitted</i></td></tr>
{% endif %}
</table>
{% endif %}
{% if ipr.legacy_url_0 %}
<div>
<h3>The text of the original IPR declaration:</h3>
{% if ipr.legacy_text %}
<pre>{{ipr.legacy_text|safe}}</pre>
{% else %}
<iframe src="{{ipr.legacy_url_0}}" style="width:55em; height:30em">
Warning: Could not embed {{ipr.legacy_url_0}}.
</iframe>
{% endif %}
</div>
{% endif %}
{% endblock %}

View file

@ -1,79 +1,59 @@
{% autoescape off %}{% load ietf_filters %}IPR Title: {{ ipr.title|safe }}
{% autoescape off %}{% load ietf_filters %}{% load ipr_filters %}IPR Title: {{ ipr.title|safe }}
Section {% cycle I,II,III,IV,V,VI,VII,VIII as section %}. {% if ipr|to_class_name == "ThirdPartyIprDisclosure" %}Possible {% endif %}Patent Holder/Applicant ("Patent Holder")
Legal Name: {{ ipr.holder_legal_name|safe }}
Section I: Patent Holder/Applicant ("Patent Holder")
Legal Name: {{ ipr.legal_name|safe }}
{% if ipr.holder_contact_name or ipr.holder_contact_info %}Section {% cycle section %}. Patent Holder's Contact for License Application
Name: {{ ipr.holder_contact_name|safe }}
Email: {{ ipr.holder_contact_email|safe }}
Info: {{ ipr.holder_contact_info|safe }}
Section II: Patent Holder's Contact for License Application
Name: {{ ipr.holder_contact.name|safe }}
Title: {{ ipr.holder_contact.title|safe }}
Department: {{ ipr.holder_contact.department|safe }}
Address1: {{ ipr.holder_contact.address1|safe }}
Address2: {{ ipr.holder_contact.address2|safe }}
Telephone: {{ ipr.holder_contact.telephone|safe }}
Fax: {{ ipr.holder_contact.fax|safe }}
Email: {{ ipr.holder_contact.email|safe }}
{% endif %}{% if ipr.ietfer_name or ipr.ietfer_contact_info %}Section {% cycle section %}. Contact Information for the IETF Participant Whose Personal Belief Triggered this Disclosure
Name: {{ ipr.ietfer_name|safe }}
Email: {{ ipr.ietfer_contact_email|safe }}
Info: {{ ipr.ietfer_contact_info|safe }}
Section III: Contact Information for the IETF Participant Whose Personal Belief Triggered the Disclosure in this Template (Optional):
Name: {{ ipr.ietf_contact.name|safe }}
Title: {{ ipr.ietf_contact.title|safe }}
Department: {{ ipr.ietf_contact.department|safe }}
Address1: {{ ipr.ietf_contact.address1|safe }}
Address2: {{ ipr.ietf_contact.address2|safe }}
Telephone: {{ ipr.ietf_contact.telephone|safe }}
Fax: {{ ipr.ietf_contact.fax|safe }}
Email: {{ ipr.ietf_contact.email|safe }}
Section IV: IETF Document or Working Group Contribution to Which Patent Disclosure Relates
RFC Number(s): {% for doc in ipr.rfcs.all %}{{ doc.document.rfc_number|safe }} ({{ doc.document.title|safe }}){% if not forloop.last %}, {% endif %}{% endfor %}
Internet-Draft(s): {% for doc in ipr.drafts.all %}{{ doc.document.filename|safe }} ({{ doc.document.title|safe }}){% if not forloop.last %}, {% endif %}{% endfor %}
{% endif %}{% if ipr|to_class_name == "HolderIprDisclosure" or ipr|to_class_name == "ThirdPartyIprDisclosure" %}Section {% cycle section %}. IETF Document or Working Group Contribution to Which Patent Disclosure Relates
Related Document(s): {% for rel in ipr.iprdocrel_set.all %}{{ rel.document.name|safe }} ({{ rel.document.document.title|safe }}){% if not forloop.last %}, {% endif %}{% endfor %}
Designations for Other Contributions: {{ ipr.other_designations|safe }}
Section V: Disclosure of Patent Information (i.e., patents or patent applications required to be disclosed by Section 6 of RFC 3979)
{% endif %}{% if ipr|to_class_name != "GenericIprDisclosure" %}Section {% cycle section %}. Disclosure of Patent Information (i.e., patents or patent applications required to be disclosed by Section 6 of RFC 3979)
A. For granted patents or published pending patent applications, please provide the following information:
Patent, Serial, Publication, Registration, or Application/File number(s): {{ ipr.patents|safe }}
Date(s) granted or applied for: {{ ipr.date_applied|safe }}
Country: {{ ipr.country|safe }}
Additional Note(s):
{{ ipr.notes|safe }}
Patent, Serial, Publication, Registration, or Application/File number(s): {{ ipr.patent_info|safe }}
B. Does your disclosure relate to an unpublished pending patent application? {{ ipr.get_is_pending_display|safe }}
{# missing ipr.applies_to_all #}
C. If an Internet-Draft or RFC includes multiple parts and it is not reasonably apparent which part of such Internet-Draft or RFC is alleged to be covered by the patent information disclosed in Section V(A) or V(B), it is helpful if the discloser identifies here the sections of the Internet-Draft or RFC that are alleged to be so covered:
{{ ipr.document_sections|safe }}
B. Does your disclosure relate to an unpublished pending patent application? {% if ipr.has_patent_pending %} Yes{% else %} No{% endif %}.
Section VI: Licensing Declaration
{% endif %}{% if ipr|to_class_name == "HolderIprDisclosure" %}Section {% cycle section %}. Licensing Declaration
The Patent Holder states that, upon approval by the IESG for publication as an RFC of the relevant IETF specification, its position with respect to licensing any patent claims contained in the patent(s) or patent application(s) disclosed above that would be necessary to implement the technology required by such IETF specification ("Patent Claims"), for the purpose of implementing the specification, is as follows(select one licensing declaration option only):
The Patent Holder states that, upon approval by the IESG for publication as an RFC of the
relevant IETF specification, its position with respect to licensing any patent claims
contained in the patent(s) or patent application(s) disclosed above that would be
necessary to implement the technology required by such IETF specification ("Patent Claims"),
for the purpose of implementing the specification, is as follows(select one licensing
declaration option only):
{{ ipr.licensing.desc|safe|indent }}
Selection:
{{ ipr.get_licensing_option_display|safe }}
{% if ipr.stdonly_license %}
{{ ipr.stdonly_license|safe }}
Above licensing declaration is limited solely to standards-track IETF documents.
{% endif %}
Licensing information, comments, notes or URL for further information:
{{ ipr.comments|safe }}
{{ ipr.comments|safe|indent }}
Section VII: Contact Information of Submitter of this Form (if different from IETF Participant in Section III above)
Name: {{ ipr.submitter.name|safe }}
Title: {{ ipr.submitter.title|safe }}
Department: {{ ipr.submitter.department|safe }}
Address1: {{ ipr.submitter.address1|safe }}
Address2: {{ ipr.submitter.address2|safe }}
Telephone: {{ ipr.submitter.telephone|safe }}
Fax: {{ ipr.submitter.fax|safe }}
Email: {{ ipr.submitter.email|safe }}
{% endif %}{% if ipr|to_class_name == "NonDocSpecificIprDisclosure" or ipr|to_class_name == "GenericIprDisclosure" %}Section {% cycle section %}. Statement
{{ ipr.statement|safe }}
{% endif %}Section {% cycle section %}. Contact Information of Submitter of this Form
Name: {{ ipr.submitter_name|safe }}
Email: {{ ipr.submitter_email|safe }}
Section VIII: Other Note(s)
{{ ipr.other_notes|safe }}
Section {% cycle section %}. Other Note(s)
{{ ipr.notes|safe }}
{% endautoescape %}

View file

@ -0,0 +1,28 @@
{% extends "base.html" %}
{% load ietf_filters %}
{# Copyright The IETF Trust 2007, All Rights Reserved #}
{% block title %}IPR Details - {{ ipr.title }}{% endblock %}
{% block pagehead %}
<meta name="description" content="IPR disclosure #{{ipr.ipr_id}}: {{ ipr.title }} ({{ ipr.time|date:"Y" }})" />
<link rel="stylesheet" type="text/css" href="/css/jquery-ui-themes/jquery-ui-1.8.11.custom.css"></link>
<link rel="stylesheet" type="text/css" href="/css/ipr.css"></link>
{% endblock %}
{% block content %}
<h1>{{ ipr.title }}<br/>{{ name }}</h1>
<div id="mytabs" class="yui-navset">
<ul class="yui-nav">
{% for name, t, url, active, tooltip in tabs %}
<li {% if t == selected %}class="selected"{% endif %}{% if tooltip %}title="{{tooltip}}"{% endif %}{% if not active %}class="disabled"{% endif %}><a{% if active %} href="{{ url }}"{% endif %}><em>{{ name }}</em></a></li>
{% endfor %}
</ul>
</div>
{% block tab_content %}
{% endblock %} <!-- tab_content -->
{% endblock %}

View file

@ -1,46 +1,20 @@
{% extends "base.html" %}
{# Copyright The IETF Trust 2007, All Rights Reserved #}
{% load ietf_filters %}
{% block title %}IPR Details - Form{% endblock %}
{% block bodyAttrs %}
{% if section_list.holder_contact %}onload="toggle_submitter_info('holder')"{% endif %}
{% if section_list.ietf_contact %}onload="toggle_submitter_info('ietf')"{% endif %}
{% endblock bodyAttrs %}
{% load ipr_filters %}
{% block morecss %}
table.ipr { margin-top: 1em; }
.ipr .light td { background: #eeeeee; }
.ipr .dark td { background: #dddddd; }
.ipr th { background: #2647a0; color: white; }
.ipr { width: 101ex; border: 0; border-collapse: collapse; }
.ipr th, .ipr td { padding: 3px 6px; text-align: left; }
.ipr tr { vertical-align: top; }
.ipr td.iprlabel { width: 18ex; }
.iprdata { font-weight: bold; }
{% block title %}New IPR - Form{% endblock %}
.iprdata li { list-style:none;}
.required { color: red; float: right; padding-top: 0.7ex; font-size: 130%; }
.errorlist { background: red; color: white; padding: 0.2ex 0.2ex 0.2ex 0.5ex; border: 0px; margin: 0px; }
ul.errorlist { margin: 0px; }
{% block pagehead %}
<link rel="stylesheet" type="text/css" href="/css/token-input.css"></link>
<link rel="stylesheet" type="text/css" href="/css/ipr.css"></link>
{% endblock %}
{% block content %}
{% include "ipr/js.html" %}
<h1>The Patent Disclosure and Licensing Declaration Template for {{ section_list.disclosure_type }}</h1>
{% if section_list.generic %}
<p>This document is an IETF IPR Patent Disclosure and Licensing
Declaration Template and is submitted to inform the IETF of a) patent
or patent application information that is not related to a specific
IETF document or contribution, 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.</p>
{% endif %}
{% if section_list.specific %}
{% if form.instance|to_class_name == "HolderIprDisclosure" %}
<h1>The Patent Disclosure and Licensing Declaration Template for Specific IPR Disclosures</h1>
<p>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
@ -49,9 +23,9 @@ 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.</p>
{% endif %}
{% if section_list.third_party %}
{% elif form.instance|to_class_name == "ThirdPartyIprDisclosure" %}
<h1>The Patent Disclosure and Licensing Declaration Template for Third Party IPR Disclosures</h1>
<p>This form is used to let the IETF know about patent information
regarding an IETF document or contribution when the person letting the
IETF know about the patent has no relationship with the patent owners.
@ -59,16 +33,24 @@ Click <a href="https://datatracker.ietf.org/ipr/new-specific">here</a>
if you want to disclose information about patents or patent
applications where you do have a relationship to the patent owners or
patent applicants.</p>
{% endif %}
{% if section_list.also_specific %}
{% else %}
<h1>The Patent Disclosure and Licensing Declaration Template for Generic IPR Disclosures</h1>
<p>This document is an IETF IPR Patent Disclosure and Licensing
Declaration Template and is submitted to inform the IETF of a) patent
or patent application information that is not related to a specific
IETF document or contribution, 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.</p>
<p>Note: According to Section 6.4.3 of
<a href="http://www.ietf.org/rfc/rfc3979.txt">RFC 3979</a>,
"Intellectual Property Rights in IETF Technology," you
are still required to file specific disclosures on IPR unless your
generic disclosure satisfies certain conditions. Please see the
RFC for details.</p>
{% endif %}
{% endif %}
<p>If you wish to submit your IPR disclosure by e-mail, then please send
it to <a href="mailto:ietf-ipr@ietf.org">ietf-ipr@ietf.org</a>.
@ -80,304 +62,298 @@ will be posted, but will be marked as "non-compliant".</p>
<form name="form1" method="post">{% csrf_token %}
{% if ipr.errors %}
{% if form.errors %}
<p class="errorlist">
There were errors in the submitted form -- see below. Please correct these and resubmit.
{% if ipr.non_field_errors %}
<ul class="errorlist">
{% for error in ipr.non_field_errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
There were errors in the submitted form -- see below. Please correct these and resubmit.
{% if form.non_field_errors %}
<ul class="errorlist">
{% for error in form.non_field_errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
</p>
{% endif %}
<p class="formlegend">
Fields marked with "*" are required.
</p>
</blockquote>
<p class="formlegend">Fields marked with "*" are required.</p>
{% if section_list.holder %}
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}">
<th colspan=2>
{% cycle I,II,III,IV,V,VI,VII,VIII as section %}.
{% if section_list.third_party %}Possible{% endif %}
Patent Holder/Applicant ("Patent Holder")
</th>
</tr>
<tr class="{% cycle row_parity %}">
<td class="iprlabel">Legal Name:</td> <td class="iprdata">{{ ipr.legal_name.errors }} <span class="required">*</span> {{ ipr.legal_name }}</td>
</tr>
</table>
{% endif %}
<tr class="{% cycle dark,light as row_parity %}"><th colspan=2>Updates</th></tr>
<tr class="{% cycle row_parity %}"><td colspan=2>If this disclosure <b>updates</b> another disclosure(s) identify here which one(s).
Leave this field blank if this disclosure does not update any prior disclosures.
Note: Updates to IPR disclosures must only be made by authorized
representatives of the original submitters. Updates will automatically
be forwarded to the current Patent Holder's Contact and to the Submitter
of the original IPR disclosure.</td></tr>
{% if section_list.holder_contact %}
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}"><th colspan="2">
{% cycle section %}.
Patent Holder's Contact for License Application
</th>
</tr>
{% for field in ipr.holder_contact %}
{% if field.name != "update_auth" %}
<tr class="{% cycle row_parity %}"><td class="iprlabel">{{field.label }}:</td><td class="iprdata">{{ field.errors }} {% if field.field.required %}<span class="required">*</span>{%endif%} {{ field }}</td></tr>
{% endif %}
{% endfor %}
</table>
{% endif %}
{% if section_list.ietf_contact %}
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}">
<th colspan="2" >
{% cycle section %}.
Contact Information for the IETF Participant Whose Personal Belief Triggered this Disclosure:
</th>
</tr>
{% for field in ipr.ietf_contact %}
{% if field.name != "update_auth" %}
<tr class="{% cycle row_parity %}"><td class="iprlabel">{{field.label }}:</td><td class="iprdata">{{ field.errors }} {% if field.field.required %}<span class="required">*</span>{%endif%} {{ field }}</td></tr>
{% endif %}
{% endfor %}
</table>
{% endif %}
{% if section_list.ietf_doc %}
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}">
<th colspan="2" >
<span class="required">*</span>
{% cycle section %}.
IETF Document or Other Contribution to Which this IPR Disclosure Relates:
</th>
</tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">RFC Numbers:</td><td class="iprdata">{{ ipr.rfclist.errors }} {{ ipr.rfclist }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">I-D Filenames (draft-...):</td><td class="iprdata">{{ ipr.draftlist.errors}} {{ ipr.draftlist }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Designations for Other Contributions:</td><td class="iprdata">{{ ipr.other_designations.errors }} {{ ipr.other_designations }}</td></tr>
</table>
{% endif %}
{% if section_list.patent_info %}
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}">
<th colspan="2" >
{% cycle section %}.
{% if section_list.generic %}
Disclosure of Patent Information (i.e., patents or patent
applications required to be disclosed by Section 6 of RFC3979)
{% endif %}
{% if section_list.specific %}
Disclosure of Patent Information (i.e., patents or patent
applications required to be disclosed by Section 6 of RFC3979)
{% endif %}
{% if section_list.third_party %}
Disclosure of Patent Information, if known (i.e., patents or
patent applications required to be disclosed by Section 6 of RFC3979)
{% endif %}
</th>
</tr>
{% if ipr.patents or ipr.notes %}
<tbody class="{% cycle row_parity %}">
<tr>
<td colspan="2">
A. For granted patents or published pending patent applications,
please provide the following information:</td>
</tr>
<tr><td class="iprlabel">Patent, Serial, Publication, Registration,
or Application/File number(s): </td><td class="iprdata">{{ ipr.patents.errors }} <span class="required">*</span> {{ ipr.patents }}</td></tr>
</tbody>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Date(s) granted or applied for: </td><td class="iprdata">{{ ipr.date_applied.errors }} <span class="required">*</span> {{ ipr.date_applied }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Country: </td><td class="iprdata">{{ ipr.country.errors }} <span class="required">*</span> {{ ipr.country }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Additional Notes: </td><td class="iprdata">{{ ipr.notes.errors }} {{ ipr.notes }}</td></tr>
<tr class="{% cycle row_parity %}">
<td colspan="2">
B. Does your disclosure relate to an unpublished pending patent application?:
<div class="iprdata">{{ ipr.is_pending.errors }} {{ ipr.is_pending }}</div>
</td>
</tr>
<tbody class="{% cycle row_parity %}">
{% if section_list.generic %}
<tr class="{% cycle row_parity %}">
<td colspan="2">
C. Does this disclosure apply to all IPR owned by
the submitter?:
<div class="iprdata">{{ ipr.applies_to_all.errors }} {{ ipr.applies_to_all }}</div>
</td>
</tr>
{% else %}
<tr class="{% cycle row_parity %}">
<td colspan="2">
C. If an Internet-Draft or RFC includes multiple parts and it is not
reasonably apparent which part of such Internet-Draft or RFC is alleged
to be covered by the patent information disclosed in Section
V(A) or V(B), it is helpful if the discloser identifies here the sections of
the Internet-Draft or RFC that are alleged to be so
covered:
</td>
</tr>
{% if ipr.document_sections %}
<tr class="{% cycle row_parity %}"><td class="iprlabel"></td><td><b>{{ ipr.document_sections.errors }} {{ ipr.document_sections }}</b></td></tr>
{% else %}
<tr class="{% cycle row_parity %}"><td class="iprlabel"></td><td></span><i>No information submitted</i></td></tr>
{% endif %}
{% endif %}
</tbody>
{% else %}
<tr class="{% cycle row_parity %}"><td class="iprlabel"></td><td><b>This disclosure relates to an unpublished pending patent application.</b></td></tr>
{% endif %}
</table>
<tr class="{% cycle row_parity %}">
<td class="iprlabel">Updates:</td>
<td class="iprdata">{{ form.updates.errors }}{{ form.updates }}</td>
</tr>
{% if user|has_role:"Secretariat" %}
<tr class="{% cycle row_parity %}">
<td class="iprlabel">{{ form.compliant.label }}:</td><td class="iprdata">{{ form.compliant }} This disclosure complies with RFC 3979</td>
</tr>
{% else %}
<input type="hidden" id="id_compliant" name="compliant" value="checked" />
{% endif %}
</table>
<br>
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}">
<th colspan=2>
{% cycle I,II,III,IV,V,VI,VII,VIII as section %}.
{% if form.instance|to_class_name == "ThirdPartyIprDisclosure" %}Possible{% endif %}
Patent Holder/Applicant ("Patent Holder")
</th>
</tr>
<tr class="{% cycle row_parity %}">
<td class="iprlabel">Legal Name:</td> <td class="iprdata">{{ form.holder_legal_name.errors }} <span class="required">*</span> {{ form.holder_legal_name }}</td>
</tr>
</table>
{% if form.holder_contact_name %}
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}">
<th colspan="2">
{% cycle section %}.
Patent Holder's Contact for License Application
</th>
</tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Name:</td><td class="iprdata">{{ form.holder_contact_name.errors }} <span class="required">*</span> {{ form.holder_contact_name }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Email:</td><td class="iprdata">{{ form.holder_contact_email.errors }} <span class="required">*</span> {{ form.holder_contact_email }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Other Info:<br>(address,phone,etc)</td><td class="iprdata">{{ form.holder_contact_info.errors }}{{ form.holder_contact_info }}</td></tr>
</table>
{% endif %}
{% if form.ietfer_name %}
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}">
<th colspan="2" >
{% cycle section %}.
Contact Information for the IETF Participant Whose Personal Belief Triggered this Disclosure:
</th>
</tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Name:</td><td class="iprdata">{% if form.instance|to_class_name == "ThirdPartyIprDisclosure" %}<span class="required">*</span>{% endif %}{{ form.ietfer_name.errors }}{{ form.ietfer_name }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Email:</td><td class="iprdata">{% if form.instance|to_class_name == "ThirdPartyIprDisclosure" %}<span class="required">*</span>{% endif %}{{ form.ietfer_contact_email.errors }}{{ form.ietfer_contact_email }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Other Info:<br>(address,phone,etc)</td><td class="iprdata">{{ form.ietfer_contact_info.errors }}{{ form.ietfer_contact_info }}</td></tr>
</table>
{% endif %}
<!-- Begin Contribution Section -->
{% if type != "generic" %}
<table id="id_contribution" class="ipr">
<col width="20%">
<col width="50%">
<col width="15%">
<col width="15%">
<tr class="{% cycle dark,light as row_parity %}">
<th colspan="4" >
<span class="required">*</span>
{% cycle section %}.
IETF Document or Other Contribution to Which this IPR Disclosure Relates:
</th>
</tr>
<tr class="{% cycle row_parity %}">
<td colspan="4">
If an Internet-Draft or RFC includes multiple parts and it is not
reasonably apparent which part of such Internet-Draft or RFC is alleged
to be covered by the patent information disclosed in Section
V(A) or V(B), it is helpful if the discloser identifies here the sections of
the Internet-Draft or RFC that are alleged to be so
covered:
</td>
</tr>
{{ rfc_formset.management_form }}
{% for rfc in rfc_formset %}
<tr class="{% cycle row_parity %} rfc_row">
<td class="iprlabel">RFC Name:{% if forloop.last %}<div><a id="rfc_add_link" href="javascript:void(0)">Add More</a></div>{% endif %}</td>
<td class="iprdata">{{ rfc.id }}{{ rfc.document.errors }}{{ rfc.document }}</td><td colspan="2" class="mini">{{ rfc.sections.errors }}{{ rfc.sections }}<div>Sections</div></td>
</tr>
{% endfor %}
{{ draft_formset.management_form }}
{% for draft in draft_formset %}
<tr class="{% cycle row_parity %} draft_row">
<td class="iprlabel">I-D Filename:{% if forloop.last %}<div><a id="draft_add_link" href="javascript:void(0)">Add More</a></div>{% endif %}</td>
<td class="iprdata">{{ draft.id }}{{ draft.document.errors }}{{ draft.document }}</td><td class="mini">{{ draft.revisions.errors }}{{ draft.revisions }}<div>Revisions</div></td><td class="mini">{{ draft.sections.errors }}{{ draft.sections }}<div>Sections</div></td>
</tr>
{% endfor %}
<tr class="{% cycle row_parity %}"><td class="iprlabel">Designations for Other Contributions:</td><td colspan="3" class="iprdata">{{ form.other_designations.errors }} {{ form.other_designations }}</td></tr>
</table>
{% endif %}
<!-- End Contribution Section -->
<!-- Begin Patent Section -->
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}">
<th colspan="2" >
{% cycle section %}.
Disclosure of Patent Information{% if form.instance|to_class_name == "ThirdPartyIprDicslosure" %}, if known{% endif %} (i.e., patents or
patent applications required to be disclosed by Section 6 of RFC3979)
</th>
</tr>
{% if form.patent_info %}
<tbody class="{% cycle row_parity %}">
<tr>
<td colspan="2">
A. For granted patents or published pending patent applications,
please provide the following information:</td>
</tr>
<tr><td class="iprlabel">Patent, Serial, Publication, Registration,
or Application/File number(s), Date(s) granted or applied for, Country,
and any additional notes: </td><td class="iprdata">{{ form.patent_info.errors }}{% if form.statement %}{% else %}<span class="required">*</span>{% endif %}{{ form.patent_info }}</td></tr>
</tbody>
<tr class="{% cycle row_parity %}">
<td colspan="2">
B. {{ form.has_patent_pending.errors }} {{ form.has_patent_pending }}
This disclosure relates to an unpublished pending patent application.
</td>
</tr>
{% else %}
<tr class="{% cycle row_parity %}"><td class="iprlabel"></td><td><b>This disclosure relates to an unpublished pending patent application.</b></td></tr>
{% endif %} <!-- form.patent_info -->
</table>
<!-- End Patent Section -->
{% if section_list.licensing %}
{% if form.licensing %}
<!-- Not to be shown for third-party disclosures -->
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}">
<th colspan="2" >
{% cycle section %}.
Licensing Declaration
</th>
</tr>
<tbody class="{% cycle row_parity %}">
<tr>
<td colspan="2">
{% if section_list.generic %}
The Patent Holder states that its position with respect
to licensing any patent claims contained in the patent(s) or patent
application(s) disclosed above that would necessarily be infringed by
implementation of a technology required by a relevant IETF specification
("Necessary Patent Claims"), for the purpose of implementing such
specification, is as follows (select one licensing declaration option only):
{% endif %}
{% if section_list.specific %}
The Patent Holder states that its position with respect
to licensing any patent claims contained in the patent(s) or patent
application(s) disclosed above that would necessarily be infringed by
implementation of the technology required by the relevant IETF specification
("Necessary Patent Claims"), for the purpose of implementing such
specification, is as follows (select one licensing declaration option only):
{% endif %}
{% if section_list.third_party %}
The Patent Holder states that its position with respect
to licensing any patent claims contained in the patent(s) or patent
application(s) disclosed above that would necessarily be infringed by
implementation of the technology required by the relevant IETF specification
("Necessary Patent Claims"), for the purpose of implementing such
specification, is as follows (select one licensing declaration option only):
{% endif %}
</td>
</tr>
<tr>
<td colspan="2">
<span class="iprdata">{{ ipr.licensing_option.errors }} {{ ipr.licensing_option }}</span>
</td>
</tr>
</tbody>
<tr class="{% cycle row_parity %}">
<td></td><td class="iprdata"> {{ ipr.stdonly_license.errors }}
{{ ipr.stdonly_license }}
Above licensing declaration is limited solely to standards-track IETF documents.
</td>
</tr>
<tbody class="{% cycle row_parity %}">
<tr>
<td colspan="2">
Licensing information, comments, notes, or URL for further information:
</td>
</tr>
<tr ><td class="iprlabel"> </td><td class="iprdata">{{ ipr.comments.errors }} {{ ipr.comments }}</td></tr>
</tbody>
{% if ipr.lic_checkbox %}
<tr class="{% cycle row_parity %}">
<td colspan="2">
<p>
{{ ipr.lic_checkbox.errors }}
{% if ipr.lic_checkbox != 1 %}{{ ipr.lic_checkbox }}{% endif %}
The individual submitting this template represents and warrants that all
terms and conditions that must be satisfied for implementers of any
covered IETF specification to obtain a license have been disclosed in this
IPR disclosure statement.
</p>
{% if section_list.generic %}
<p>
Note: According to
<a href="http://www.ietf.org/rfc/rfc3979.txt?number=3979">RFC 3979</a>,
Section 6.4.3, unless you check the box
above, and choose either option a) or b), you must still file specific
IPR disclosures as appropriate.
</p>
{% endif %}
</td>
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}">
<th colspan="2" >
{% cycle section %}.
Licensing Declaration
</th>
</tr>
<tbody class="{% cycle row_parity %}">
<tr>
<td colspan="2">
The Patent Holder states that its position with respect
to licensing any patent claims contained in the patent(s) or patent
application(s) disclosed above that would necessarily be infringed by
implementation of a technology required by a relevant IETF specification
("Necessary Patent Claims"), for the purpose of implementing such
specification, is as follows (select one licensing declaration option only):
</td>
</tr>
<tr>
<td colspan="2">
<span class="iprdata">{{ form.licensing.errors }} {{ form.licensing }}</span>
</td>
</tr>
</tbody>
<tr class="{% cycle row_parity %}">
<td></td><td class="iprdata"> {{ form.stdonly_license.errors }}
{{ form.stdonly_license }}
Above licensing declaration is limited solely to standards-track IETF documents.
</td>
</tr>
<tbody class="{% cycle row_parity %}">
<tr>
<td colspan="2">
Licensing information, comments, notes, or URL for further information:
</td>
</tr>
<tr ><td class="iprlabel"> </td><td class="iprdata">{{ form.licensing_comments.errors }} {{ form.licensing_comments }}</td></tr>
</tbody>
{% if form.submitter_claims_all_terms_disclosed %}
<tr class="{% cycle row_parity %}">
<td colspan="2">
<p>
{{ form.submitter_claims_all_terms_disclosed.errors }}
{{ form.submitter_claims_all_terms_disclosed }}
The individual submitting this template represents and warrants that all
terms and conditions that must be satisfied for implementers of any
covered IETF specification to obtain a license have been disclosed in this
IPR disclosure statement.
</p>
{% if form.instance|to_class_name == "GenericIprDisclosure" %}
<p>
Note: According to
<a href="http://www.ietf.org/rfc/rfc3979.txt?number=3979">RFC 3979</a>,
Section 6.4.3, unless you check the box
above, and choose either option a) or b), you must still file specific
IPR disclosures as appropriate.
</p>
{% endif %} <!-- generic -->
</td>
</tr>
{% endif %} <!-- form.submitter_claims_all_terms_disclosed -->
<tr class="{% cycle row_parity %}">
<td colspan="2">
<b>Note: The individual submitting this template represents and warrants
that he or she is authorized by the Patent Holder to agree to the
above-selected licensing declaration.</b>
</td>
</tr>
</table>
{% endif %} <!-- form.licensing -->
{% if form.statement %}
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}">
<th colspan="2" >
{% cycle section %}.
Statement
</th>
</tr>
<tbody class="{% cycle row_parity %}">
<tr>
<td colspan="2">
The statement should include any licensing information.
</td>
</tr>
<tr>
<td class="iprlabel">Statement:</td>
<td>
<span class="iprdata">{{ form.statement.errors }} {{ form.statement }}</span>
</td>
</tr>
</tbody>
</table>
{% endif %} <!-- form.statement (Generic and NonDocSpecific) -->
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}">
<th colspan="2" >
{% cycle section %}.
Contact Information of Submitter of this Form (if different from the Contact Information above)
</th>
</tr>
<tr class="{% cycle row_parity %}"><td colspan="2">Same as in section II above: {{ form.same_as_ii_above }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Name:</td><td class="iprdata"><span class="required">*</span>{{ form.submitter_name.errors }}{{ form.submitter_name }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Email:</td><td class="iprdata"><span class="required">*</span>{{ form.submitter_email.errors }}{{ form.submitter_email }}</td></tr>
</table>
</tr>
{% endif %}
<tr class="{% cycle row_parity %}">
<td colspan="2">
<b>Note: The individual submitting this template represents and warrants
that he or she is authorized by the Patent Holder to agree to the
above-selected licensing declaration.</b>
</td>
</tr>
</table>
{% endif %}
{% if section_list.submitter %}
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}">
<th colspan="2" >
{% cycle section %}.
Contact Information of Submitter of this Form (if different from the
Contact Information above)
</th>
</tr>
{% if ipr.ietf_contact_is_submitter %}
<tbody class="{% cycle row_parity %}">
{% if section_list.holder_contact %}
<tr>
<td colspan="2">
Same as in Section II above:
<input type="checkbox" name="hold_contact_is_submitter" onChange="toggle_submitter_info('holder');" {% if ipr.hold_contact_is_submitter_checked %}checked="checked"{%endif%} >
</td>
</tr>
{% endif %}
{% if section_list.ietf_contact %}
<tr>
<td colspan="2">
Same as in Section III above:
<input type="checkbox" name="ietf_contact_is_submitter" onChange="toggle_submitter_info('ietf');" {% if ipr.ietf_contact_is_submitter_checked %}checked="checked"{%endif%} }} />
</td>
</tr>
{% endif %}
</tbody>
{% endif %}
{% for field in ipr.submitter %}
{% if field.name != "update_auth" %}
<tr class="{% cycle row_parity %}"><td class="iprlabel">{{field.label }}:</td><td class="iprdata">{{ field.errors }} {% if field.field.required %}<span class="required">*</span>{%endif%} {{ field }}</td></tr>
{% endif %}
{% endfor %}
</table>
{% endif %}
{% if section_list.notes %}
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}">
<th colspan="2" >
{% cycle section %}.
Other Notes:
</th>
</tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel"> </td><td class="iprdata">{{ ipr.other_notes.errors }} {{ ipr.other_notes }}</td></tr>
</table>
{% endif %}
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}">
<th colspan="2" >
{% cycle section %}.
Other Notes:
</th>
</tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel"> </td><td class="iprdata">{{ form.notes.errors }} {{ form.notes }}</td></tr>
</table>
<input type="submit" name="submit" value="Submit" />
</form>
{% endblock %}
{% block js %}
{% comment %} <script type="text/javascript" src="/secretariat/js/jquery-ui-1.8.9.min.js"></script> {% endcomment %}
<script type="text/javascript" src="/js/ipr-edit.js"></script>
<script type="text/javascript" src="/js/lib/jquery.tokeninput.js"></script>
<script type="text/javascript" src="/js/tokenized-field.js"></script>
{% endblock %}

View file

@ -0,0 +1,54 @@
{% extends "ipr/details_base.html" %}
{# Copyright The IETF Trust 2007, All Rights Reserved #}
{% load ietf_filters %}
{% load ipr_filters %}
{% block pagehead %}
<link rel="stylesheet" type="text/css" href="/css/ipr.css"></link>
{% endblock %}
{% block tab_content %}
<h2>Disclosure history</h2>
{% if user|has_role:"Area Director,Secretariat,IANA,RFC Editor" %}
<div class="history-actions">
<a class="button" href="{% url "ipr_add_comment" id=ipr.id %}">Add comment</a>
<a class="button" href="{% url "ipr_add_email" id=ipr.id %}">Add email</a>
</div>
{% endif %}
<table class="ietf-table history">
<tr><th class="date-column">Date</th><th>Type</th><th>By</th><th>Text</th></tr>
{% for e in events %}
<tr class="{% cycle oddrow,evenrow %}" id="history-{{ e.pk }}">
<td class="date-column">{{ e.time|date:"Y-m-d" }}</td>
<td>{{ e.type }}
{% if e.response_due %}
{% if e.response_past_due %}
<img src="/images/warning.png" title="Response overdue"/>
{% endif %}
{% endif %}
</td>
<td>{{ e.by }}</td>
{% if e.message %}
<td>{{ e.message|render_message_for_history|format_history_text:"100" }}
{% if e.response_due %}
<br>Response Due: {{ e.response_due|date:"Y-m-d" }}
{% endif %}
{% else %}
<td>{{ e.desc|format_history_text }}
{% endif %}
</td>
</tr>
{% endfor %}
</table>
{% endblock %} <!-- tab_content -->
{% block content_end %}
<script type="text/javascript" src="/js/history.js"></script>
<script type="text/javascript" src="/js/snippet.js"></script>
{% endblock content_end %}

View file

@ -0,0 +1,290 @@
{% extends "ipr/details_base.html" %}
{# Copyright The IETF Trust 2007, All Rights Reserved #}
{% load ietf_filters %}
{% load ipr_filters %}
{% block tab_content %}
{% if not ipr.compliant %}
<p style="color:red;">This IPR disclosure does not comply with the formal requirements of Section 6,
"IPR Disclosures," of RFC 3979, "Intellectual Property Rights in IETF Technology."
</p>
{% endif %}
{% if ipr.has_legacy_event %}
<p>The text of the original IPR disclosure is available in the <a href="{% url "ietf.ipr.views.history" id=ipr.id %}">disclosure history</a>.</p>
{% endif %}
<p>Only those sections of the relevant entry form where the submitter provided information are displayed.</p>
{% for item in ipr.relatedipr_source_set.all %}
<p>This IPR disclosure updates IPR disclosure ID #{{ item.target.id }},
{% if item.target.state.slug == "removed" %}
"{{ item.target.title }}", which was removed at the request of the submitter.
{% else %}
"<a href="{% url "ietf.ipr.views.show" id=item.target.id %}">{{ item.target.title }}</a>".
{% endif %}
</p>
{% endfor %}
{% for item in ipr.relatedipr_target_set.all %}
{% if item.source.state.slug == "posted" %}
<p>
This IPR disclosure has been updated by IPR disclosure ID #{{ item.source.id }},
"<a href="{% url "ietf.ipr.views.show" id=item.source.id %}">{{ item.source.title }}</a>".
</p>
{% endif %}
{% endfor %}
{% if ipr.state_id == 'posted' %}
<p><a href="{% url "ietf.ipr.views.update" ipr.id %}" rel="nofollow">Update this IPR disclosure</a>. Note: Updates to IPR disclosures must only be made by authorized
representatives of the original submitters. Updates will automatically
be forwarded to the current Patent Holder's Contact and to the Submitter
of the original IPR disclosure.</p>
{% endif %}
<p><strong>Submitted Date: {{ ipr.time|date:"F j, Y" }}
{% if user|has_role:"Secretariat" %}<br>State: {{ ipr.state }}{% endif %}
</strong></p>
{% if user|has_role:"Secretariat" and ipr.update_notified_date %}
<span class="alert">This update was notified to the submitter of the IPR that is being updated on: {{ ipr.update_notified_date|date:"Y-m-d" }}</span>
{% endif %}
<!-- Admin action menu -->
{% if user|has_role:"Secretariat" %}
<div id="admin-menu">
{% if ipr.updates and ipr.state_id == 'pending' and not ipr.update_notified_date %}
<a class="admin-action" href="{% url "ipr_notify" id=ipr.id type="update"%}" title="Notify the submitter of IPR that is being updated">Notify</a>
{% endif %}
{% if ipr.updates and ipr.state_id == 'pending' and ipr.update_notified_date or not ipr.updates and ipr.state_id == 'pending' %}
<a class="admin-action" href="{% url "ipr_post" id=ipr.id %}">Post</a>
{% endif %}
<a class="admin-action" href="{% url "ipr_email" id=ipr.id %}" title="Email submitter of this disclsoure">Email</a>
<a class="admin-action" href="{% url "ipr_edit" id=ipr.id %}">Edit</a>
<a class="admin-action" href="{% url "ipr_state" id=ipr.id %}">Change State</a>
</div>
{% endif %}
<!-- Begin Sections -->
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}">
<th colspan="2">
{% cycle I,II,III,IV,V,VI,VII,VIII as section %}.
{% if ipr|to_class_name == "ThirdPartyIprDisclosure" %}Possible{% endif %}
Patent Holder/Applicant ("Patent Holder")
</th>
</tr>
<tr class="{% cycle row_parity %}">
<td class="iprlabel">Legal Name:</td> <td class="iprdata">{{ ipr.holder_legal_name }}</td>
</tr>
</table>
{% if ipr.holder_contact_name or ipr.holder_contact_info %}
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}"><th colspan="2">
{% cycle section %}.
Patent Holder's Contact for License Application
</th>
</tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Name:</td><td class="iprdata">{{ ipr.holder_contact_name }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Email:</td><td class="iprdata">{{ ipr.holder_contact_email }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Other Info:<br>(address,phone,etc)</td> <td class="iprdata">{{ ipr.holder_contact_info|linebreaks }}</td></tr>
</table>
{% endif %}
{% if ipr.ietfer_name or ipr.ietfer_contact_info %}
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}">
<th colspan="2" >
{% cycle section %}.
Contact Information for the IETF Participant Whose Personal Belief Triggered this Disclosure:
</th>
</tr>
{% if ipr.ietfer_name %}
<tr class="{% cycle row_parity %}"><td class="iprlabel">Name:</td><td class="iprdata">{{ ipr.ietfer_name }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Email:</td><td class="iprdata">{{ ipr.ietfer_contact_email }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Other Info:<br>(address,phone,etc)</td> <td class="iprdata">{{ ipr.ietfer_contact_info|linebreaks }}</td></tr>
{% else %}
<tr class="{% cycle row_parity %}"><td colspan="2"><i>No information submitted</i></td></tr>
{% endif %}
</table>
{% endif %}
{% if ipr.iprdocrel_set.all or ipr.other_designations %}
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}">
<th colspan="2" >
{% cycle section %}.
IETF Document or Other Contribution to Which this IPR Disclosure Relates:
</th>
</tr>
{% for iprdocrel in ipr.iprdocrel_set.all %}
<tr class="{% cycle row_parity %}">
<td class="iprlabel">{{ iprdocrel.doc_type }}:</td>
<td class="iprdata">"{{ iprdocrel.document.document.title }}"<br />({{ iprdocrel.formatted_name }}){% if iprdocrel.revisions or iprdocrel.sections%}<br />{% if iprdocrel.revisions %}Revisions: {{ iprdocrel.revisions }}&nbsp&nbsp&nbsp&nbsp{% endif %}{% if iprdocrel.sections %}Sections: {{ iprdocrel.sections }}{% endif %}{% endif %}</td>
</tr>
{% endfor %}
{% if ipr.other_designations %}
<tr class="{% cycle row_parity %}"><td class="iprlabel">Designations for Other Contributions:</td><td class="iprdata">{{ ipr.other_designations }}</td></tr>
{% endif %}
</table>
{% endif %}
{% if ipr.patent_info %}
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}">
<th colspan="2" >
{% cycle section %}.
Disclosure of Patent Information (i.e., patents or patent
applications required to be disclosed by Section 6 of RFC 3979)
</th>
</tr>
{% if ipr.patent_info %}
<tbody class="{% cycle row_parity %}">
<tr>
<td colspan="2">
A. For granted patents or published pending patent applications,
please provide the following information:</td>
</tr>
<tr><td class="iprlabel">Patent, Serial, Publication, Registration,
or Application/File number(s): </td><td class="iprdata">{{ ipr.patent_info|linebreaks }}</td></tr>
</tbody>
<tr class="{% cycle row_parity %}">
<td colspan="2">
B. Does this disclosure relate to an unpublished pending patent application?:
<span class="iprdata">{{ ipr.has_patent_pending|yesno }}</span>
</td>
</tr>
{% else %}
<tr class="{% cycle row_parity %}"><td class="iprlabel"></td><td class="iprdata">This disclosure relates to an unpublished pending patent application.</td></tr>
{% endif %}
</table>
{% endif %}
{% if ipr.licensing %}
<!-- Not to be shown for third-party disclosures -->
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}">
<th colspan="2" >
{% cycle section %}.
Licensing Declaration
</th>
</tr>
<tbody class="{% cycle row_parity %}">
<tr>
<td colspan="2">
The Patent Holder states that its position with respect
to licensing any patent claims contained in the patent(s) or patent
application(s) disclosed above that would necessarily be infringed by
implementation of the technology required by the relevant IETF specification
("Necessary Patent Claims"), for the purpose of implementing such
specification, is as follows(select one licensing declaration option only):
</td>
</tr>
<tr>
<td></td><td class="iprdata" colspan="2">{% if ipr.licensing.slug == "later" %}{{ ipr.licensing.desc|slice:"2:"|slice:":43" }}{% else %}{{ ipr.licensing.desc|slice:"2:" }}{% endif %}</td>
</tr>
</tbody>
<tbody class="{% cycle row_parity %}">
<tr>
<td colspan="2">
Licensing information, comments, notes, or URL for further information:
</td>
</tr>
{% if ipr.licensing_comments %}
<tr ><td class="iprlabel"> </td><td class="iprdata">{{ ipr.licensing_comments|linebreaks }}</td></tr>
{% else %}
<tr ><td class="iprlabel"> </td><td><i>No information submitted</i></td></tr>
{% endif %}
</tbody>
{% if ipr.lic_checkbox %}
<tr class="{% cycle row_parity %}">
<td colspan="2">
<p>
{% if ipr.lic_checkbox != 1 %}{{ ipr.lic_checkbox }}{% endif %}
The individual submitting this template represents and warrants that all
terms and conditions that must be satisfied for implementers of any
covered IETF specification to obtain a license have been disclosed in this
IPR disclosure statement.
</p>
{% if ipr|to_class_name == "GenericIprDisclosure" %}
<p>
Note: According to
<a href="http://www.ietf.org/rfc/rfc3979.txt?number=3979">RFC 3979</a>,
Section 6.4.3, unless you check the box
above, and choose either option a) or b), you must still file specific
IPR disclosures as appropriate.
</p>
{% endif %}
</td>
</tr>
{% endif %}
<tr class="{% cycle row_parity %}">
<td colspan="2">
<span class="iprdata">Note: The individual submitting this template represents and warrants
that he or she is authorized by the Patent Holder to agree to the
above-selected licensing declaration.</span>
</td>
</tr>
</table>
{% elif ipr.statement %}
<table class="ipr data">
<tr class="{% cycle dark,light as row_parity %}">
<th colspan="2" >
{% cycle section %}.
Statement
</th>
</tr>
<tbody class="{% cycle row_parity %}">
<tr>
<td class="iprdata" colspan="2">{{ ipr.statement }}</td>
</tr>
</table>
{% endif %}
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}"><th colspan="2">
{% cycle section %}.
Contact Information of Submitter of this Form
</th>
</tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Name:</td><td class="iprdata">{{ ipr.submitter_name }}</td></tr>
<tr class="{% cycle row_parity %}"><td class="iprlabel">Email:</td><td class="iprdata">{{ ipr.submitter_email }}</td></tr>
</table>
{% if ipr.notes %}
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}">
<th colspan="2" >
{% cycle section %}.
Other Notes:
</th>
</tr>
{% if ipr.notes %}
<tr class="{% cycle row_parity %}"><td class="iprlabel"> </td><td class="iprdata">{{ ipr.notes|linebreaks }}</td></tr>
{% else %}
<tr class="{% cycle row_parity %}"><td colspan="2"><i>No information submitted</i></td></tr>
{% endif %}
</table>
{% endif %}
{% endblock %} <!-- tab_content -->
{% block js %}
<script type="text/javascript" src="/js/jquery-ui-1.8.11.custom.min.js"></script>
<script type="text/javascript" src="/js/ipr-view.js"></script>
{% endblock %}

View file

@ -20,11 +20,11 @@
<hr />
<ul>
<li><a href="{% url "ietf.ipr.new.new" "specific" %}">File a disclosure about your IPR related to a specific IETF contribution</a></li>
<li><a href="{% url "ietf.ipr.new.new" "generic" %}">File an IPR disclosure that is not related to a specific IETF contribution</a></li>
<li><a href="{% url "ietf.ipr.new.new" "third-party" %}">Notify the IETF of IPR other than your own</a></li>
<li><a href="{% url "ietf.ipr.views.new" "specific" %}">File a disclosure about your IPR related to a specific IETF contribution</a></li>
<li><a href="{% url "ietf.ipr.views.new" "generic" %}">File an IPR disclosure that is not related to a specific IETF contribution</a></li>
<li><a href="{% url "ietf.ipr.views.new" "third-party" %}">Notify the IETF of IPR other than your own</a></li>
<li>To update an existing IPR disclosure, find the original disclosure and select "update this IPR disclosure".</li>
<li><a href="{% url "ietf.ipr.search.search" %}">Search the IPR disclosures</a></li>
<li><a href="{% url "ietf.ipr.views.search" %}">Search the IPR disclosures</a></li>
<li><a href="{% url "ietf.ipr.views.showlist" %}">List of IPR disclosures</a></li>
</ul>

View file

@ -0,0 +1,43 @@
{% extends "base.html" %}
{# Copyright The IETF Trust 2007, All Rights Reserved #}
{% block title %}IPR Email{% endblock %}
{% block pagehead %}
<link rel="stylesheet" type="text/css" href="/css/jquery-ui-themes/jquery-ui-1.8.11.custom.css"></link>
<link rel="stylesheet" type="text/css" href="/css/ipr.css"></link>
{% endblock %}
{% block content %}
<div class="ipr">
<h2>Send email to disclosure submitter</h2>
<form action="" method="post">{% csrf_token %}
<table id="ipr-table">
<th colspan=2>Email Form</th>
{% if form.non_field_errors %}{{ form.non_field_errors }}{% endif %}
{% for field in form.visible_fields %}
<tr>
<td>{{ field.label_tag }}{% if field.field.required %}<span class="required"> *</span>{% endif %}</td>
<td>{{ field.errors }}{{ field }}{% if field.help_text %}<br>{{ field.help_text }}{% endif %}</td>
</tr>
{% endfor %}
</table>
<div class="button-group">
<ul id="announcement-button-list">
<li><button type="submit" name="submit" value="submit">Submit</button></li>
<li><button type="submit" name="submit" value="Cancel">Cancel</button></li>
</ul>
</div> <!-- button-group -->
</form>
</div> <!-- module -->
{% endblock %}
{% block js %}
<script type="text/javascript" src="/js/jquery-ui-1.8.11.custom.min.js"></script>
<script type="text/javascript" src="/js/ipr-email.js"></script>
{% endblock %}

View file

@ -1,63 +0,0 @@
{# Copyright The IETF Trust 2007, All Rights Reserved #}
<script type="text/javascript">
function toggle_submitter_info (src) {
var checked = false;
if (src == 'holder') {
checked = document.form1.hold_contact_is_submitter.checked;
if (checked) {
if (document.form1.ietf_contact_is_submitter)
document.form1.ietf_contact_is_submitter.checked = false;
document.form1.subm_name.value = document.form1.hold_name.value;
document.form1.subm_title.value = document.form1.hold_title.value;
document.form1.subm_department.value = document.form1.hold_department.value;
document.form1.subm_telephone.value = document.form1.hold_telephone.value;
document.form1.subm_fax.value = document.form1.hold_fax.value;
document.form1.subm_email.value = document.form1.hold_email.value;
document.form1.subm_address1.value = document.form1.hold_address1.value;
document.form1.subm_address2.value = document.form1.hold_address2.value;
} else {
document.form1.subm_name.value = document.form1.subm_name.defaultValue;
document.form1.subm_title.value = document.form1.subm_title.defaultValue;
document.form1.subm_department.value = document.form1.subm_department.defaultValue;
document.form1.subm_telephone.value = document.form1.subm_telephone.defaultValue;
document.form1.subm_fax.value = document.form1.subm_fax.defaultValue;
document.form1.subm_email.value = document.form1.subm_email.defaultValue;
document.form1.subm_address1.value = document.form1.subm_address1.defaultValue;
document.form1.subm_address2.value = document.form1.subm_address2.defaultValue;
}
} else if (src == 'ietf') {
checked = document.form1.ietf_contact_is_submitter.checked;
if (checked) {
if (document.form1.hold_contact_is_submitter)
document.form1.hold_contact_is_submitter.checked = false;
document.form1.subm_name.value = document.form1.ietf_name.value;
document.form1.subm_title.value = document.form1.ietf_title.value;
document.form1.subm_department.value = document.form1.ietf_department.value;
document.form1.subm_telephone.value = document.form1.ietf_telephone.value;
document.form1.subm_fax.value = document.form1.ietf_fax.value;
document.form1.subm_email.value = document.form1.ietf_email.value;
document.form1.subm_address1.value = document.form1.ietf_address1.value;
document.form1.subm_address2.value = document.form1.ietf_address2.value;
} else {
document.form1.subm_name.value = document.form1.subm_name.defaultValue;
document.form1.subm_title.value = document.form1.subm_title.defaultValue;
document.form1.subm_department.value = document.form1.subm_department.defaultValue;
document.form1.subm_telephone.value = document.form1.subm_telephone.defaultValue;
document.form1.subm_fax.value = document.form1.subm_fax.defaultValue;
document.form1.subm_email.value = document.form1.subm_email.defaultValue;
document.form1.subm_address1.value = document.form1.subm_address1.defaultValue;
document.form1.subm_address2.value = document.form1.subm_address2.defaultValue;
}
}
document.form1.subm_name.disabled = checked;
document.form1.subm_title.disabled = checked;
document.form1.subm_department.disabled = checked;
document.form1.subm_telephone.disabled = checked;
document.form1.subm_fax.disabled = checked;
document.form1.subm_email.disabled = checked;
document.form1.subm_address1.disabled = checked;
document.form1.subm_address2.disabled = checked;
return true;
}
</script>

View file

@ -1,6 +1,13 @@
{% extends "base.html" %}
{% load ietf_filters %}
{# Copyright The IETF Trust 2007, All Rights Reserved #}
{% block title %}IPR List{% endblock %}
{% block pagehead %}
<link rel="stylesheet" type="text/css" href="/css/ipr.css"></link>
{% endblock %}
{% block content %}
<h1>IETF Page of Intellectual Property Rights Disclosures</h1>
@ -14,12 +21,15 @@ pertain to the implementation or use of the technology described in any IETF doc
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.</p>
<p><a href="{% url "ietf.ipr.views.about" %}">Click here to submit an IPR disclosure</a></p>
<a href="{% url "ietf.ipr.search.search" %}">Search the IPR Disclosures</a>
<a href="{% url "ietf.ipr.views.search" %}">Search the IPR Disclosures</a>
{% if user|has_role:"Secretariat" %}
<br><a href="{% url "ipr_admin_main" %}">Administrative View</a>
{% endif %}
<a name="generic"></a>
<h2>Generic IPR Disclosures</h2>
<table class="ietf-table" width="820">
<tr><th>Date Submitted</th><th width="70">ID #</th><th>Title of IPR Disclosure</th></tr>
<tr><th class="date-column">Submitted</th><th class="id-column">ID #</th><th class="title-column">Title of IPR Disclosure</th></tr>
{% for ipr in generic_disclosures %}
{% include "ipr/list_item.html" %}
{% endfor %}
@ -28,7 +38,7 @@ which any license under such rights might or might not be available; nor does it
<a name="specific"></a>
<h2>Specific IPR Disclosures</h2>
<table class="ietf-table" width="820">
<tr><th>Date Submitted</th><th width="70">ID #</th><th>Title of IPR Disclosure</th></tr>
<tr><th class="date-column">Submitted</th><th class="id-column">ID #</th><th class="title-column">Title of IPR Disclosure</th></tr>
{% for ipr in specific_disclosures %}
{% include "ipr/list_item.html" %}
{% endfor %}
@ -37,7 +47,7 @@ which any license under such rights might or might not be available; nor does it
<a name="notify"></a>
<h2>Specific Third Party IPR Disclosures</h2>
<table class="ietf-table" width="820">
<tr><th>Date Submitted</th><th width="70">ID #</th><th>Title of IPR Disclosure</th></tr>
<tr><th class="date-column">Submitted</th><th class="id-column">ID #</th><th class="title-column">Title of IPR Disclosure</th></tr>
{% for ipr in thirdpty_disclosures %}
{% include "ipr/list_item.html" %}
{% endfor %}

View file

@ -1,46 +1,27 @@
{% load ietf_filters %}
{# Copyright The IETF Trust 2007, All Rights Reserved #}
<tr class="{{ forloop.counter|divisibleby:2|yesno:"oddrow,evenrow" }}">
<td>{{ ipr.submitted_date }}</td>
<td>{{ ipr.ipr_id }}</td>
<td>
{% if ipr.status == 1 %}
<a href="{% url "ietf.ipr.views.show" ipr.ipr_id %}">{{ ipr.title }}</a>
{% else %}
<td class="date-column">{{ ipr.time|date:"Y-m-d" }}</td>
<td class="id-column">{{ ipr.id }}</td>
<td class="title-column">
{% if ipr.state_id == 'posted' %}
<a href="{% url "ietf.ipr.views.show" ipr.id %}">{{ ipr.title }}</a>
{% else %}
{{ ipr.title }}
<br/>This IPR disclosure was removed at the request of the submitter.
<br/>This IPR disclosure was removed at the request of the submitter.
{% endif %}
<br />
{% for item in ipr.updates.all %}
{% if item.updated.status == 1 %}
Updates ID <a href="{% url "ietf.ipr.views.show" item.updated.ipr_id %}">#{{ item.updated.ipr_id }}</a>.<br/>
<br />
{% for item in ipr.relatedipr_source_set.all %}
{% if item.target.state_id == 'posted' %}
Updates ID <a href="{% url "ietf.ipr.views.show" item.target.id %}">#{{ item.target.id }}</a>.<br/>
{% endif %}
{% endfor %}
{% for item in ipr.updated_by.all %}
{% if item.processed == 1 and item.ipr.status != 2 %}
Updated by ID <a href="{% url "ietf.ipr.views.show" item.ipr.ipr_id %}">#{{ item.ipr.ipr_id }}</a>.<br/>
{% endif %}
{% endfor %}
{% endfor %}
{% for item in ipr.relatedipr_target_set.all %}
{% comment %}{% if item.processed == 1 and item.ipr.status != 2 %}{% endcomment %}
{% if item.source.state_id == "posted" %}
Updated by ID <a href="{% url "ietf.ipr.views.show" item.source.id %}">#{{ item.source.id }}</a>.<br/>
{% endif %}
{% endfor %}
</td>
</tr>
{% if ipr.status == 1 %}
{% if ipr.legacy_title_1 %}
<tr class="{{ forloop.counter|divisibleby:2|yesno:"oddrow,evenrow" }}">
<td></td>
<td></td>
<td>
<b>*</b>
<a href="{{ ipr.legacy_url_1 }}">{{ ipr.legacy_title_1 }}</a>
</td>
</tr>
{% endif %}
{% if ipr.legacy_title_2 %}
<tr class="{{ forloop.counter|divisibleby:2|yesno:"oddrow,evenrow" }}">
<td></td>
<td></td>
<td>
<b>*</b>
<a href="{{ ipr.legacy_url_2 }}">{{ ipr.legacy_title_2 }}</a>
</td>
</tr>
{% endif %}
{% endif %}

View file

@ -0,0 +1,31 @@
{% load ietf_filters %}
The Patent Holder states that its position with respect to licensing any patent claims
contained in the patent(s) or patent application(s) disclosed above that would necessarily
be infringed by implementation of the technology required by the relevant IETF
specification ("Necessary Patent Claims"), for the purpose of implementing such
specification, is as follows(select one licensing declaration option only):
{% if option == 1 %}
No License Required for Implementers.
{% elif option == 2 %}
Royalty-Free, Reasonable and Non-Discriminatory License to All Implementers.
{% elif option == 3 %}
Reasonable and Non-Discriminatory License to All Implementers with Possible
Royalty/Fee.
{% elif option == 4 %}
Licensing Declaration to be Provided Later (implies a willingness to commit to the
provisions of a), b), or c) above to all implementers; otherwise, the next option
"Unwilling to Commit to the Provisions of a), b), or c) Above" - must be selected)
{% elif option == 5 %}
Unwilling to Commit to the Provisions of a), b), or c) Above
{% elif option == 6 %}
See text box below for licensing declaration.
{% else %}
None selected.
{% endif %}
{% if extra %}{{ extra|safe|wordwrap:80|indent }}
{% endif %}Licensing information, comments, notes or URL for further information:
{{ info|safe|wordwrap:80|indent }}

View file

@ -1,6 +1,6 @@
{% autoescape off %}A new IPR disclosure has been submitted.
Please check it and post it.
https://datatracker.ietf.org/secr/ipradmin/admin/
https://datatracker.ietf.org/ipr/admin/pending/
{% include "ipr/details.txt" %}
{% endautoescape %}

View file

@ -0,0 +1,23 @@
{% extends "base.html" %}
{% block title %}Send Notification{% endblock %}
{% block pagehead %}
<link rel="stylesheet" type="text/css" href="/css/ipr.css"></link>
{% endblock %}
{% block content %}
<h1>Send Notification about {{ ipr }}</h1>
<form class="send-notification" action="" method="post">{% csrf_token %}
<table>
{{ formset }}
<tr>
<td></td>
<td class="actions">
<input type="submit" value="Send Notification(s)"/>
</td>
</tr>
</table>
</form>
{% endblock %}

View file

@ -0,0 +1,15 @@
{% load ietf_filters %}
To: {{ to_email }}
From: IETF Secretariat <ietf-ipr@ietf.org>
Subject: IPR Disclosure {{ ipr.title }}
Cc: {{ cc_email }}
Dear {{ to_name }}:
{% wordwrap 80 %}
An IPR disclosure that pertains to your {{ doc_info }} was submitted to the IETF Secretariat on {{ ipr.submitted_date|date:"Y-m-d" }} and has been posted on the "IETF Page of Intellectual Property Rights Disclosures" (https://datatracker.ietf.org/ipr/{{ ipr.pk }}/). The title of the IPR disclosure is "{{ ipr.title }}"
{% endwordwrap %}
Thank you
IETF Secretariat

View file

@ -0,0 +1,15 @@
To: {{ to_email }}
From: IETF Secretariat <ietf-ipr@ietf.org>
Subject: Posting of IPR Disclosure
Cc:
Dear {{ to_name }}:
A generic IPR disclosure was submitted to the IETF Secretariat on {{ ipr.submitted_date|date:"Y-m-d" }}
and has been posted on the "IETF Page of Intellectual Property Rights Disclosures"
(https://datatracker.ietf.org/ipr/). The title of the IPR disclosure is
{{ ipr.title }}.
Thank you
IETF Secretariat

View file

@ -0,0 +1,20 @@
To: {{ to_email }}
From: IETF Secretariat <ietf-ipr@ietf.org>
Subject: Posting of IPR {% if ipr.updates %}Updated {% endif %}Disclosure
Cc: {{ cc_email }}
Dear {{ to_name }}:
Your IPR disclosure entitled {{ ipr.title }}
has been posted on the "IETF Page of Intellectual Property Rights Disclosures"
(https://datatracker.ietf.org/ipr/).{% if ipr.updates %}
Your IPR disclosure updates:
{% for rel in ipr.updates %}
IPR disclosure ID #{{ rel.target.pk }}, "{{ rel.target.title }}", which was posted on {{ rel.target.submitted_date }}
{% endfor %}
{% endif %}
Thank you
IETF Secretariat

View file

@ -2,102 +2,18 @@
{# Copyright The IETF Trust 2007, All Rights Reserved #}
{% block title %}IPR Search{% endblock %}
{% block morecss %}
form { clear:both; margin-top:1em;}
label { float:left; width: 200px; }
{% block pagehead %}
<link rel="stylesheet" type="text/css" href="/css/ipr.css"></link>
{% endblock %}
{% block content %}
<h1>IPR Search</h1>
<h2>Document Search</h2>
<div class="ietf-box search-form-box">
<form>
<input type="hidden" name="option" value="document_search">
<label>I-D name (draft-...):</label>
<input type="text" name="document_search" size="30">
<input type="submit" value="SEARCH" >
</form>
<script language="javascript"><!--
function IsNumeric(strString) {
var strValidChars = "0123456789.-";
var strChar;
var blnResult = true;
if (strString.length == 0) return false;
for (i = 0; i < strString.length && blnResult == true; i++)
{
strChar = strString.charAt(i);
if (strValidChars.indexOf(strChar) == -1)
{
blnResult = false;
}
}
return blnResult;
}
function check_numeric(val) {
if (IsNumeric(val)) {
return true;
} else {
alert ("Please enter numerics only");
return false;
}
return false;
}
// -->
</script>
<form name="form_rfc_search">
<input type="hidden" name="option" value="rfc_search">
<label>RFC Number:</label>
<input type="text" name="rfc_search" size="8">
<input type="submit" value="SEARCH" onClick="return check_numeric(document.form_rfc_search.rfc_search.value);">
</form>
</div>
<h2>Keyword Search</h2>
<div class="ietf-box search_form_box">
<form>
<input type="hidden" name="option" value="patent_search">
<label>Name of patent owner/applicant:</label>
<input type="text" name="patent_search" size="30">
<input type="submit" value="SEARCH">
</form>
<form>
<input type="hidden" name="option" value="patent_info_search"/>
<label>Characters in patent information (Full/Partial):</label>
<input type="text" name="patent_info_search" size="30"/>
<input type="submit" value="SEARCH"/>
</form>
<font size="-1" color="red">* The search string must contain at least three characters, including at least one digit, and include punctuation marks. For best results, please enter the entire string, or as much of it as possible.</font>
<form>
<input type="hidden" name="option" value="wg_search">
<label>Working group name:</label>
<select name="wg_search">
<option value="">--Select WG</option>
{% for wg in wgs %}
<option value="{{ wg.acronym }}">{{ wg.acronym }}</option>{% endfor %}
</select>
<input type="submit" value="SEARCH" width="15">
</form>
<form>
<input type="hidden" name="option" value="title_search"/>
<label>Words in document title:</label>
<input type="text" name="title_search" size="30" />
<input type="submit" value="SEARCH" />
</form>
<form>
<input type="hidden" name="option" value="ipr_title_search" />
<label>Words in IPR disclosure title:</label>
<input type="text" name="ipr_title_search" size="30" />
<input type="submit" value="SEARCH" />
</form>
</div>
{% include "ipr/search_form.html" %}
<p><a href="{% url "ietf.ipr.views.showlist" %}">Back to IPR Disclosure Page</a></p>
{% endblock %}
{% block js %}
<script type="text/javascript" src="/js/lib/jquery-1.8.2.min.js"></script>
<script type="text/javascript" src="/js/ipr-search.js"></script>
{% endblock %}

View file

@ -8,7 +8,7 @@
<h3>Please select one of following I-Ds</h3>
<ul>
{% for docalias in docs %}
<li><a href="?option=document_search&id={{ docalias.name }}">{{ docalias.name }}</a></li>
<li><a href="?submit=draft&id={{ docalias.name }}">{{ docalias.name }}</a></li>
{% endfor %}
</ul>
{% endblock %}

View file

@ -2,45 +2,44 @@
{% extends "ipr/search_result.html" %}
{% load ietf_filters %}
{% block search_result %}
<table cellpadding="1" cellspacing="0" border="0">
<table cellpadding="1" cellspacing="0" border="0">
<tr><td colspan="3">Total number of IPR disclosures found: {{ iprs|length }} </td></tr>
{% for ipr in iprs %}
<tr valign="top" bgcolor="#dadada">
<td width="100">{{ ipr.submitted_date }}</td>
<td width="90"><li>ID # {{ ipr.ipr_id }}</li></td>
<td><a href="{% url "ietf.ipr.views.show" ipr_id=ipr.ipr_id %}">"{{ ipr.title }}"</a></td>
</tr>
{% endfor %}
<tr><td colspan="3">Total number of IPR disclosures found: {{ iprs|length }} </td></tr>
{% for ipr in iprs %}
<tr valign="top" bgcolor="#dadada">
<td width="100">{{ ipr.time|date:"Y-m-d" }}</td>
<td width="90"><li>ID # {{ ipr.id }}</li></td>
<td><a href="{% url "ietf.ipr.views.show" id=ipr.id %}">"{{ ipr.title }}"</a></td>
</tr>
{% endfor %}
<tr><td colspan="3"><hr>Total number of documents searched: {{ docs|length}}</td></tr>
{% for doc in docs %}
<tbody bgcolor="#{% cycle dadada,eaeaea as bgcolor %}">
<tr >
<td colspan="3">
<tr><td colspan="3"><hr>Total number of documents searched: {{ docs|length }}</td></tr>
{% for doc in docs %}
<tbody bgcolor="#{% cycle dadada,eaeaea as bgcolor %}">
<tr >
<td colspan="3">
Search result on {{ doc.name|rfcspace|lstrip:"0"|rfcnospace }}, "{{ doc.document.title }}"{% if not forloop.first %}{% if doc.related %}, that was {{ doc.relation|lower }} {{ doc.related.source|rfcspace|lstrip:"0"|rfcnospace }}, "{{ doc.related.source.title }}"{% endif %}{% endif %}
</td>
</tr>
{% if doc.iprs %}
{% for ipr in doc.iprs %}
<tr valign="top">
<td width="100">{{ ipr.submitted_date }}</td>
<td width="90"><li>ID # {{ ipr.ipr_id }}</li></td>
<td><a href="{% url "ietf.ipr.views.show" ipr_id=ipr.ipr_id %}">"{{ ipr.title }}"</a></td>
</tr>
{% endfor %}
{% else %}
<tr>
<td></td>
<td colspan="2">
No IPR disclosures have been submitted directly on <i>{{ doc.name|rfcspace|lstrip:"0" }}</i>{% if iprs %},
</td>
</tr>
{% if doc.iprdocrel_set.all %}
{% for ipr in doc.iprdocrel_set.all %}
<tr valign="top">
<td width="100">{{ ipr.disclosure.time|date:"Y-m-d" }}</td>
<td width="90"><li>ID # {{ ipr.disclosure.id }}</li></td>
<td><a href="{% url "ietf.ipr.views.show" id=ipr.id %}">"{{ ipr.disclosure.title }}"</a></td>
</tr>
{% endfor %}
{% else %}
<tr>
<td></td>
<td colspan="2">
No IPR disclosures have been submitted directly on <i>{{ doc.name|rfcspace|lstrip:"0" }}</i>{% if iprs %},
but there are disclosures on {% if docs|length == 2 %}a related document{% else %}related documents{% endif %}, listed on this page{% endif %}.
</b>
</td>
</tr>
{% endif %}
</tbody>
{% endfor %}
</td>
</tr>
{% endif %}
</tbody>
{% endfor %}
</table>
</table>
{% endblock %}

View file

@ -1,52 +1,52 @@
{# Copyright The IETF Trust 2007, All Rights Reserved #}
{% extends "ipr/search_result.html" %}
{% load ietf_filters %}
{% block search_result %}
<table cellpadding="1" cellspacing="0" border="0">
<tr><td colspan="3"><b>{% block search_header %}Search result on {{ q }}{% endblock %}</b></td></tr>
{% if not count %}
<tr>
<td></td>
<td colspan="2">
<b>No IPR disclosures related to a document with the word(s) <i>{{ q }}</i> in the title have been submitted.</b>
</td>
</tr>
{% else %}
<tr><td colspan="3">Total number of IPR disclosures found: {{ count }} </td></tr>
{% block search_result %}
<table cellpadding="1" cellspacing="0" border="0">
<tr><td colspan="3"><b>{% block search_header %}Search result on {{ q }}{% endblock %}</b></td></tr>
{% if not docs %}
<tr>
<td></td>
<td colspan="2">
<b>No IPR disclosures related to a document with the word(s) <i>{{ q }}</i> in the title have been submitted.</b>
</td>
</tr>
{% else %}
<tr><td colspan="3">Total number of IPR disclosures found: {{ iprs|length }} </td></tr>
{% block iprlist %}
{% for alias in docs %}
<tbody bgcolor="#{% cycle dadada,eaeaea as bgcolor %}">
<tr >
<td colspan="3">
IPR that is related to <b><i>{{ alias.name|rfcspace|lstrip:"0"|rfcnospace }}, "{{ alias.document.title }}"{% if alias.related %}, that was {{ alias.relation|lower }} {{ alias.related.source.name|rfcspace|lstrip:"0"|rfcnospace }}, "{{ alias.related.source.title }}"{% endif %}
</i><!--,</b> which has the string <b>"<i>{{ q }}</i>"</b> within the document title.-->
</td>
</tr>
{% if alias.iprs %}
{% for ipr in alias.iprs %}
<tr valign="top">
<td width="100">{{ ipr.submitted_date }}</td>
<td width="90"><li>ID # {{ ipr.ipr_id }}</li></td>
<td>
{% for item in ipr.updated_by.all %}
{% if item.processed == 1 and item.ipr.status != 2 %}
IPR disclosure ID# {{ item.ipr.ipr_id }} "<a href="{% url "ietf.ipr.views.show" item.ipr.ipr_id %}">{{ item.ipr.title }}</a>" Updates
{% endif %}
{% endfor %}
<a href="{% url "ietf.ipr.views.show" ipr.ipr_id %}">"{{ ipr.title }}"</a>
</td>
</tr>
{% endfor %}
{% else %}
<tr>
<td></td>
<td colspan="2"><b>No IPR disclosures related to <i>{{ alias.name|rfcspace|lstrip:"0" }}</i> have been submitted</b></td>
</tr>
{% endif %}
</tbody>
{% endfor %}
{% endblock %}
{% endif %}
</table>
{% endblock %}
{% block iprlist %}
{% for alias in docs %}
<tbody bgcolor="#{% cycle dadada,eaeaea as bgcolor %}">
<tr >
<td colspan="3">
IPR that is related to <b><i>{{ alias.name|rfcspace|lstrip:"0"|rfcnospace }}, "{{ alias.document.title }}"{% if alias.related %}, that was {{ alias.relation|lower }} {{ alias.related.source.name|rfcspace|lstrip:"0"|rfcnospace }}, "{{ alias.related.source.title }}"{% endif %}
</i><!--,</b> which has the string <b>"<i>{{ q }}</i>"</b> within the document title.-->
</td>
</tr>
{% if alias.document.ipr %}
{% for ipr in alias.document.ipr %}
<tr valign="top">
<td width="100">{{ ipr.disclosure.time|date:"Y-m-d" }}</td>
<td width="90"><li>ID # {{ ipr.disclosure.id }}</li></td>
<td>
{% for item in ipr.disclosure.updated_by.all %}
{% if item.source.state_id == "posted" %}
IPR disclosure ID# {{ item.ipr.ipr_id }} "<a href="{% url "ietf.ipr.views.show" item.source.id %}">{{ item.source.title }}</a>" Updates
{% endif %}
{% endfor %}
<a href="{% url "ietf.ipr.views.show" ipr.id %}">"{{ ipr.disclosure.title }}"</a>
</td>
</tr>
{% endfor %}
{% else %}
<tr>
<td></td>
<td colspan="2"><b>No IPR disclosures related to <i>{{ alias.name|rfcspace|lstrip:"0" }}</i> have been submitted</b></td>
</tr>
{% endif %}
</tbody>
{% endfor %}
{% endblock %}
{% endif %}
</table>
{% endblock %}

View file

@ -0,0 +1,65 @@
{% load ietf_filters %}
<h1>IPR Search</h1>
<a href="{% url "ietf.ipr.views.showlist" %}">Back to IPR Disclosure Page</a>
<form id="search-form">
{% if user|has_role:"Secretariat" %}
<h2>State Filter</h2>
<div class="ietf-box search-form-box">
{{ form.state }}
</div>
{% endif %}
<h2>Document Search</h2>
<div class="ietf-box search-form-box">
<p>
<label>I-D name (draft-...):</label>
{{ form.draft.errors }}
{{ form.draft }}
<button name="submit" value="draft" type="submit">SEARCH</button>
</p>
<p>
<label>RFC Number:</label>
{{ form.rfc.errors }}
{{ form.rfc }}
<button name="submit" value="rfc" type="submit">SEARCH</button>
</p>
</div>
<h2>Keyword Search</h2>
<div class="ietf-box search-form-box">
<p>
<label>Name of patent owner/applicant:</label>
{{ form.holder.errors }}
{{ form.holder }}
<button name="submit" value="holder" type="submit">SEARCH</button>
</p>
<p>
<label>Characters in patent information (Full/Partial):</label>
{{ form.patent.errors }}
{{ form.patent }}
<button name="submit" value="patent" type="submit">SEARCH</button>
</p>
<p>
<label>Working group name:</label>
{{ from.group.errors }}
{{ form.group }}
<button name="submit" value="group" type="submit">SEARCH</button>
</p>
<p>
<label>Words in document title:</label>
{{ form.doctitle.errors }}
{{ form.doctitle }}
<button name="submit" value="doctitle" type="submit">SEARCH</button>
</p>
<p>
<label>Words in IPR disclosure title:</label>
{{ form.iprtitle.errors }}
{{ form.iprtitle }}
<button name="submit" value="iprtitle" type="submit">SEARCH</button>
</p>
</div>
</form>

View file

@ -1,5 +1,5 @@
{# Copyright The IETF Trust 2007, All Rights Reserved #}
{% extends "ipr/search_result.html" %}
{% load ietf_filters %}
{% block search_header %}{% if not count %}Search result on {{ q }}{% else %}Patent Owner/Applicant Search Result{% endif %}{% endblock %}</b></td></tr>
{% block search_header %}{% if not iprs %}Search result on {{ q }}{% else %}Patent Owner/Applicant Search Result{% endif %}{% endblock %}</b></td></tr>
{% block intro_prefix %}IPR that was submitted by <b><i>{{ q }}</i></b>, and{% endblock %}

View file

@ -1,7 +1,7 @@
{# Copyright The IETF Trust 2007, All Rights Reserved #}
{% extends "ipr/search_result.html" %}
{% load ietf_filters %}
{% block search_header %}{% if not count %}Search result on {{ q }}{% else %}IPR Disclosure Title Search Result{% endif %}{% endblock %}</b></td></tr>
{% block search_header %}{% if not iprs %}Search result on {{ q }}{% else %}IPR Disclosure Title Search Result{% endif %}{% endblock %}</b></td></tr>
{% block intro_prefix %}IPR that{% endblock %}
{% block intro_suffix %}and has the string <b><i>"{{ q }}"</i></b> within the IPR disclosure title.{% endblock %}
{% block search_failed %}No IPR disclosures with the word(s) "<i>{{ q }}</i>" in the title have been submitted{% endblock %}

View file

@ -1,6 +1,6 @@
{# Copyright The IETF Trust 2007, All Rights Reserved #}
{% extends "ipr/search_result.html" %}
{% load ietf_filters %}
{% block search_header %}{% if not count %}Search result on {{ q }}{% else %}Patent Information Search Result{% endif %}{% endblock %}
{% block search_header %}{% if not iprs %}Search result on {{ q }}{% else %}Patent Information Search Result{% endif %}{% endblock %}
{% block search_failed %}No IPR disclosures with the word(s) "<i>{{ q }}</i>" in the Patent Information have been submitted{% endblock %}
{% block intro_prefix %}IPR that contains the string <b><i>{{ q }}</i></b> in the "Disclosure of Patent Information" section of the form, or in the body of the text (for disclosures submitted by e-mail), and{% endblock %}

View file

@ -1,72 +1,82 @@
{# Copyright The IETF Trust 2007, All Rights Reserved #}
{% extends "base.html" %}
{% block morecss %}
{% endblock %}
{% load ietf_filters %}
{% block doctype %}{% endblock %}
{% block title %}IPR Search Result{% endblock %}
{% block content %}
{% load ietf_filters %}
<h1>IPR Disclosures</h1>
{% block search_result %}
<table cellpadding="1" cellspacing="0" border="0">
<tr><td colspan="3"><b>{% block search_header %}Patent Owner/Applicant Search Result{% endblock %}</b></td></tr>
{% if not iprs %}
<tr>
<td></td>
<td colspan="2"><b>{% block search_failed %}No IPR disclosures have been submitted by <i>{{ q }}</i>{% endblock %}</b></td>
</tr>
{% else %}
<tr><td colspan="3">Total number of IPR disclosures found: {{ count }} </td></tr>
{% block iprlist %}
{% for ipr in iprs %}
<tbody bgcolor="#{% cycle eeeeee,dddddd as bgcolor %}">
<tr valign="top">
<td colspan="3">
{% block intro_prefix %}IPR that was submitted by <b><i>{{ q }}</i></b>, and{% endblock %}
{% block pagehead %}
<link rel="stylesheet" type="text/css" href="/css/ipr.css"></link>
{% endblock %}
{% block content %}
{% include "ipr/search_form.html" %}
<br>
{% block search_result %}
<table cellpadding="1" cellspacing="0" border="0">
<tr><td colspan="3"><b>{% block search_header %}Patent Owner/Applicant Search Result{% endblock %}</b></td></tr>
{% if not iprs %}
<tr>
<td></td>
<td colspan="2"><b>{% block search_failed %}No IPR disclosures have been submitted by <i>{{ q }}</i>{% endblock %}</b></td>
</tr>
{% else %}
<tr><td colspan="3">Total number of IPR disclosures found: {{ iprs|length }} </td></tr>
{% block iprlist %}
{% for ipr in iprs %}
{% if user|has_role:"Secretariat" %}{% ifchanged %}<tr><td colspan="3"><h3>{{ ipr.state.name }}</h3></td></tr>{% endifchanged %}{% endif %}
<tbody bgcolor="#{% cycle eeeeee,dddddd as bgcolor %}">
<tr valign="top">
<td colspan="3">
{% block intro_prefix %}IPR that was submitted by <b><i>{{ q }}</i></b>, and{% endblock %}
{% block related %}
{% with ipr.docs as iprdocaliases %}
{% if not iprdocaliases %}
{% with ipr.iprdocrel_set.all as iprdocrels %}
{% if not iprdocrels %}
is not related to a specific IETF contribution.
{% else %}
is related to
{% for item in iprdocaliases %}
{% for item in iprdocrels %}
{% if forloop.last and forloop.counter > 1 %}and{% endif %}
<b><i>{{ item.formatted_name|rfcspace }}, "{{ item.doc_alias.document.title }}"</i></b>{% if not forloop.last and forloop.counter > 1 %},{% endif %}
<b><i>{{ item.formatted_name|rfcspace }}, "{{ item.document.document.title }}"</i></b>{% if not forloop.last and forloop.counter > 1 %},{% endif %}
{% endfor %}
{% endif %}
{% endwith %}
{% endblock %}
{% block intro_suffix %}{% endblock %}
</td>
</tr>
<tr valign="top">
<td width="100">{{ ipr.submitted_date }}</td>
<td width="90"><li>ID # {{ ipr.ipr_id }}</li></td>
<td><a href="{% url "ietf.ipr.views.show" ipr_id=ipr.ipr_id %}">"{{ ipr.title }}"</a></td>
</tr>
{% for item in ipr.updates.all %}
{% block intro_suffix %}{% endblock %}
</td>
</tr>
<tr valign="top">
<td width="100">{{ ipr.time|date:"Y-m-d" }}</td>
<td width="90"><li>ID # {{ ipr.id }}</li></td>
<td><a href="{% url "ietf.ipr.views.show" id=ipr.id %}">"{{ ipr.title }}"</a></td>
</tr>
{% for item in ipr.updates.all %}
{% if item != ipr %}
<tr valign="top">
<td width="100">{{ item.updated.submitted_date }}</td>
<td width="90"><li>ID # {{ item.updated.ipr_id }}</li></td>
<td>
IPR disclosure ID# {{ ipr.ipr_id }} <a href="{% url "ietf.ipr.views.show" ipr_id=ipr.ipr_id %}">"{{ ipr.title }}"</a>
Updates <a href="{% url "ietf.ipr.views.show" ipr_id=item.ipr_id %}">{{ item.updated.title }}</a>
</td>
</tr>
<tr valign="top">
<td width="100">{{ item.target.time|date:"Y-m-d" }}</td>
<td width="90"><li>ID # {{ item.target.id }}</li></td>
<td>
IPR disclosure ID# {{ ipr.id }} <a href="{% url "ietf.ipr.views.show" id=ipr.id %}">"{{ ipr.title }}"</a>
Updates <a href="{% url "ietf.ipr.views.show" id=item.id %}">{{ item.target.title }}</a>
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
{% endfor %}
{% endblock %}
{% endif %}
</table>
{% endblock %}
<hr><br>
{% endfor %}
</tbody>
{% endfor %}
{% endblock %}
{% endif %}
</table>
{% endblock %}
<hr><br>
<a href="{% url "ietf.ipr.search.search" %}">IPR Search Main Page</a><br>
<a href="{% url "ietf.ipr.views.showlist" %}">IPR Disclosure Page</a>
<br>
<a href="{% url "ietf.ipr.views.showlist" %}">Back to IPR Disclosure Page</a>
<br>
{% endblock %}
{% block js %}
<script type="text/javascript" src="/js/lib/jquery-1.8.2.min.js"></script>
<script type="text/javascript" src="/js/ipr-search.js"></script>
{% endblock %}

View file

@ -1,53 +1,53 @@
{# Copyright The IETF Trust 2007, All Rights Reserved #}
{% extends "ipr/search_result.html" %}
{% load ietf_filters %}
{% block search_result %}
<table cellpadding="1" cellspacing="0" border="0">
<tr><td colspan="3"><b>{% block search_header %}Working Group Search Result{% endblock %}</b></td></tr>
{% if not count %}
<tr>
<td></td>
<td colspan="2">
<b>No IPR disclosures related to the <i>{{ q }}</i> working group have been submitted.</b>
</td>
</tr>
<tr><td colspan="3">Total number of IPR disclosures found: {{ count }} </td></tr>
{% else %}
<tr><td colspan="3">Total number of IPR disclosures found: {{ count }} </td></tr>
{% block search_result %}
<table cellpadding="1" cellspacing="0" border="0">
<tr><td colspan="3"><b>{% block search_header %}Working Group Search Result{% endblock %}</b></td></tr>
{% if not iprs %}
<tr>
<td></td>
<td colspan="2">
<b>No IPR disclosures related to the <i>{{ q }}</i> working group have been submitted.</b>
</td>
</tr>
<tr><td colspan="3">Total number of IPR disclosures found: {{ iprs|length }} </td></tr>
{% else %}
<tr><td colspan="3">Total number of IPR disclosures found: {{ iprs|length }} </td></tr>
{% block iprlist %}
{% for alias in docs %}
<tbody bgcolor="#{% cycle dadada,eaeaea as bgcolor %}">
{% block iprlist %}
{% for alias in docs %}
<tbody bgcolor="#{% cycle dadada,eaeaea as bgcolor %}">
<tr>
<td colspan="3">
<td colspan="3">
IPR that is related to <b><i>{{ alias.name|rfcspace|lstrip:"0"|rfcnospace }}, "{{ alias.document.title }}"{% if alias.related %}, that was {{ alias.relation|lower }} {{ alias.related.source|rfcspace|lstrip:"0"|rfcnospace }}, "{{ alias.related.source.title|escape }}"{% endif %}
</i></b>{% if alias.product_of_this_wg %} which is a product of Working Group <b><i>{{ q }}</i></b>{% endif %}
</td>
</tr>
{% if alias.iprs %}
{% for ipr in alias.iprs %}
<tr valign="top">
<td width="100">{{ ipr.submitted_date }}</td>
<td width="90"><li>ID # {{ ipr.ipr_id }}</li></td>
<td>
{% for item in ipr.updates.all %}
{% if item.updated.status == 1 %}
IPR disclosure ID# {{ item.updated.ipr_id }}, "<a href="{% url "ietf.ipr.views.show" item.updated.ipr_id %}">{{ item.updated.title }}</a>" Updated by
</i></b>{% if alias.product_of_this_wg %} which is a product of Working Group <b><i>{{ q }}</i></b>{% endif %}
</td>
</tr>
{% if alias.document.ipr %}
{% for ipr in alias.document.ipr %}
<tr valign="top">
<td width="100">{{ ipr.disclosure.time|date:"Y-m-d" }}</td>
<td width="90"><li>ID # {{ ipr.disclosure.id }}</li></td>
<td>
{% for item in ipr.disclosure.updates.all %}
{% if item.target.state_id == "posted" %}
IPR disclosure ID# {{ item.target.id }}, "<a href="{% url "ietf.ipr.views.show" item.target.id %}">{{ item.target.title }}</a>" Updated by
{% endif %}
{% endfor %}
<a href="{% url "ietf.ipr.views.show" ipr.ipr_id %}">"{{ ipr.title }}"</a>
</td>
</tr>
{% endfor %}
{% else %}
<tr>
<td></td>
<td colspan="2"><b>No IPR disclosures related to <i>{{ alias.name|rfcspace|lstrip:"0" }}</i> have been submitted</b></td>
</tr>
{% endif %}
</tbody>
{% endfor %}
{% endblock %}
{% endif %}
</table>
{% endblock %}
{% endfor %}
<a href="{% url "ietf.ipr.views.show" ipr.id %}">"{{ ipr.disclosure.title }}"</a>
</td>
</tr>
{% endfor %}
{% else %}
<tr>
<td></td>
<td colspan="2"><b>No IPR disclosures related to <i>{{ alias.name|rfcspace|lstrip:"0" }}</i> have been submitted</b></td>
</tr>
{% endif %}
</tbody>
{% endfor %}
{% endblock %}
{% endif %}
</table>
{% endblock %}

View file

@ -0,0 +1,26 @@
{% extends "base.html" %}
{% block title %}Change State of {{ ipr.title }}{% endblock %}
{% block pagehead %}
<link rel="stylesheet" type="text/css" href="/css/ipr.css"></link>
{% endblock %}
{% block content %}
<h1>Change State of {{ ipr }}</h1>
<p>You may add a comment to be included in the disclosure history.</p>
<form class="add-comment" action="" method="post">{% csrf_token %}
<table>
{{ form.as_table }}
<tr>
<td></td>
<td class="actions">
<a href="{% url "ipr_show" id=ipr.id %}">Back</a>
<input type="submit" value="Submit"/>
</td>
</tr>
</table>
</form>
{% endblock %}

View file

@ -1,62 +0,0 @@
{% extends "base.html" %}
{# Copyright The IETF Trust 2007, All Rights Reserved #}
{% block title %}IPR Update{% endblock %}
{% block morecss %}
table.ipr { margin-top: 1em; }
.ipr .light td { background: #eeeeee; }
.ipr .dark td { background: #dddddd; }
.ipr th { background: #2647a0; color: white; }
.ipr { width: 101ex; border: 0; border-collapse: collapse; }
.ipr th, .ipr td { padding: 3px 6px; text-align: left; }
.ipr tr { vertical-align: top; }
.ipr td.iprlabel { width: 18ex; }
.iprdata { font-weight: bold; }
.required { color: red; float: right; padding-top: 0.7ex; font-size: 130%; }
.errorlist { background: red; color: white; padding: 0.2ex 0.2ex 0.2ex 0.5ex; border: 0px; margin: 0px; font-family: Arial, sans-serif; }
ul.errorlist { margin: 0px; }
.errorlist { background: red; color: white; padding: 0.2ex 0.2ex 0.2ex 0.5ex; border: 0px; margin: 0px; font-family: Arial, sans-serif; }
ul.errorlist { margin: 0px; }
{% endblock %}
{% block content %}
<h1>Updating {{ type|title }} IPR Disclosure <br><i>{{ ipr.title }}</i></h1>
<form name="form1" method="post">{% csrf_token %}
{% if form.errors %}
<p class="errorlist">
There were errors in the submitted form -- see below. Please correct these and resubmit.
{% if form.non_field_errors %}
<ul class="errorlist">
{% for error in form.non_field_errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
</p>
{% endif %}
<table class="ipr">
<tr class="{% cycle dark,light as row_parity %}"><th colspan="2" >
Contact Information for Submitter of this Update.
</th>
</tr>
{% for field in form %}
{% if field.name != "update_auth" %}
<tr class="{% cycle row_parity %}"><td class="iprlabel">{{field.label }}:</td><td class="iprdata">{{ field.errors }} {% if field.field.required %}<span class="required">*</span>{%endif%} {{ field }}</td></tr>
{% endif %}
{% endfor %}
</table>
<p>
{{ form.update_auth.errors }}
<span class="required">*</span>
{{ form.update_auth }}
<b>I am authorized to update this IPR disclosure, and I understand that notification of this update will be provided to the submitter of the original IPR disclosure and to the Patent Holder's Contact.</b>
</p>
<p><input type="submit" name="submit" value="Submit" />
&nbsp; <input type="button" value="Cancel" onClick="history.go(-1);return true;" /></p>
</form>
{% endblock %}

View file

@ -0,0 +1,27 @@
To: {{ to_email }}
From: IETF Secretariat <ietf-ipr@ietf.org>
Subject: IPR update notification
Reply-To: {{ reply_to }}
Dear {{ to_name }}:
We have just received a request to update the IPR disclosure(s) submitted by you:
{% for ipr in iprs %}
{{ ipr.title }} {{ ipr.get_absolute_url }}
{% endfor %}
The name and email address of the person who submitted the update to your IPR disclosure are:
{{ new_ipr.submitter_name }}, {{ new_ipr.submitter_email }}.
We will not post this update unless we receive positive confirmation from you that
{{ new_ipr.submitter_name }} is authorized to update your disclosure.
Please respond to this message to confirm.
If we do not hear from you within 30 days, we will inform {{ new_ipr.submitter_name }}
that we were not able to secure approval for posting and that we are therefore rejecting
the update until we can be assured it is authorized.
Thank you
IETF Secretariat

View file

@ -109,7 +109,7 @@
{% if liaison.from_contact and liaison.body %}
<tr>
<td>Body:</td>
<td>Body: </td>
<td><pre>{{ liaison.body|wordwrap:"71" }}</pre></td>
</tr>
{% endif %}

View file

@ -8,7 +8,7 @@ import debug # pyflakes:ignore
from ietf.doc.models import Document, DocAlias, State, DocumentAuthor, BallotType, DocEvent, BallotDocEvent
from ietf.group.models import Group, GroupHistory, Role, RoleHistory
from ietf.iesg.models import TelechatDate
from ietf.ipr.models import IprDetail, IprDocAlias
from ietf.ipr.models import HolderIprDisclosure, IprDocRel, IprDisclosureStateName, IprLicenseTypeName
from ietf.meeting.models import Meeting
from ietf.name.models import StreamName
from ietf.person.models import Person, Alias, Email
@ -233,31 +233,24 @@ def make_test_data():
)
# IPR
ipr = IprDetail.objects.create(
ipr = HolderIprDisclosure.objects.create(
by=Person.objects.get(name="(System)"),
title="Statement regarding rights",
legal_name="Native Martians United",
is_pending=0,
applies_to_all=1,
licensing_option=1,
lic_opt_a_sub=2,
lic_opt_b_sub=2,
lic_opt_c_sub=2,
patents="PTO12345",
date_applied="foo",
country="Whole World",
comments="",
lic_checkbox=True,
other_notes="",
status=1,
generic=0,
third_party=0,
submitted_date=datetime.date.today(),
holder_legal_name="Native Martians United",
state=IprDisclosureStateName.objects.get(slug='posted'),
patent_info='US12345',
holder_contact_name='George',
holder_contact_email='george@acme.com',
holder_contact_info='14 Main Street\nEarth',
licensing=IprLicenseTypeName.objects.get(slug='royalty-free'),
submitter_name='George',
submitter_email='george@acme.com',
)
IprDocAlias.objects.create(
ipr=ipr,
doc_alias=doc_alias,
rev="00",
IprDocRel.objects.create(
disclosure=ipr,
document=doc_alias,
revisions='00',
)
# meeting

165
static/css/ipr.css Normal file
View file

@ -0,0 +1,165 @@
table.ipr { margin-top: 1em; }
.ipr .light td { background: #eeeeee; }
.ipr .dark td { background: #dddddd; }
.ipr th { background: #2647a0; color: white; }
.ipr { width: 101ex; border: 0; border-collapse: collapse; }
.ipr th, .ipr td { padding: 3px 6px; text-align: left; }
.ipr tr { vertical-align: top; }
.ipr td.iprlabel { width: 18ex; }
.iprdata { font-weight: bold; }
#email-form { background: #dddddd; }
#ipr-table { background: #F2F2E6; width: 101ex;}
#ipr-table tr td:first-child { text-align: right; }
#ipr-table input,textarea { width: 80%; }
.required {
color: red;
float: right;
padding-left: 0.5em;
font-size: 130%;
}
.button-group {
clear: both;
width: auto;
height: 2.5em;
padding: 4px 7px;
background: #F2F2E6;
border: 0 solid #ccc;
border-top: 1px solid #ccc;
margin: 5px 0 0 0;
overflow: hidden;
}
.button-group ul {
list-style-type: none;
margin: 0;
padding: 7px;
text-align: center;
}
.button-group li {
display: inline;
padding: 5px;
}
.history-actions {
margin-bottom: 1em;
padding-left: 1px;
}
form.add-email #id_message {
width: 600px;
height: 300px;
}
form.add-email .actions {
padding-top: 20px;
}
#id_response_due {
width: 150px;
}
ul#id_direction {
list-style-type: none;
}
ul#id_direction li {
display: inline;
}
.date-column {
width: 6.5em;
}
.id-column {
width: 3em;
}
.column-four {
width: 5.5em;
}
.column-five {
width: 7em;
}
form.send-notification .actions {
padding-top: 20px;
}
form.send-notification textarea {
width: 600px;
height: 300px;
}
#id_state li {
display:inline;
list-style-type: none;
padding-right: 20px;
}
#id_state li label {
width: 100px;
}
.search-form-box input[type!=checkbox] {
width: 20em;
}
#state-form {
display: inline;
}
.ui-selectmenu-button {
vertical-align: middle;
}
#id_contribution ul.token-input-list {
width: 332px;
}
/* add_comment
========================================================================== */
form.add-comment #id_comment {
width: 600px;
height: 300px;
}
form.add-comment .actions {
padding-top: 20px;
}
/* details_edit
========================================================================== */
.iprdata li { list-style:none;}
.iprdata input[type=text],input[type=email],textarea { width:80%; }
.data td { white-space: pre; }
#id_contribution { table-layout:fixed; }
.mini input { width:60px; }
.required { color: red; float: right; padding-top: 0.7ex; font-size: 130%; }
.errorlist { background: red; color: white; padding: 0.2ex 0.2ex 0.2ex 0.5ex; border: 0px; margin: 0px; }
ul.errorlist { margin: 0px; }
/* search
========================================================================== */
#search-form { clear:both; margin-top:1em;}
#search-form label { float:left; width: 200px; }
#search-form input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
#search-form input[type=number] {
-moz-appearance:textfield;
}

36
static/js/ipr-edit.js Normal file
View file

@ -0,0 +1,36 @@
function cloneMore(selector, type) {
// customized for inclusion of jQuery Tokeninput fields
var newElement = jQuery(selector).clone(true);
var total = jQuery('#id_' + type + '-TOTAL_FORMS').val();
// remove special token bits
newElement.find('.token-input-list').remove();
newElement.find(':input').each(function() {
var name = jQuery(this).attr('name').replace('-' + (total-1) + '-','-' + total + '-');
var id = 'id_' + name;
jQuery(this).attr({'name': name, 'id': id}).val('').removeAttr('checked');
});
newElement.find('.tokenized-field').each(function() {
jQuery(this).attr('data-pre','[]');
});
newElement.find('label').each(function() {
var newFor = jQuery(this).attr('for').replace('-' + (total-1) + '-','-' + total + '-');
jQuery(this).attr('for', newFor);
});
jQuery(selector).find('a[id$="add_link"]').remove();
total++;
jQuery('#id_' + type + '-TOTAL_FORMS').val(total);
jQuery(selector).after(newElement);
// re-initialize tokenized fields
newElement.find(".tokenized-field").each(function () { setupTokenizedField(jQuery(this)); });
}
jQuery(function() {
jQuery('#draft_add_link').click(function() {
cloneMore('#id_contribution tr.draft_row:last','draft');
});
jQuery('#rfc_add_link').click(function() {
cloneMore('#id_contribution tr.rfc_row:last','rfc');
});
})

4
static/js/ipr-email.js Normal file
View file

@ -0,0 +1,4 @@
// setup admin action buttons
jQuery(function() {
jQuery("#id_response_due").datepicker({dateFormat:"yy-mm-dd"});
});

23
static/js/ipr-search.js Normal file
View file

@ -0,0 +1,23 @@
// this is required to trigger the correct submit button if enter is pressed
jQuery(function() {
jQuery("#id_state input[value!=all]").change(function(e) {
if (this.checked) {
jQuery("#id_state_0").prop('checked',false);
}
});
jQuery("#id_state_0").change(function(e) {
if (this.checked) {
jQuery("#id_state input[value!=all]").prop('checked',false);
}
});
jQuery("form input,select").keypress(function (e) {
//alert("key press");
if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
jQuery(this).next('button[type=submit]').click();
return false;
} else {
return true;
}
});
});

4
static/js/ipr-view.js Normal file
View file

@ -0,0 +1,4 @@
// setup admin action buttons
jQuery(function() {
jQuery("a.admin-action").button();
});