diff --git a/bin/mkdiagram b/bin/mkdiagram index 765a7ba52..ef50ce673 100755 --- a/bin/mkdiagram +++ b/bin/mkdiagram @@ -9,7 +9,7 @@ trap 'echo "$program($LINENO): Command failed with error code $? ($0 $*)"; exit if [ "$*" ]; then apps="$@"; graph="${1%.*}"; else apps=$(ls */models.py | sed 's!/models.py!!'); graph="models"; fi newapps="doc group meeting message person name" -legacyapps="announcements idindex idrfc idtracker iesg ietfauth ietfworkflows ipr liaisons mailinglists proceedings redirects submit wgchairs wgcharter wginfo" +legacyapps="announcements idindex idrfc idtracker iesg ietfauth ipr liaisons mailinglists proceedings redirects submit wgcharter wginfo" proxy="$(grep ^class */proxy.py | tr '()' ' ' | awk '{printf $2 ","}')" names="$(grep ^class name/models.py | tr '()' ' ' | awk '{printf $2 ","}')" diff --git a/debug.py b/debug.py index a172bb521..fbcbc61f7 100644 --- a/debug.py +++ b/debug.py @@ -24,8 +24,6 @@ try: except ImportError: debug = True -from decorator import decorator - # A debug decorator, written by Paul Butler, taken from # http://paulbutler.org/archives/python-debugging-with-decorators/ # Additional functions and decorator functionality added by @@ -78,6 +76,7 @@ def trace(fn): # renamed from 'report' by henrik 16 Jun 2011 return ret wrap.callcount = 0 if debug: + from decorator import decorator return decorator(wrap, fn) else: return fn @@ -109,6 +108,7 @@ def time(fn): return ret wrap.callcount = 0 if debug: + from decorator import decorator return decorator(wrap, fn) else: return fn @@ -169,6 +169,7 @@ def profile(fn): prof.dump_stats(datafn) return retval if debug: + from decorator import decorator return decorator(wrapper, fn) else: return fn diff --git a/ietf/announcements/.gitignore b/ietf/announcements/.gitignore deleted file mode 100644 index c7013ced9..000000000 --- a/ietf/announcements/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/*.pyc -/settings_local.py diff --git a/ietf/announcements/__init__.py b/ietf/announcements/__init__.py deleted file mode 100644 index a4b306690..000000000 --- a/ietf/announcements/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# Copyright The IETF Trust 2007, All Rights Reserved - diff --git a/ietf/announcements/models.py b/ietf/announcements/models.py deleted file mode 100644 index 6ee8e1bfb..000000000 --- a/ietf/announcements/models.py +++ /dev/null @@ -1,88 +0,0 @@ -# Copyright The IETF Trust 2007, All Rights Reserved - -from django.db import models -from django.conf import settings -from ietf.idtracker.models import PersonOrOrgInfo, ChairsHistory -#from django.contrib.auth.models import Permission - -# I don't know why the IETF database mostly stores times -# as char(N) instead of TIME. Until it's important, let's -# keep them as char here too. - -# email is not used; the announced_from text is Foo Bar -class AnnouncedFrom(models.Model): - announced_from_id = models.AutoField(primary_key=True) - announced_from = models.CharField(blank=True, max_length=255, db_column='announced_from_value') - email = models.CharField(blank=True, max_length=255, db_column='announced_from_email', editable=False) - #permission = models.ManyToManyField(Permission, limit_choices_to={'codename__endswith':'announcedfromperm'}, verbose_name='Permission Required', blank=True) - def __str__(self): - return self.announced_from - class Meta: - db_table = 'announced_from' - #permissions = ( - # ("ietf_chair_announcedfromperm", "Can send messages from IETF Chair"), - # ("iab_chair_announcedfromperm", "Can send messages from IAB Chair"), - # ("iad_announcedfromperm", "Can send messages from IAD"), - # ("ietf_execdir_announcedfromperm", "Can send messages from IETF Executive Director"), - # ("other_announcedfromperm", "Can send announcements from others"), - #) - -class AnnouncedTo(models.Model): - announced_to_id = models.AutoField(primary_key=True) - announced_to = models.CharField(blank=True, max_length=255, db_column='announced_to_value') - email = models.CharField(blank=True, max_length=255, db_column='announced_to_email') - def __str__(self): - return self.announced_to - class Meta: - db_table = 'announced_to' - -class Announcement(models.Model): - announcement_id = models.AutoField(primary_key=True) - announced_by = models.ForeignKey(PersonOrOrgInfo, db_column='announced_by') - announced_date = models.DateField(null=True, blank=True) - announced_time = models.CharField(blank=True, max_length=20) - text = models.TextField(blank=True, db_column='announcement_text') - announced_from = models.ForeignKey(AnnouncedFrom) - cc = models.CharField(blank=True, null=True, max_length=255) - subject = models.CharField(blank=True, max_length=255) - extra = models.TextField(blank=True,null=True) - announced_to = models.ForeignKey(AnnouncedTo) - nomcom = models.NullBooleanField() - nomcom_chair = models.ForeignKey(ChairsHistory, null=True, blank=True) - manually_added = models.BooleanField(db_column='manualy_added') - other_val = models.CharField(blank=True, null=True, max_length=255) - def __str__(self): - return "Announcement from %s to %s on %s %s" % (self.announced_from, self.announced_to, self.announced_date, self.announced_time) - def from_name(self): - if self.announced_from_id == 99: - return self.other_val - if self.announced_from_id == 18: # sigh hardcoding - return self.nomcom_chair.person - return self.announced_from - class Meta: - db_table = 'announcements' - -class ScheduledAnnouncement(models.Model): - mail_sent = models.BooleanField() - to_be_sent_date = models.DateField(null=True, blank=True) - to_be_sent_time = models.CharField(blank=True, null=True, max_length=50) - scheduled_by = models.CharField(blank=True, max_length=100) - scheduled_date = models.DateField(null=True, blank=True) - scheduled_time = models.CharField(blank=True, max_length=50) - subject = models.CharField(blank=True, max_length=255) - to_val = models.CharField(blank=True, max_length=255) - from_val = models.CharField(blank=True, max_length=255) - cc_val = models.TextField(blank=True,null=True) - body = models.TextField(blank=True) - actual_sent_date = models.DateField(null=True, blank=True) - actual_sent_time = models.CharField(blank=True, max_length=50) # should be time, but database contains oddities - first_q = models.IntegerField(null=True, blank=True) - second_q = models.IntegerField(null=True, blank=True) - note = models.TextField(blank=True,null=True) - content_type = models.CharField(blank=True, max_length=255) - replyto = models.CharField(blank=True, null=True, max_length=255) - bcc_val = models.CharField(blank=True, null=True, max_length=255) - def __str__(self): - return "Scheduled Announcement from %s to %s on %s %s" % (self.from_val, self.to_val, self.to_be_sent_date, self.to_be_sent_time) - class Meta: - db_table = 'scheduled_announcements' diff --git a/ietf/announcements/send_scheduled.py b/ietf/announcements/send_scheduled.py deleted file mode 100644 index 0a8b91093..000000000 --- a/ietf/announcements/send_scheduled.py +++ /dev/null @@ -1,68 +0,0 @@ -import re, datetime, email - -from django.conf import settings - -from ietf.utils.mail import send_mail_text, send_mail_mime - -first_dot_on_line_re = re.compile(r'^\.', re.MULTILINE) - -def send_scheduled_announcement(announcement): - # for some reason, the old Perl code base substituted away . on line starts - body = first_dot_on_line_re.sub("", announcement.body) - - extra = {} - if announcement.replyto: - extra['Reply-To'] = announcement.replyto - - # announcement.content_type can contain a case-sensitive parts separator, - # so we need to keep it as is, not lowercased, but we want a lowercased - # version for the coming comparisons. - content_type_lowercase = announcement.content_type.lower() - if not content_type_lowercase or 'text/plain' in content_type_lowercase: - send_mail_text(None, announcement.to_val, announcement.from_val, announcement.subject, - body, cc=announcement.cc_val, bcc=announcement.bcc_val) - elif 'multipart/' in content_type_lowercase: - # make body a real message so we can parse it. - body = ("MIME-Version: 1.0\r\nContent-Type: %s\r\n" % announcement.content_type) + body - - msg = email.message_from_string(body.encode("utf-8")) - send_mail_mime(None, announcement.to_val, announcement.from_val, announcement.subject, - msg, cc=announcement.cc_val, bcc=announcement.bcc_val) - - now = datetime.datetime.now() - announcement.actual_sent_date = now.date() - announcement.actual_sent_time = str(now.time()) - announcement.mail_sent = True - announcement.save() - - -def send_scheduled_announcementREDESIGN(send_queue): - message = send_queue.message - - # for some reason, the old Perl code base substituted away . on line starts - body = first_dot_on_line_re.sub("", message.body) - - extra = {} - if message.reply_to: - extra['Reply-To'] = message.reply_to - - # announcement.content_type can contain a case-sensitive parts separator, - # so we need to keep it as is, not lowercased, but we want a lowercased - # version for the coming comparisons. - content_type_lowercase = message.content_type.lower() - if not content_type_lowercase or 'text/plain' in content_type_lowercase: - send_mail_text(None, message.to, message.frm, message.subject, - body, cc=message.cc, bcc=message.bcc) - elif 'multipart' in content_type_lowercase: - # make body a real message so we can parse it - body = ("MIME-Version: 1.0\r\nContent-Type: %s\r\n" % message.content_type) + body - - msg = email.message_from_string(body.encode("utf-8")) - send_mail_mime(None, message.to, message.frm, message.subject, - msg, cc=message.cc, bcc=message.bcc) - - send_queue.sent_at = datetime.datetime.now() - send_queue.save() - -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - send_scheduled_announcement = send_scheduled_announcementREDESIGN diff --git a/ietf/announcements/sitemaps.py b/ietf/announcements/sitemaps.py deleted file mode 100644 index 2765f0fa0..000000000 --- a/ietf/announcements/sitemaps.py +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright The IETF Trust 2007, All Rights Reserved - -from django.conf import settings -from django.contrib.sitemaps import Sitemap -from ietf.announcements.models import Announcement -from ietf.message.models import Message - -class NOMCOMAnnouncementsMap(Sitemap): - changefreq = "never" - def items(self): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - return Message.objects.filter(related_groups__acronym__startswith="nomcom").exclude(related_groups__acronym="nomcom").order_by('-time') - return Announcement.objects.all().filter(nomcom=True) - def location(self, obj): - return "/ann/nomcom/%d/" % obj.id - def lastmod(self, obj): - # could re-parse the time into a datetime object - return obj.time diff --git a/ietf/announcements/tests.py b/ietf/announcements/tests.py deleted file mode 100644 index f23a0628d..000000000 --- a/ietf/announcements/tests.py +++ /dev/null @@ -1,133 +0,0 @@ -import datetime - -from django.conf import settings - -from ietf.utils.test_utils import SimpleUrlTestCase, canonicalize_sitemap -from ietf.utils.test_data import make_test_data -from ietf.utils.mail import outbox -from ietf.utils import TestCase - -from ietf.announcements.models import ScheduledAnnouncement - -from ietf.message.models import Message, SendQueue -from ietf.person.models import Person - -class AnnouncementsUrlTestCase(SimpleUrlTestCase): - def testUrls(self): - self.doTestUrls(__file__) - def doCanonicalize(self, url, content): - if url.startswith("/sitemap"): - return canonicalize_sitemap(content) - else: - return content - -class SendScheduledAnnouncementsTestCase(TestCase): - def test_send_plain_announcement(self): - a = ScheduledAnnouncement.objects.create( - mail_sent=False, - subject="This is a test", - to_val="test@example.com", - from_val="testmonkey@example.com", - cc_val="cc.a@example.com, cc.b@example.com", - bcc_val="bcc@example.com", - body="Hello World!", - content_type="", - ) - - mailbox_before = len(outbox) - - from ietf.announcements.send_scheduled import send_scheduled_announcement - send_scheduled_announcement(a) - - self.assertEquals(len(outbox), mailbox_before + 1) - self.assertTrue("This is a test" in outbox[-1]["Subject"]) - self.assertTrue(ScheduledAnnouncement.objects.get(id=a.id).mail_sent) - - def test_send_mime_announcement(self): - a = ScheduledAnnouncement.objects.create( - mail_sent=False, - subject="This is a test", - to_val="test@example.com", - from_val="testmonkey@example.com", - cc_val="cc.a@example.com, cc.b@example.com", - bcc_val="bcc@example.com", - body='--NextPart\r\n\r\nA New Internet-Draft is available from the on-line Internet-Drafts directories.\r\n--NextPart\r\nContent-Type: Message/External-body;\r\n\tname="draft-huang-behave-bih-01.txt";\r\n\tsite="ftp.ietf.org";\r\n\taccess-type="anon-ftp";\r\n\tdirectory="internet-drafts"\r\n\r\nContent-Type: text/plain\r\nContent-ID: <2010-07-30001541.I-D@ietf.org>\r\n\r\n--NextPart--', - content_type='Multipart/Mixed; Boundary="NextPart"', - ) - - mailbox_before = len(outbox) - - from ietf.announcements.send_scheduled import send_scheduled_announcement - send_scheduled_announcement(a) - - self.assertEquals(len(outbox), mailbox_before + 1) - self.assertTrue("This is a test" in outbox[-1]["Subject"]) - self.assertTrue("--NextPart" in outbox[-1].as_string()) - self.assertTrue(ScheduledAnnouncement.objects.get(id=a.id).mail_sent) - - -class SendScheduledAnnouncementsTestCaseREDESIGN(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ["names"] - - def test_send_plain_announcement(self): - make_test_data() - - msg = Message.objects.create( - by=Person.objects.get(name="(System)"), - subject="This is a test", - to="test@example.com", - frm="testmonkey@example.com", - cc="cc.a@example.com, cc.b@example.com", - bcc="bcc@example.com", - body="Hello World!", - content_type="", - ) - - q = SendQueue.objects.create( - by=Person.objects.get(name="(System)"), - message=msg, - send_at=datetime.datetime.now() + datetime.timedelta(hours=12) - ) - - mailbox_before = len(outbox) - - from ietf.announcements.send_scheduled import send_scheduled_announcement - send_scheduled_announcement(q) - - self.assertEquals(len(outbox), mailbox_before + 1) - self.assertTrue("This is a test" in outbox[-1]["Subject"]) - self.assertTrue(SendQueue.objects.get(id=q.id).sent_at) - - def test_send_mime_announcement(self): - make_test_data() - - msg = Message.objects.create( - by=Person.objects.get(name="(System)"), - subject="This is a test", - to="test@example.com", - frm="testmonkey@example.com", - cc="cc.a@example.com, cc.b@example.com", - bcc="bcc@example.com", - body='--NextPart\r\n\r\nA New Internet-Draft is available from the on-line Internet-Drafts directories.\r\n--NextPart\r\nContent-Type: Message/External-body;\r\n\tname="draft-huang-behave-bih-01.txt";\r\n\tsite="ftp.ietf.org";\r\n\taccess-type="anon-ftp";\r\n\tdirectory="internet-drafts"\r\n\r\nContent-Type: text/plain\r\nContent-ID: <2010-07-30001541.I-D@ietf.org>\r\n\r\n--NextPart--', - content_type='Multipart/Mixed; Boundary="NextPart"', - ) - - q = SendQueue.objects.create( - by=Person.objects.get(name="(System)"), - message=msg, - send_at=datetime.datetime.now() + datetime.timedelta(hours=12) - ) - - mailbox_before = len(outbox) - - from ietf.announcements.send_scheduled import send_scheduled_announcement - send_scheduled_announcement(q) - - self.assertEquals(len(outbox), mailbox_before + 1) - self.assertTrue("This is a test" in outbox[-1]["Subject"]) - self.assertTrue("--NextPart" in outbox[-1].as_string()) - self.assertTrue(SendQueue.objects.get(id=q.id).sent_at) - -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - SendScheduledAnnouncementsTestCase = SendScheduledAnnouncementsTestCaseREDESIGN diff --git a/ietf/announcements/testurl.list b/ietf/announcements/testurl.list deleted file mode 100644 index 5c88659c4..000000000 --- a/ietf/announcements/testurl.list +++ /dev/null @@ -1,5 +0,0 @@ -200 /ann/nomcom/ -200 /ann/nomcom/1230/ -200 /ann/nomcom/1607/ # non-ASCII content -200 /ann/nomcom/2001/ # non-ASCII content -200 /sitemap-nomcom-announcements.xml diff --git a/ietf/announcements/urls.py b/ietf/announcements/urls.py deleted file mode 100644 index 0f101a17f..000000000 --- a/ietf/announcements/urls.py +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright The IETF Trust 2007, All Rights Reserved - -from django.conf.urls.defaults import patterns -from ietf.announcements.models import Announcement - -from django.conf import settings - -nomcom_dict = { - 'queryset': Announcement.objects.all().filter(nomcom=True) - } - -urlpatterns = patterns('', -# (r'^nomcom/$', 'django.views.generic.simple.redirect_to', {'url': 'http://www.ietf.org/nomcom/index.html'} ), - (r'^nomcom/$', 'ietf.announcements.views.nomcom'), - (r'^nomcom/(?P\d+)/$', 'ietf.announcements.views.message_detail') if settings.USE_DB_REDESIGN_PROXY_CLASSES else (r'^nomcom/(?P\d+)/$', 'django.views.generic.list_detail.object_detail', nomcom_dict) -) diff --git a/ietf/announcements/views.py b/ietf/announcements/views.py deleted file mode 100644 index 45094beb9..000000000 --- a/ietf/announcements/views.py +++ /dev/null @@ -1,88 +0,0 @@ -# Copyright The IETF Trust 2007, All Rights Reserved - -from django.views.generic.simple import direct_to_template -from django.shortcuts import get_object_or_404 -from django.conf import settings -from django.db.models import Q - -import re - -from ietf.idtracker.models import ChairsHistory -from ietf.idtracker.models import Role -from ietf.announcements.models import Announcement -from ietf.group.models import Group, GroupEvent -from ietf.message.models import Message - -def nomcom(request): - curr_chair = (ChairsHistory.objects. - get(chair_type=Role.NOMCOM_CHAIR, present_chair='1')) - - all_chairs = (ChairsHistory.objects.all(). - filter(chair_type='3',start_year__gt = 2003). - order_by('-start_year')) - - nomcom_announcements = Announcement.objects.all().filter(nomcom=1) - - regimes = [] - - for chair in all_chairs: - chair_announcements = (nomcom_announcements.filter(nomcom_chair=chair). - order_by('-announced_date','-announced_time')) - regimes = regimes + [{'chair': chair, - 'announcements' : chair_announcements }] - - return direct_to_template(request, - "announcements/nomcom.html", - { 'curr_chair' : curr_chair, - 'regimes' : regimes }) - -def nomcomREDESIGN(request): - address_re = re.compile("<.*>") - - nomcoms = list(Group.objects.filter(acronym__startswith="nomcom").exclude(name="nomcom")) - - regimes = [] - - for n in nomcoms: - e = GroupEvent.objects.filter(group=n, type="changed_state", changestategroupevent__state="active").order_by('time')[:1] - n.start_year = e[0].time.year if e else 0 - if n.start_year <= 2003: - continue - e = GroupEvent.objects.filter(group=n, type="changed_state", changestategroupevent__state="conclude").order_by('time')[:1] - n.end_year = e[0].time.year if e else "" - - r = n.role_set.select_related().filter(name="chair") - chair = None - if r: - chair = r[0] - announcements = Message.objects.filter(related_groups=n).order_by('-time') - for a in announcements: - a.to_name = address_re.sub("", a.to) - - regimes.append(dict(chair=chair, - announcements=announcements, - group=n)) - - regimes.sort(key=lambda x: x["group"].start_year, reverse=True) - - return direct_to_template(request, - "announcements/nomcomREDESIGN.html", - { 'curr_chair' : regimes[0]["chair"], - 'regimes' : regimes }) - - -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - nomcom = nomcomREDESIGN - - -def message_detail(request, object_id): - # restrict to nomcom announcements for the time being - nomcoms = Group.objects.filter(acronym__startswith="nomcom").exclude(acronym="nomcom") - m = get_object_or_404(Message, id=object_id, - related_groups__in=nomcoms) - - return direct_to_template(request, - "announcements/message_detail.html", - dict(message=m)) - - diff --git a/ietf/bin/dump-draft-info b/ietf/bin/dump-draft-info index a3a5bfbee..c2008b7ef 100755 --- a/ietf/bin/dump-draft-info +++ b/ietf/bin/dump-draft-info @@ -12,15 +12,21 @@ os.environ["DJANGO_SETTINGS_MODULE"] = "ietf.settings" from django.template import Template, Context -from ietf.idtracker.models import IDInternal -#from ietf.idtracker.models import InternetDraft -#from ietf.idtracker.models import IDStatus +from ietf.doc.models import Document +from ietf.person.models import Person -drafts = IDInternal.objects.all() +drafts = Document.objects.filter(type="draft") -templ_text = """{% for draft in drafts %}{% if draft.state_change_notice_to or draft.job_owner %}{% if draft.draft.filename %}{{ draft.draft.filename }}{% if draft.state_change_notice_to %} docnotify='{{ draft.state_change_notice_to|cut:"<"|cut:">" }}'{% endif %}{% if draft.job_owner %} docsponsor='{{ draft.job_owner.person.email.1 }}'{% endif %} -{% endif %}{% endif %}{% endfor %}""" +ads = {} +for p in Person.objects.filter(ad_document_set__type="draft").distinct(): + ads[p.id] = p.role_email("ad") + +for d in drafts: + d.ad_email = ads.get(d.ad_id) + +templ_text = """{% for draft in drafts %}{% if draft.notify or draft.ad_email %}{{ draft.name }}{% if draft.notify %} docnotify='{{ draft.notify|cut:"<"|cut:">" }}'{% endif %}{% if draft.ad_email %} docsponsor='{{ draft.ad_email }}'{% endif %} +{% endif %}{% endfor %}""" template = Template(templ_text) -context = Context({ 'drafts':drafts }) +context = Context({ 'drafts':drafts }) -print template.render(context) +print template.render(context).encode('utf-8') diff --git a/ietf/bin/expire-submissions b/ietf/bin/expire-submissions new file mode 100644 index 000000000..5801f721e --- /dev/null +++ b/ietf/bin/expire-submissions @@ -0,0 +1,20 @@ +#!/usr/bin/env python + +import datetime, os +import syslog + +from ietf import settings +from django.core import management +management.setup_environ(settings) + +syslog.openlog(os.path.basename(__file__), syslog.LOG_PID, syslog.LOG_USER) + +from ietf.person.models import Person +from ietf.submit.utils import expirable_submissions, expire_submission + +system = Person.objects.get(name="(System)") + +for sub in expirable_submissions(older_than_days=30): + expire_submission(sub, system) + + syslog.syslog("Expired submission %s of %s-%s" % (sub.pk, sub.name, sub.rev)) diff --git a/ietf/bin/find-submission-confirmation-email-in-postfix-log b/ietf/bin/find-submission-confirmation-email-in-postfix-log index d38c20bb9..2270cb7e8 100644 --- a/ietf/bin/find-submission-confirmation-email-in-postfix-log +++ b/ietf/bin/find-submission-confirmation-email-in-postfix-log @@ -31,7 +31,7 @@ from django.conf import settings from ietf.utils.path import path as Path -from ietf.submit.models import IdSubmissionDetail +from ietf.submit.models import Submission from ietf.doc.models import Document @@ -56,13 +56,13 @@ from_email = settings.IDSUBMIT_FROM_EMAIL if "<" in from_email: from_email = from_email.split("<")[1].split(">")[0] -submission = IdSubmissionDetail.objects.filter(filename=draft).latest('submission_date') +submission = Submission.objects.filter(name=draft).latest('submission_date') document = Document.objects.get(name=draft) emails = [ author.address for author in document.authors.all() ] timestrings = [] -for file in [ Path(settings.INTERNET_DRAFT_PATH) / ("%s-%s.txt"%(draft, submission.revision)), - Path(settings.IDSUBMIT_STAGING_PATH) / ("%s-%s.txt"%(draft, submission.revision)) ]: +for file in [ Path(settings.INTERNET_DRAFT_PATH) / ("%s-%s.txt"%(draft, submission.rev)), + Path(settings.IDSUBMIT_STAGING_PATH) / ("%s-%s.txt"%(draft, submission.rev)) ]: if os.path.exists(file): upload_time = time.localtime(file.mtime) ts = time.strftime("%b %d %H:%M", upload_time) @@ -95,4 +95,3 @@ for log in logfiles: for qi in queue_ids: if qi in line: sys.stdout.write(line) - \ No newline at end of file diff --git a/ietf/bin/send-scheduled-mail b/ietf/bin/send-scheduled-mail index 804e1eca6..882e8369c 100755 --- a/ietf/bin/send-scheduled-mail +++ b/ietf/bin/send-scheduled-mail @@ -10,42 +10,24 @@ management.setup_environ(settings) syslog.openlog(os.path.basename(__file__), syslog.LOG_PID, syslog.LOG_USER) -from ietf.announcements.models import ScheduledAnnouncement -from ietf.announcements.send_scheduled import * -from django.db.models import Q - if len(sys.argv) != 2 or sys.argv[1] not in ('all', 'rsync', 'specific'): - print "USAGE: %s " % os.path.basename(__file__) + print "USAGE: %s " % os.path.basename(__file__) print "'all' means all not sent" - print "'rsync' means all not sent where to-be-sent-date is null" print "'specific' means all not sent that are due to be sent" sys.exit(1) +from ietf.message.utils import send_scheduled_message_from_send_queue +from ietf.message.models import SendQueue + mode = sys.argv[1] now = datetime.datetime.now() -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - from ietf.message.models import SendQueue - announcements = SendQueue.objects.filter(sent_at=None) - if mode == "rsync": - announcements = announcements.filter(send_at=None) - elif mode == "specific": - announcements = announcements.exclude(send_at=None).filter(send_at__lte=now) -else: - announcements = ScheduledAnnouncement.objects.filter(mail_sent=False) - if mode == "rsync": - # include bogus 0000-00-00 entries - announcements = announcements.filter(Q(to_be_sent_date=None) | Q(to_be_sent_date__lte=datetime.date.min)) - elif mode == "specific": - # exclude null/bogus entries - announcements = announcements.exclude(Q(to_be_sent_date=None) | Q(to_be_sent_date__lte=datetime.date.min)) +needs_sending = SendQueue.objects.filter(sent_at=None).select_related("message") +if mode == "specific": + needs_sending = needs_sending.exclude(send_at=None).filter(send_at__lte=now) - announcements = announcements.filter(to_be_sent_date__lte=now.date(), - to_be_sent_time__lte=now.time()) - -for announcement in announcements: - send_scheduled_announcement(announcement) +for s in needs_sending: + send_scheduled_message_from_send_queue(s) - subject = announcement.message.subject if settings.USE_DB_REDESIGN_PROXY_CLASSES else announcement.subject - syslog.syslog(u'Sent scheduled announcement %s "%s"' % (announcement.id, subject)) + syslog.syslog(u'Sent scheduled message %s "%s"' % (s.id, s.message.subject)) diff --git a/ietf/bin/test-crawl b/ietf/bin/test-crawl index 405be9341..3c71f01f7 100755 --- a/ietf/bin/test-crawl +++ b/ietf/bin/test-crawl @@ -24,7 +24,7 @@ connection.queries = DontSaveQueries() MAX_URL_LENGTH = 500 SLOW_THRESHOLD = 1.0 -initial = ["/doc/all/", "/doc/in-last-call/"] +initial = ["/doc/all/", "/doc/in-last-call/", "/iesg/decisions/"] visited = set() urls = {} # url -> referrer diff --git a/ietf/community/display.py b/ietf/community/display.py index ac93159d0..3164192cc 100644 --- a/ietf/community/display.py +++ b/ietf/community/display.py @@ -3,7 +3,6 @@ import datetime from django.db.models import Q from django.core.urlresolvers import reverse as urlreverse -from ietf.ietfworkflows.utils import get_state_for_draft from ietf.doc.models import DocAlias, DocEvent diff --git a/ietf/community/management/commands/update_doc_change_dates.py b/ietf/community/management/commands/update_doc_change_dates.py index 825edb539..32dbf22fd 100644 --- a/ietf/community/management/commands/update_doc_change_dates.py +++ b/ietf/community/management/commands/update_doc_change_dates.py @@ -5,18 +5,18 @@ from django.db.models import Q from ietf.community.constants import SIGNIFICANT_STATES from ietf.community.models import DocumentChangeDates -from redesign.doc.models import Document +from ietf.doc.models import Document class Command(BaseCommand): help = (u"Update drafts in community lists by reviewing their rules") def handle(self, *args, **options): - documents = Document.objects.filter(Q(type__name='Draft') | Q(states__name='rfc')).distinct() + documents = Document.objects.filter(type='draft') index = 1 total = documents.count() - for doc in documents: + for doc in documents.iterator(): (changes, created) = DocumentChangeDates.objects.get_or_create(document=doc) new_version = doc.latest_event(type='new_revision') normal_change = doc.latest_event() diff --git a/ietf/cookies/views.py b/ietf/cookies/views.py index 98eadaa4b..d2703c8cc 100644 --- a/ietf/cookies/views.py +++ b/ietf/cookies/views.py @@ -51,7 +51,7 @@ def expires_soon(request, days="14"): def full_draft(request, enabled="off"): if enabled != "on" and enabled != "off": - enabled = "off" + enabled = "off" response = settings(request, -1, -1, enabled) response.set_cookie("full_draft", enabled, 315360000) return response diff --git a/ietf/dbtemplate/views.py b/ietf/dbtemplate/views.py index bcfcbd636..95529c378 100644 --- a/ietf/dbtemplate/views.py +++ b/ietf/dbtemplate/views.py @@ -5,7 +5,7 @@ from django.template import RequestContext from ietf.dbtemplate.models import DBTemplate from ietf.dbtemplate.forms import DBTemplateForm from ietf.group.models import Group -from ietf.ietfauth.decorators import has_role +from ietf.ietfauth.utils import has_role def template_list(request, acronym): diff --git a/ietf/doc/mails.py b/ietf/doc/mails.py index 7f483ad5e..54242c747 100644 --- a/ietf/doc/mails.py +++ b/ietf/doc/mails.py @@ -9,7 +9,7 @@ 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.doc.models import WriteupDocEvent, BallotPositionDocEvent, LastCallDocEvent, DocAlias, ConsensusDocEvent +from ietf.doc.models import WriteupDocEvent, BallotPositionDocEvent, LastCallDocEvent, DocAlias, ConsensusDocEvent, DocTagName from ietf.person.models import Person from ietf.group.models import Group, Role @@ -413,3 +413,66 @@ def email_last_call_expired(doc): doc=doc, url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url()), cc="iesg-secretary@ietf.org") + +def stream_state_email_recipients(doc, extra_recipients=[]): + persons = set() + res = [] + for r in Role.objects.filter(group=doc.group, name__in=("chair", "delegate")).select_related("person", "email"): + res.append(r.formatted_email()) + persons.add(r.person) + + for email in doc.authors.all(): + if email.person not in persons: + res.append(email.formatted_email()) + persons.add(email.person) + + for p in extra_recipients: + if not p in persons: + res.append(p.formatted_email()) + persons.add(p) + + return res + +def email_draft_adopted(request, doc, by, comment): + recipients = stream_state_email_recipients(doc) + send_mail(request, recipients, settings.DEFAULT_FROM_EMAIL, + u"%s adopted in %s %s" % (doc.name, doc.group.acronym, doc.group.type.name), + 'doc/mail/draft_adopted_email.txt', + dict(doc=doc, + url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url(), + by=by, + comment=comment)) + +def email_stream_state_changed(request, doc, prev_state, new_state, by, comment=""): + recipients = stream_state_email_recipients(doc) + + state_type = (prev_state or new_state).type + + send_mail(request, recipients, settings.DEFAULT_FROM_EMAIL, + u"%s changed for %s" % (state_type.label, doc.name), + 'doc/mail/stream_state_changed_email.txt', + dict(doc=doc, + url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url(), + state_type=state_type, + prev_state=prev_state, + new_state=new_state, + by=by, + comment=comment)) + +def email_stream_tags_changed(request, doc, added_tags, removed_tags, by, comment=""): + extra_recipients = [] + + if DocTagName.objects.get(slug="sheph-u") in added_tags and doc.shepherd: + extra_recipients.append(doc.shepherd) + + recipients = stream_state_email_recipients(doc, extra_recipients) + + send_mail(request, recipients, settings.DEFAULT_FROM_EMAIL, + u"Tags changed for %s" % doc.name, + 'doc/mail/stream_tags_changed_email.txt', + dict(doc=doc, + url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url(), + added=added_tags, + removed=removed_tags, + by=by, + comment=comment)) diff --git a/ietf/doc/migrations/0015_split_state_changing_iesg_approve_events.py b/ietf/doc/migrations/0015_split_state_changing_iesg_approve_events.py new file mode 100644 index 000000000..f12b880d9 --- /dev/null +++ b/ietf/doc/migrations/0015_split_state_changing_iesg_approve_events.py @@ -0,0 +1,435 @@ +# encoding: utf-8 +import datetime +from south.db import db +from south.v2 import DataMigration +from django.db import models + +class Migration(DataMigration): + + def forwards(self, orm): + state_mapping = dict((s.name.lower(), s) for s in orm.State.objects.filter(type="draft-iesg")) + doc_type_mapping = { + 'draft': " the document", + 'conflrev': " the conflict review response", + 'statchg': " the status change", + 'charter': " the charter", + } + + import re + approve_re = re.compile(r"IESG has approved( the charter| the document| the conflict review response| the status change)?( and state has been changed to '?(.*?)'?( by .*)?\.?)?$") + disapprove_re = re.compile("(DNP|Do Not Publish) note has been sent to( the)? RFC Editor( and state has been changed to '?(.*?)'?( by .*)?\.?)?$") + for e in orm.DocEvent.objects.filter(type__in=("iesg_disapproved", "iesg_approved")).order_by("id").select_related("doc").iterator(): + if e.type == "iesg_approved": + m = approve_re.match(e.desc) + if not m: + print "FAIL", e.desc + else: + doc_type, state_set, state_name, by = m.groups() + + if state_set: + state = state_mapping[state_name.lower()] + + s = orm.StateDocEvent() + s.doc_id = e.doc_id + s.by_id = e.by_id + s.type = "changed_state" + s.state_type_id = state.type_id + s.state = state + s.desc = "%s changed to %s" % (state.type.label, state.name) + s.time = e.time + s.save() + + #print e.doc_id, s.desc + + if not doc_type: + doc_type = doc_type_mapping[e.doc.type_id] + + new_desc = "IESG has approved%s" % doc_type + + if new_desc != e.desc: + #print e.doc_id, e.desc, "->", new_desc + orm.DocEvent.objects.filter(id=e.id).update(desc=new_desc) + + elif e.type == "iesg_disapproved": + m = disapprove_re.match(e.desc) + if not m: + print "FAIL", e.desc + else: + dnp, the, state_set, state_name, by = m.groups() + + if state_set: + state = state_mapping[state_name.lower()] + + s = orm.StateDocEvent() + s.doc_id = e.doc_id + s.by_id = e.by_id + s.type = "changed_state" + s.state_type_id = state.type_id + s.state = state + s.desc = "%s changed to %s" % (state.type.label, state.name) + s.time = e.time + s.save() + + #print e.doc_id, s.desc + + new_desc = "Do Not Publish note has been sent to the RFC Editor" + + if new_desc != e.desc: + #print e.doc_id, e.desc, "->", new_desc + orm.DocEvent.objects.filter(id=e.id).update(desc=new_desc) + + + def backwards(self, orm): + "Write your backwards methods here." + + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + '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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + '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', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + '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', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}) + }, + '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'}), + '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'}) + }, + 'doc.ballotdocevent': { + 'Meta': {'ordering': "['-time', '-id']", 'object_name': 'BallotDocEvent', '_ormbases': ['doc.DocEvent']}, + 'ballot_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.BallotType']"}), + 'docevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['doc.DocEvent']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'doc.ballotpositiondocevent': { + 'Meta': {'ordering': "['-time', '-id']", 'object_name': 'BallotPositionDocEvent', '_ormbases': ['doc.DocEvent']}, + 'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"}), + 'ballot': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['doc.BallotDocEvent']", 'null': 'True'}), + 'comment': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'comment_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'discuss': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'discuss_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'docevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['doc.DocEvent']", 'unique': 'True', 'primary_key': 'True'}), + 'pos': ('django.db.models.fields.related.ForeignKey', [], {'default': "'norecord'", 'to': "orm['name.BallotPositionName']"}) + }, + 'doc.ballottype': { + 'Meta': {'ordering': "['order']", 'object_name': 'BallotType'}, + 'doc_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.DocTypeName']", 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'positions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['name.BallotPositionName']", 'symmetrical': 'False', 'blank': 'True'}), + 'question': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'db_index': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + 'doc.consensusdocevent': { + 'Meta': {'ordering': "['-time', '-id']", 'object_name': 'ConsensusDocEvent', '_ormbases': ['doc.DocEvent']}, + 'consensus': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'docevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['doc.DocEvent']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'doc.deletedevent': { + 'Meta': {'object_name': 'DeletedEvent'}, + 'by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'json': ('django.db.models.fields.TextField', [], {}), + 'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}) + }, + 'doc.docalias': { + 'Meta': {'object_name': 'DocAlias'}, + 'document': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.Document']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}) + }, + 'doc.docevent': { + 'Meta': {'ordering': "['-time', '-id']", 'object_name': 'DocEvent'}, + 'by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"}), + 'desc': ('django.db.models.fields.TextField', [], {}), + 'doc': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.Document']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'doc.dochistory': { + 'Meta': {'object_name': 'DocHistory'}, + 'abstract': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'ad': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'ad_dochistory_set'", 'null': 'True', 'to': "orm['person.Person']"}), + 'authors': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['person.Email']", 'symmetrical': 'False', 'through': "orm['doc.DocHistoryAuthor']", 'blank': 'True'}), + 'doc': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'history_set'", 'to': "orm['doc.Document']"}), + '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': "orm['group.Group']", 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'intended_std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': "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'}), + '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'}), + 'related': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.DocAlias']", 'symmetrical': 'False', 'through': "orm['doc.RelatedDocHistory']", '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_dochistory_set'", 'null': 'True', 'to': "orm['person.Person']"}), + 'states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}), + 'std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.StdLevelName']", 'null': 'True', 'blank': 'True'}), + 'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.StreamName']", 'null': 'True', 'blank': 'True'}), + 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "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': "orm['name.DocTypeName']", 'null': 'True', 'blank': 'True'}) + }, + 'doc.dochistoryauthor': { + 'Meta': {'ordering': "['document', 'order']", 'object_name': 'DocHistoryAuthor'}, + 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Email']"}), + 'document': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.DocHistory']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'order': ('django.db.models.fields.IntegerField', [], {}) + }, + 'doc.docreminder': { + 'Meta': {'object_name': 'DocReminder'}, + 'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'due': ('django.db.models.fields.DateTimeField', [], {}), + 'event': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.DocEvent']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.DocReminderTypeName']"}) + }, + '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': "orm['person.Person']"}), + 'authors': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['person.Email']", 'symmetrical': 'False', 'through': "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': "orm['group.Group']", 'null': 'True', 'blank': 'True'}), + 'intended_std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': "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': "orm['person.Person']"}), + 'states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}), + 'std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.StdLevelName']", 'null': 'True', 'blank': 'True'}), + 'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.StreamName']", 'null': 'True', 'blank': 'True'}), + 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "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': "orm['name.DocTypeName']", 'null': 'True', 'blank': 'True'}) + }, + 'doc.documentauthor': { + 'Meta': {'ordering': "['document', 'order']", 'object_name': 'DocumentAuthor'}, + 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Email']"}), + 'document': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.Document']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '1'}) + }, + 'doc.initialreviewdocevent': { + 'Meta': {'ordering': "['-time', '-id']", 'object_name': 'InitialReviewDocEvent', '_ormbases': ['doc.DocEvent']}, + 'docevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['doc.DocEvent']", 'unique': 'True', 'primary_key': 'True'}), + 'expires': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}) + }, + 'doc.lastcalldocevent': { + 'Meta': {'ordering': "['-time', '-id']", 'object_name': 'LastCallDocEvent', '_ormbases': ['doc.DocEvent']}, + 'docevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['doc.DocEvent']", 'unique': 'True', 'primary_key': 'True'}), + 'expires': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}) + }, + 'doc.newrevisiondocevent': { + 'Meta': {'ordering': "['-time', '-id']", 'object_name': 'NewRevisionDocEvent', '_ormbases': ['doc.DocEvent']}, + 'docevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['doc.DocEvent']", 'unique': 'True', 'primary_key': 'True'}), + 'rev': ('django.db.models.fields.CharField', [], {'max_length': '16'}) + }, + 'doc.relateddochistory': { + 'Meta': {'object_name': 'RelatedDocHistory'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'relationship': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.DocRelationshipName']"}), + 'source': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.DocHistory']"}), + 'target': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'reversely_related_document_history_set'", 'to': "orm['doc.DocAlias']"}) + }, + 'doc.relateddocument': { + 'Meta': {'object_name': 'RelatedDocument'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'relationship': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.DocRelationshipName']"}), + 'source': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.Document']"}), + 'target': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.DocAlias']"}) + }, + 'doc.state': { + 'Meta': {'ordering': "['type', 'order']", 'object_name': 'State'}, + 'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + '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': "orm['doc.State']"}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'db_index': 'True'}), + 'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.StateType']"}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + 'doc.statedocevent': { + 'Meta': {'ordering': "['-time', '-id']", 'object_name': 'StateDocEvent', '_ormbases': ['doc.DocEvent']}, + 'docevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['doc.DocEvent']", 'unique': 'True', 'primary_key': 'True'}), + 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.State']", 'null': 'True', 'blank': 'True'}), + 'state_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.StateType']"}) + }, + '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'}) + }, + 'doc.telechatdocevent': { + 'Meta': {'ordering': "['-time', '-id']", 'object_name': 'TelechatDocEvent', '_ormbases': ['doc.DocEvent']}, + 'docevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['doc.DocEvent']", 'unique': 'True', 'primary_key': 'True'}), + 'returning_item': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'telechat_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}) + }, + 'doc.writeupdocevent': { + 'Meta': {'ordering': "['-time', '-id']", 'object_name': 'WriteupDocEvent', '_ormbases': ['doc.DocEvent']}, + 'docevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['doc.DocEvent']", 'unique': 'True', 'primary_key': 'True'}), + 'text': ('django.db.models.fields.TextField', [], {'blank': 'True'}) + }, + 'group.group': { + 'Meta': {'object_name': 'Group'}, + 'acronym': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '40', 'db_index': 'True'}), + 'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "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': "orm['doc.Document']"}), + 'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + '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': "orm['group.Group']", 'null': 'True', 'blank': 'True'}), + 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupStateName']", 'null': 'True'}), + 'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupTypeName']", 'null': 'True'}), + 'unused_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}), + 'unused_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['name.DocTagName']", 'symmetrical': 'False', 'blank': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': "orm['person.Person']", 'null': 'True'}), + 'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}) + }, + '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'}), + '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': "orm['auth.User']", 'unique': 'True', 'null': 'True', 'blank': 'True'}) + } + } + + complete_apps = ['doc'] diff --git a/ietf/doc/migrations/0016_add_docevent_time_index.py b/ietf/doc/migrations/0016_add_docevent_time_index.py new file mode 100644 index 000000000..d77cff9c7 --- /dev/null +++ b/ietf/doc/migrations/0016_add_docevent_time_index.py @@ -0,0 +1,370 @@ +# encoding: utf-8 +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + +class Migration(SchemaMigration): + + def forwards(self, orm): + + # Adding index on 'DocEvent', fields ['time'] + db.create_index('doc_docevent', ['time']) + + + def backwards(self, orm): + + # Removing index on 'DocEvent', fields ['time'] + db.delete_index('doc_docevent', ['time']) + + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + '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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + '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', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + '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', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}) + }, + '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'}), + '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'}) + }, + 'doc.ballotdocevent': { + 'Meta': {'ordering': "['-time', '-id']", 'object_name': 'BallotDocEvent', '_ormbases': ['doc.DocEvent']}, + 'ballot_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.BallotType']"}), + 'docevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['doc.DocEvent']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'doc.ballotpositiondocevent': { + 'Meta': {'ordering': "['-time', '-id']", 'object_name': 'BallotPositionDocEvent', '_ormbases': ['doc.DocEvent']}, + 'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"}), + 'ballot': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['doc.BallotDocEvent']", 'null': 'True'}), + 'comment': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'comment_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'discuss': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'discuss_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'docevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['doc.DocEvent']", 'unique': 'True', 'primary_key': 'True'}), + 'pos': ('django.db.models.fields.related.ForeignKey', [], {'default': "'norecord'", 'to': "orm['name.BallotPositionName']"}) + }, + 'doc.ballottype': { + 'Meta': {'ordering': "['order']", 'object_name': 'BallotType'}, + 'doc_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.DocTypeName']", 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'positions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['name.BallotPositionName']", 'symmetrical': 'False', 'blank': 'True'}), + 'question': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'db_index': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + 'doc.consensusdocevent': { + 'Meta': {'ordering': "['-time', '-id']", 'object_name': 'ConsensusDocEvent', '_ormbases': ['doc.DocEvent']}, + 'consensus': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'docevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['doc.DocEvent']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'doc.deletedevent': { + 'Meta': {'object_name': 'DeletedEvent'}, + 'by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'json': ('django.db.models.fields.TextField', [], {}), + 'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}) + }, + 'doc.docalias': { + 'Meta': {'object_name': 'DocAlias'}, + 'document': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.Document']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}) + }, + 'doc.docevent': { + 'Meta': {'ordering': "['-time', '-id']", 'object_name': 'DocEvent'}, + 'by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"}), + 'desc': ('django.db.models.fields.TextField', [], {}), + 'doc': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.Document']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'doc.dochistory': { + 'Meta': {'object_name': 'DocHistory'}, + 'abstract': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'ad': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'ad_dochistory_set'", 'null': 'True', 'to': "orm['person.Person']"}), + 'authors': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['person.Email']", 'symmetrical': 'False', 'through': "orm['doc.DocHistoryAuthor']", 'blank': 'True'}), + 'doc': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'history_set'", 'to': "orm['doc.Document']"}), + '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': "orm['group.Group']", 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'intended_std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': "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'}), + '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'}), + 'related': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.DocAlias']", 'symmetrical': 'False', 'through': "orm['doc.RelatedDocHistory']", '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_dochistory_set'", 'null': 'True', 'to': "orm['person.Person']"}), + 'states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}), + 'std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.StdLevelName']", 'null': 'True', 'blank': 'True'}), + 'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.StreamName']", 'null': 'True', 'blank': 'True'}), + 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "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': "orm['name.DocTypeName']", 'null': 'True', 'blank': 'True'}) + }, + 'doc.dochistoryauthor': { + 'Meta': {'ordering': "['document', 'order']", 'object_name': 'DocHistoryAuthor'}, + 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Email']"}), + 'document': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.DocHistory']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'order': ('django.db.models.fields.IntegerField', [], {}) + }, + 'doc.docreminder': { + 'Meta': {'object_name': 'DocReminder'}, + 'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'due': ('django.db.models.fields.DateTimeField', [], {}), + 'event': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.DocEvent']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.DocReminderTypeName']"}) + }, + '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': "orm['person.Person']"}), + 'authors': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['person.Email']", 'symmetrical': 'False', 'through': "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': "orm['group.Group']", 'null': 'True', 'blank': 'True'}), + 'intended_std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': "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': "orm['person.Person']"}), + 'states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}), + 'std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.StdLevelName']", 'null': 'True', 'blank': 'True'}), + 'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.StreamName']", 'null': 'True', 'blank': 'True'}), + 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "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': "orm['name.DocTypeName']", 'null': 'True', 'blank': 'True'}) + }, + 'doc.documentauthor': { + 'Meta': {'ordering': "['document', 'order']", 'object_name': 'DocumentAuthor'}, + 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Email']"}), + 'document': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.Document']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '1'}) + }, + 'doc.initialreviewdocevent': { + 'Meta': {'ordering': "['-time', '-id']", 'object_name': 'InitialReviewDocEvent', '_ormbases': ['doc.DocEvent']}, + 'docevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['doc.DocEvent']", 'unique': 'True', 'primary_key': 'True'}), + 'expires': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}) + }, + 'doc.lastcalldocevent': { + 'Meta': {'ordering': "['-time', '-id']", 'object_name': 'LastCallDocEvent', '_ormbases': ['doc.DocEvent']}, + 'docevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['doc.DocEvent']", 'unique': 'True', 'primary_key': 'True'}), + 'expires': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}) + }, + 'doc.newrevisiondocevent': { + 'Meta': {'ordering': "['-time', '-id']", 'object_name': 'NewRevisionDocEvent', '_ormbases': ['doc.DocEvent']}, + 'docevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['doc.DocEvent']", 'unique': 'True', 'primary_key': 'True'}), + 'rev': ('django.db.models.fields.CharField', [], {'max_length': '16'}) + }, + 'doc.relateddochistory': { + 'Meta': {'object_name': 'RelatedDocHistory'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'relationship': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.DocRelationshipName']"}), + 'source': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.DocHistory']"}), + 'target': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'reversely_related_document_history_set'", 'to': "orm['doc.DocAlias']"}) + }, + 'doc.relateddocument': { + 'Meta': {'object_name': 'RelatedDocument'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'relationship': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.DocRelationshipName']"}), + 'source': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.Document']"}), + 'target': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.DocAlias']"}) + }, + 'doc.state': { + 'Meta': {'ordering': "['type', 'order']", 'object_name': 'State'}, + 'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + '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': "orm['doc.State']"}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'db_index': 'True'}), + 'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.StateType']"}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + 'doc.statedocevent': { + 'Meta': {'ordering': "['-time', '-id']", 'object_name': 'StateDocEvent', '_ormbases': ['doc.DocEvent']}, + 'docevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['doc.DocEvent']", 'unique': 'True', 'primary_key': 'True'}), + 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.State']", 'null': 'True', 'blank': 'True'}), + 'state_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.StateType']"}) + }, + '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'}) + }, + 'doc.telechatdocevent': { + 'Meta': {'ordering': "['-time', '-id']", 'object_name': 'TelechatDocEvent', '_ormbases': ['doc.DocEvent']}, + 'docevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['doc.DocEvent']", 'unique': 'True', 'primary_key': 'True'}), + 'returning_item': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'telechat_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}) + }, + 'doc.writeupdocevent': { + 'Meta': {'ordering': "['-time', '-id']", 'object_name': 'WriteupDocEvent', '_ormbases': ['doc.DocEvent']}, + 'docevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['doc.DocEvent']", 'unique': 'True', 'primary_key': 'True'}), + 'text': ('django.db.models.fields.TextField', [], {'blank': 'True'}) + }, + 'group.group': { + 'Meta': {'object_name': 'Group'}, + 'acronym': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '40', 'db_index': 'True'}), + 'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "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': "orm['doc.Document']"}), + 'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + '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': "orm['group.Group']", 'null': 'True', 'blank': 'True'}), + 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupStateName']", 'null': 'True'}), + 'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupTypeName']", 'null': 'True'}), + 'unused_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}), + 'unused_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['name.DocTagName']", 'symmetrical': 'False', 'blank': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': "orm['person.Person']", 'null': 'True'}), + 'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}) + }, + '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'}), + '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': "orm['auth.User']", 'unique': 'True', 'null': 'True', 'blank': 'True'}) + } + } + + complete_apps = ['doc'] diff --git a/ietf/doc/models.py b/ietf/doc/models.py index f1219318e..058ae0d9c 100644 --- a/ietf/doc/models.py +++ b/ietf/doc/models.py @@ -80,6 +80,8 @@ class DocumentInfo(models.Model): return settings.CHARTER_PATH elif self.type_id == "conflrev": return settings.CONFLICT_REVIEW_PATH + elif self.type_id == "statchg": + return settings.STATUS_CHANGE_PATH else: raise NotImplemented @@ -120,7 +122,7 @@ class DocumentInfo(models.Model): if not hasattr(self, "state_cache") or self.state_cache == None: self.state_cache = {} - for s in self.states.all().select_related(): + for s in self.states.all().select_related("type"): self.state_cache[s.type_id] = s return self.state_cache.get(state_type, None) @@ -147,8 +149,8 @@ class DocumentInfo(models.Model): def active_ballot(self): """Returns the most recently created ballot if it isn't closed.""" - ballot = self.latest_event(BallotDocEvent, type="created_ballot") - if ballot and self.ballot_open(ballot.ballot_type.slug): + ballot = self.latest_event(BallotDocEvent, type__in=("created_ballot", "closed_ballot")) + if ballot and ballot.type == "created_ballot": return ballot else: return None @@ -334,7 +336,7 @@ class Document(DocumentInfo): if g: if g.type_id == "area": return g.acronym - elif g.type_id != "individ": + elif g.type_id != "individ" and g.parent: return g.parent.acronym else: return None @@ -367,7 +369,7 @@ class Document(DocumentInfo): return self.latest_event(LastCallDocEvent,type="sent_last_call") def displayname_with_link(self): - return '%s-%s' % (self.get_absolute_url(), self.name , self.rev) + return mark_safe('%s-%s' % (self.get_absolute_url(), self.name , self.rev)) def rfc_number(self): n = self.canonical_name() @@ -596,7 +598,7 @@ EVENT_TYPES = [ class DocEvent(models.Model): """An occurrence for a document, used for tracking who, when and what.""" - time = models.DateTimeField(default=datetime.datetime.now, help_text="When the event happened") + time = models.DateTimeField(default=datetime.datetime.now, help_text="When the event happened", db_index=True) type = models.CharField(max_length=50, choices=EVENT_TYPES) by = models.ForeignKey(Person) doc = models.ForeignKey('doc.Document') @@ -642,17 +644,15 @@ class BallotDocEvent(DocEvent): active_ads = list(Person.objects.filter(role__name="ad", role__group__state="active")) res = {} - if self.doc.latest_event(BallotDocEvent, type="created_ballot") == self: - - positions = BallotPositionDocEvent.objects.filter(type="changed_ballot_position",ad__in=active_ads, ballot=self).select_related('ad', 'pos').order_by("-time", "-id") - - for pos in positions: - if pos.ad not in res: - res[pos.ad] = pos - - for ad in active_ads: - if ad not in res: - res[ad] = None + positions = BallotPositionDocEvent.objects.filter(type="changed_ballot_position",ad__in=active_ads, ballot=self).select_related('ad', 'pos').order_by("-time", "-id") + + for pos in positions: + if pos.ad not in res: + res[pos.ad] = pos + + for ad in active_ads: + if ad not in res: + res[ad] = None return res def all_positions(self): diff --git a/ietf/doc/proxy.py b/ietf/doc/proxy.py deleted file mode 100644 index 21993174c..000000000 --- a/ietf/doc/proxy.py +++ /dev/null @@ -1,1003 +0,0 @@ -import glob -import os -import math - -from ietf.doc.models import * -from ietf.person.models import Email -from ietf.utils.proxy import TranslatingManager -from ietf.name.proxy import * - -from django.conf import settings - -class InternetDraft(Document): - objects = TranslatingManager(dict(filename="name", - filename__contains="name__contains", - id_document_tag="pk", - status=lambda v: ("states__slug", { 1: 'active', 2: 'expired', 3: 'rfc', 4: 'auth-rm', 5: 'repl', 6: 'ietf-rm'}[v], "states__type", "draft"), - job_owner="ad", - rfc_number=lambda v: ("docalias__name", "rfc%s" % v), - cur_state=lambda v: ("states__order", v, 'states__type', 'draft-iesg'), - idinternal__primary_flag=None, - idinternal__cur_state__state=lambda v: ("states__name", v, 'states__type', 'draft-iesg'), - ), always_filter=dict(type="draft")) - - DAYS_TO_EXPIRE=185 - - # things from InternetDraft - - #id_document_tag = models.AutoField(primary_key=True) - @property - def id_document_tag(self): - return self.name # Will only work for some use cases - #title = models.CharField(max_length=255, db_column='id_document_name') # same name - #id_document_key = models.CharField(max_length=255, editable=False) - @property - def id_document_key(self): - return self.title.upper() - #group = models.ForeignKey(Acronym, db_column='group_acronym_id') - @property - def group(self): - from ietf.group.proxy import Acronym as AcronymProxy - g = super(InternetDraft, self).group - return AcronymProxy().from_object(g) if g else None - #filename = models.CharField(max_length=255, unique=True) - @property - def filename(self): - return self.name - #revision = models.CharField(max_length=2) - @property - def revision(self): - return self.rev - #revision_date = models.DateField() - @property - def revision_date(self): - if hasattr(self, "new_revision"): - e = self.new_revision - else: - e = self.latest_event(type="new_revision") - return e.time.date() if e else None - # helper function - def get_file_type_matches_from(self, base_path): - possible_types = [".txt", ".pdf", ".xml", ".ps"] - res = [] - for m in glob.glob(base_path + '.*'): - for t in possible_types: - if base_path + t == m: - res.append(t) - return ",".join(res) - #file_type = models.CharField(max_length=20) - @property - def file_type(self): - return self.get_file_type_matches_from(os.path.join(settings.INTERNET_DRAFT_PATH, self.name + "-" + self.rev)) or ".txt" - #txt_page_count = models.IntegerField() - @property - def txt_page_count(self): - return self.pages - #local_path = models.CharField(max_length=255, blank=True) # unused - #start_date = models.DateField() - @property - def start_date(self): - e = NewRevisionDocEvent.objects.filter(doc=self).order_by("time")[:1] - return e[0].time.date() if e else None - #expiration_date = models.DateField() - @property - def expiration_date(self): - e = self.latest_event(type__in=('expired_document', 'new_revision', "completed_resurrect")) - return e.time.date() if e and e.type == "expired_document" else None - #abstract = models.TextField() # same name - #dunn_sent_date = models.DateField(null=True, blank=True) # unused - #extension_date = models.DateField(null=True, blank=True) # unused - #status = models.ForeignKey(IDStatus) - @property - def status(self): - s = self.get_state() - return IDStatus().from_object(s) if s else None - - @property - def status_id(self): - return { 'active': 1, 'repl': 5, 'expired': 2, 'rfc': 3, 'auth-rm': 4, 'ietf-rm': 6 }[self.get_state_slug()] - - #intended_status = models.ForeignKey(IDIntendedStatus) - @property - def intended_status(self): - return self.intended_std_level - - #lc_sent_date = models.DateField(null=True, blank=True) - @property - def lc_sent_date(self): - e = self.latest_event(type="sent_last_call") - return e.time.date() if e else None - - #lc_changes = models.CharField(max_length=3) # used in DB, unused in Django code? - - #lc_expiration_date = models.DateField(null=True, blank=True) - @property - def lc_expiration_date(self): - e = self.latest_event(LastCallDocEvent, type="sent_last_call") - return e.expires.date() if e else None - - #b_sent_date = models.DateField(null=True, blank=True) - @property - def b_sent_date(self): - e = self.latest_event(type="sent_ballot_announcement") - return e.time.date() if e else None - - #b_discussion_date = models.DateField(null=True, blank=True) # unused - - #b_approve_date = models.DateField(null=True, blank=True) - @property - def b_approve_date(self): - e = self.latest_event(type="iesg_approved") - return e.time.date() if e else None - - #wgreturn_date = models.DateField(null=True, blank=True) # unused - - #rfc_number = models.IntegerField(null=True, blank=True, db_index=True) - @property - def rfc_number(self): - n = self.canonical_name() - return int(n[3:]) if n.startswith("rfc") else None - - #comments = models.TextField(blank=True) # unused - - #last_modified_date = models.DateField() - @property - def last_modified_date(self): - return self.time.date() - - #replaced_by = models.ForeignKey('self', db_column='replaced_by', blank=True, null=True, related_name='replaces_set') - @property - def replaced_by(self): - r = InternetDraft.objects.filter(relateddocument__target__document=self, relateddocument__relationship="replaces") - return r[0] if r else None - - @property - def replaced_by_id(self): - r = self.replaced_by - return r.id_document_tag if r else None - - #replaces = FKAsOneToOne('replaces', reverse=True) - @property - def replaces(self): - r = self.replaces_set - return r[0] if r else None - - @property - def replaces_set(self): - return InternetDraft.objects.filter(docalias__relateddocument__source=self, docalias__relateddocument__relationship="replaces") - - #review_by_rfc_editor = models.BooleanField() - @property - def review_by_rfc_editor(self): - return bool(self.tags.filter(slug='rfc-rev')) - - #expired_tombstone = models.BooleanField() - @property - def expired_tombstone(self): - return False - - #shepherd = BrokenForeignKey('PersonOrOrgInfo', null=True, blank=True, null_values=(0, )) # same name - - #idinternal = FKAsOneToOne('idinternal', reverse=True, query=models.Q(rfc_flag = 0)) - @property - def idinternal(self): - # since IDInternal is now merged into the document, we try to - # guess here - if hasattr(self, "changed_ballot_position"): - e = self.changed_ballot_position - else: - e = self.latest_event(type="changed_ballot_position") - return self if e or self.get_state("draft-iesg") else None - - # reverse relationship - @property - def authors(self): - return IDAuthor.objects.filter(document=self) - - @property - def protowriteup_set(self): - from ietf.wgchairs.models import ProtoWriteUpProxy - return ProtoWriteUpProxy.objects.filter(doc=self, type="changed_protocol_writeup") - - # methods from InternetDraft - def displayname(self): - return self.name - def file_tag(self): - return "<%s>" % self.filename_with_rev() - def filename_with_rev(self): - return "%s-%s.txt" % (self.filename, self.revision_display()) - def group_acronym(self): - g = super(Document, self).group - if g.type_id == "area": - return "none" - else: - return g.acronym - def group_ml_archive(self): - return self.group.list_archive - def idstate(self): - return self.docstate() - def revision_display(self): - return self.rev - def expiration(self): - return self.expires.date() - def can_expire(self): - # Copying the logic from expire-ids-1 without thinking - # much about it. - if self.review_by_rfc_editor: - return False - idinternal = self.idinternal - if idinternal: - cur_state_id = idinternal.cur_state_id - # 42 is "AD is Watching"; this matches what's in the - # expire-ids-1 perl script. - # A better way might be to add a column to the table - # saying whether or not a document is prevented from - # expiring. - if cur_state_id < 42: - return False - return True - - def clean_abstract(self): - # Cleaning based on what "id-abstracts-text" script does - import re - a = self.abstract - a = re.sub(" *\r\n *", "\n", a) # get rid of DOS line endings - a = re.sub(" *\r *", "\n", a) # get rid of MAC line endings - a = re.sub("(\n *){3,}", "\n\n", a) # get rid of excessive vertical whitespace - a = re.sub("\f[\n ]*[^\n]*\n", "", a) # get rid of page headers - # Get rid of 'key words' boilerplate and anything which follows it: - # (No way that is part of the abstract...) - a = re.sub("(?s)(Conventions [Uu]sed in this [Dd]ocument|Requirements [Ll]anguage)?[\n ]*The key words \"MUST\", \"MUST NOT\",.*$", "", a) - # Get rid of status/copyright boilerplate - a = re.sub("(?s)\nStatus of [tT]his Memo\n.*$", "", a) - # wrap long lines without messing up formatting of Ok paragraphs: - while re.match("([^\n]{72,}?) +", a): - a = re.sub("([^\n]{72,}?) +([^\n ]*)(\n|$)", "\\1\n\\2 ", a) - # Remove leading and trailing whitespace - a = a.strip() - return a - - - # things from IDInternal - - #draft = models.ForeignKey(InternetDraft, primary_key=True, unique=True, db_column='id_document_tag') - @property - def draft(self): - return self - - @property - def draft_id(self): - return self.name - - #rfc_flag = models.IntegerField(null=True) - @property - def rfc_flag(self): - return self.get_state_slug() == "rfc" - - #ballot = models.ForeignKey(BallotInfo, related_name='drafts', db_column="ballot_id") - @property - def ballot(self): - if not self.idinternal: - raise BallotInfo.DoesNotExist() - return self - @property - def ballot_id(self): - return self.ballot.name - - #primary_flag = models.IntegerField(blank=True, null=True) - @property - def primary_flag(self): - # left-over from multi-ballot documents which we don't really - # support anymore, just pretend we're always primary - return True - - #group_flag = models.IntegerField(blank=True, default=0) # not used anymore, contained the group acronym_id once upon a time (so it wasn't a flag) - - #token_name = models.CharField(blank=True, max_length=25) - @property - def token_name(self): - return self.ad.plain_name() - - #token_email = models.CharField(blank=True, max_length=255) - @property - def token_email(self): - return self.ad.role_email("ad") - - #note = models.TextField(blank=True) # same name - - #status_date = models.DateField(blank=True,null=True) - @property - def status_date(self): - return self.time.date() - - #email_display = models.CharField(blank=True, max_length=50) # unused - #agenda = models.IntegerField(null=True, blank=True) - @property - def agenda(self): - e = self.latest_event(TelechatDocEvent, type="scheduled_for_telechat") - return bool(e and e.telechat_date and e.telechat_date >= datetime.date.today()) - - #cur_state = models.ForeignKey(IDState, db_column='cur_state', related_name='docs') - @property - def cur_state(self): - s = self.get_state("draft-iesg") - return IDState().from_object(s) if s else None - - @property - def cur_state_id(self): - s = self.get_state("draft-iesg") - return s.order if s else None - - #prev_state = models.ForeignKey(IDState, db_column='prev_state', related_name='docs_prev') - @property - def prev_state(self): - ds = self.history_set.exclude(states=self.get_state("draft-iesg")).order_by('-time')[:1] - if ds: - s = ds[0].get_state("draft-iesg") - if s: - return IDState().from_object(s) if ds else None - return None - - #assigned_to = models.CharField(blank=True, max_length=25) # unused - - #mark_by = models.ForeignKey(IESGLogin, db_column='mark_by', related_name='marked') - @property - def mark_by(self): - e = self.latest_event() - from ietf.person.proxy import IESGLogin as IESGLoginProxy - return IESGLoginProxy().from_object(e.by) if e else None - - # job_owner = models.ForeignKey(IESGLogin, db_column='job_owner', related_name='documents') - @property - def job_owner(self): - from ietf.person.proxy import IESGLogin as IESGLoginProxy - return IESGLoginProxy().from_object(self.ad) if self.ad else None - - #event_date = models.DateField(null=True) - @property - def event_date(self): - e = self.latest_event() - return e.time if e else None - - #area_acronym = models.ForeignKey(Area) - @property - def area_acronym(self): - from ietf.group.proxy import Area - g = super(InternetDraft, self).group # be careful with group which is proxied - if g: - if g.type_id == "area": - return Area().from_object(g) - elif g.type_id != "individ": - return Area().from_object(g.parent) - else: - return None - - #cur_sub_state = BrokenForeignKey(IDSubState, related_name='docs', null=True, blank=True, null_values=(0, -1)) - @property - def cur_sub_state(self): - s = self.tags.filter(slug__in=['extpty', 'need-rev', 'ad-f-up', 'point']) - return IDSubState().from_object(s[0]) if s else None - @property - def cur_sub_state_id(self): - s = self.cur_sub_state - return s.order if s else None - - #prev_sub_state = BrokenForeignKey(IDSubState, related_name='docs_prev', null=True, blank=True, null_values=(0, -1)) - @property - def prev_sub_state(self): - ds = self.history_set.all().order_by('-time')[:1] - substates = ds[0].tags.filter(slug__in=['extpty', 'need-rev', 'ad-f-up', 'point']) if ds else None - return IDSubState().from_object(substates[0]) if substates else None - @property - def prev_sub_state_id(self): - s = self.prev_sub_state - return s.order if s else None - - #returning_item = models.IntegerField(null=True, blank=True) - @property - def returning_item(self): - e = self.latest_event(TelechatDocEvent, type="scheduled_for_telechat") - return e.returning_item if e else None - - #telechat_date = models.DateField(null=True, blank=True) - @property - def telechat_date(self): - e = self.latest_event(TelechatDocEvent, type="scheduled_for_telechat") - return e.telechat_date if e else None - - #via_rfc_editor = models.IntegerField(null=True, blank=True) - @property - def via_rfc_editor(self): - return self.stream_id in ('ise','irtf') - - #state_change_notice_to = models.CharField(blank=True, max_length=255) - @property - def state_change_notice_to(self): - return self.notify - - #dnp = models.IntegerField(null=True, blank=True) - @property - def dnp(self): - e = self.latest_event(type__in=("iesg_disapproved", "iesg_approved")) - return e != None and e.type == "iesg_disapproved" - - #dnp_date = models.DateField(null=True, blank=True) - @property - def dnp_date(self): - e = self.latest_event(type__in=("iesg_disapproved", "iesg_approved")) - return e.time.date() if e != None and e.type == "iesg_disapproved" else None - - #noproblem = models.IntegerField(null=True, blank=True) - @property - def noproblem(self): - e = self.latest_event(type__in=("iesg_disapproved", "iesg_approved")) - return e != None and e.type == "iesg_approved" - - #resurrect_requested_by = BrokenForeignKey(IESGLogin, db_column='resurrect_requested_by', related_name='docsresurrected', null=True, blank=True) - @property - def resurrect_requested_by(self): - e = self.latest_event(type__in=("requested_resurrect", "completed_resurrect")) - from ietf.person.proxy import IESGLogin as IESGLoginProxy - return IESGLoginProxy().from_object(e.by) if e and e.type == "requested_resurrect" else None - - #approved_in_minute = models.IntegerField(null=True, blank=True) - @property - def approved_in_minute(self): - return self.latest_event(type="approved_in_minute") - - - def get_absolute_url(self): - if self.rfc_flag and self.rfc_number: - return "/doc/rfc%d/" % self.rfc_number - else: - return "/doc/%s/" % self.name - - def document(self): - return self - - def comments(self): - return DocumentComment.objects.filter(doc=self).order_by('-time') - - def public_comments(self): - return self.comments() - - def ballot_set(self): - return [self] - def ballot_primary(self): - return [self] - def ballot_others(self): - return [] - def docstate(self): - s = self.get_state("draft-iesg") - if s: - subs = self.cur_sub_state - if subs: - return "%s::%s" % (s.name, subs) - return s.name - else: - return "I-D Exists" - - # things from BallotInfo - #active = models.BooleanField() - @property - def active(self): - # taken from BallotWrapper - s = self.get_state("draft-iesg") - return self.latest_event(type="sent_ballot_announcement") and s and s.name in ['In Last Call', 'Waiting for Writeup', 'Waiting for AD Go-Ahead', 'IESG Evaluation', 'IESG Evaluation - Defer'] and (self.get_state_slug() in ("rfc", "active")) - - #an_sent = models.BooleanField() - @property - def an_sent(self): - return bool(self.latest_event(type="iesg_approved")) - - #an_sent_date = models.DateField(null=True, blank=True) - @property - def an_sent_date(self): - e = self.latest_event(type="iesg_approved") - return e.time if e else None - - #an_sent_by = models.ForeignKey(IESGLogin, db_column='an_sent_by', related_name='ansent', null=True) - @property - def an_sent_by(self): - e = self.latest_event(type="iesg_approved") - from ietf.person.proxy import IESGLogin as IESGLoginProxy - return IESGLoginProxy().from_object(e.by) if e else None - - #defer = models.BooleanField() - @property - def defer(self): - # we're deferred if we're in the deferred state - return self.get_state_slug("draft-iesg") == "defer" - - #defer_by = models.ForeignKey(IESGLogin, db_column='defer_by', related_name='deferred', null=True) - @property - def defer_by(self): - e = self.latest_event(type="changed_document", desc__startswith="State changed to IESG Evaluation - Defer") - from ietf.person.proxy import IESGLogin as IESGLoginProxy - return IESGLoginProxy().from_object(e.by) if e else None - - #defer_date = models.DateField(null=True, blank=True) - @property - def defer_date(self): - e = self.latest_event(type="changed_document", desc__startswith="State changed to IESG Evaluation - Defer") - return e.time.date() if e else None - - #approval_text = models.TextField(blank=True) - @property - def approval_text(self): - e = self.latest_event(WriteupDocEvent, type="changed_ballot_approval_text") - return e.text if e else "" - - #last_call_text = models.TextField(blank=True) - @property - def last_call_text(self): - e = self.latest_event(WriteupDocEvent, type="changed_last_call_text") - return e.text if e else "" - - #ballot_writeup = models.TextField(blank=True) - @property - def ballot_writeup(self): - e = self.latest_event(WriteupDocEvent, type="changed_ballot_writeup_text") - return e.text if e else "" - - #ballot_issued = models.IntegerField(null=True, blank=True) - @property - def ballot_issued(self): - return bool(self.latest_event(type="sent_ballot_announcement")) - - # def remarks(self): # apparently not used - # remarks = list(self.discusses.all()) + list(self.comments.all()) - # return remarks - def active_positions(self): - """Returns a list of dicts, with AD and Position tuples""" - from ietf.person.proxy import IESGLogin as IESGLoginProxy - - res = [] - for ad, pos in self.active_ballot().active_ad_positions().iteritems(): - res.append(dict(ad=IESGLoginProxy().from_object(ad), pos=Position().from_object(pos) if pos else None)) - - res.sort(key=lambda x: x["ad"].last_name) - - return res - - def needed(self, standardsTrack=True): - """Returns text answering the question what does this document - need to pass?. The return value is only useful if the document - is currently in IESG evaluation.""" - tmp = self.active_positions() - positions = [x["pos"] for x in tmp if x["pos"]] - ads = [x["ad"] for x in tmp] - - yes = noobj = discuss = recuse = 0 - for position in positions: - p = position.pos_id - if p == "yes": - yes += 1 - if p == "noobj": - noobj += 1 - if p == "discuss": - discuss += 1 - if p == "recuse": - recuse += 1 - answer = '' - if yes < 1: - answer += "Needs a YES. " - if discuss > 0: - if discuss == 1: - answer += "Has a DISCUSS. " - else: - answer += "Has %d DISCUSSes. " % discuss - if standardsTrack: - # For standards-track, need positions from 2/3 of the - # non-recused current IESG. - needed = int(math.ceil((len(ads) - recuse) * 2.0/3.0)) - else: - # Info and experimental only need one position. - # Info and experimental without Yes have their full spec now. - if yes < 1: - return answer.rstrip() - else: - needed = 1 - have = yes + noobj - if have < needed: - more = needed - have - if more == 1: - answer += "Needs one more YES or NO OBJECTION position " - else: - answer += "Needs %d more YES or NO OBJECTION positions " % more - if discuss: - if discuss == 1: - answer += "once the DISCUSS is resolved." - else: - answer += "once %d DISCUSSes are resolved." % discuss - else: - answer += ". " - else: - answer += "Has enough positions to pass" - if discuss: - if discuss == 1: - answer += "once the DISCUSS is resolved" - else: - answer += "once %d DISCUSSes are resolved" % discuss - answer += ". " - - return answer.rstrip() - - - # things from RfcIndex - - #rfc_number = models.IntegerField(primary_key=True) # already taken care of - #title = models.CharField(max_length=250) # same name - #authors = models.CharField(max_length=250) # exists already - #rfc_published_date = models.DateField() - @property - def rfc_published_date(self): - if hasattr(self, 'published_rfc'): - e = self.published_rfc - else: - e = self.latest_event(type="published_rfc") - return e.time.date() if e else datetime.date(1990,1,1) - - #current_status = models.CharField(max_length=50,null=True) - @property - def current_status(self): - if self.std_level: - return self.std_level.name - else: - return u"(None)" - - #updates = models.CharField(max_length=200,blank=True,null=True) - @property - def updates(self): - return ",".join("RFC%s" % n for n in sorted(d.rfc_number for d in InternetDraft.objects.filter(docalias__relateddocument__source=self, docalias__relateddocument__relationship="updates"))) - - #updated_by = models.CharField(max_length=200,blank=True,null=True) - @property - def updated_by(self): - if not hasattr(self, "updated_by_list"): - self.updated_by_list = [d.rfc_number for d in InternetDraft.objects.filter(relateddocument__target__document=self, relateddocument__relationship="updates")] - return ",".join("RFC%s" % n for n in sorted(self.updated_by_list)) - - #obsoletes = models.CharField(max_length=200,blank=True,null=True) - @property - def obsoletes(self): - return ",".join("RFC%s" % n for n in sorted(d.rfc_number for d in InternetDraft.objects.filter(docalias__relateddocument__source=self, docalias__relateddocument__relationship="obs"))) - - #obsoleted_by = models.CharField(max_length=200,blank=True,null=True) - @property - def obsoleted_by(self): - if not hasattr(self, "obsoleted_by_list"): - self.obsoleted_by_list = [d.rfc_number for d in InternetDraft.objects.filter(relateddocument__target__document=self, relateddocument__relationship="obs")] - return ",".join("RFC%s" % n for n in sorted(self.obsoleted_by_list)) - - #also = models.CharField(max_length=50,blank=True,null=True) - @property - def also(self): - aliases = self.docalias_set.filter(models.Q(name__startswith="bcp") | - models.Q(name__startswith="std") | - models.Q(name__startswith="bcp")) - return aliases[0].name.upper() if aliases else None - - #draft = models.CharField(max_length=200,null=True) # have to ignore this, it's already implemented - - #has_errata = models.BooleanField() - @property - def has_errata(self): - return bool(self.tags.filter(slug="errata")) - - #stream = models.CharField(max_length=15,blank=True,null=True) - @property - def stream(self): - s = super(InternetDraft, self).stream - return s.name if s else None - - #wg = models.CharField(max_length=15,blank=True,null=True) - @property - def wg(self): - return self.group.acronym - - #file_formats = models.CharField(max_length=20,blank=True,null=True) - @property - def file_formats(self): - return self.get_file_type_matches_from(os.path.join(settings.RFC_PATH, "rfc" + str(self.rfc_number))).replace(".", "").replace("txt", "ascii") - - @property - def positions(self): - res = [] - found = set() - for pos in Position.objects.filter(doc=self, type="changed_ballot_position").select_related('ad').order_by("-time", "-id"): - if pos.ad not in found: - found.add(pos.ad) - res.append(pos) - - class Dummy: - def all(self): - return self.res - d = Dummy() - d.res = res - return d - - @property - def ipr(self): - from ietf.ipr.models import IprDraftProxy - return IprDraftProxy.objects.filter(doc_alias__document=self.pk) - - class Meta: - proxy = True - -IDInternal = InternetDraft -BallotInfo = InternetDraft -RfcIndex = InternetDraft -Rfc = InternetDraft - - -class IDAuthor(DocumentAuthor): - #document = models.ForeignKey(InternetDraft, db_column='id_document_tag', related_name='authors') # same name - #person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag') - @property - def person(self): - return self.author.person - - #author_order = models.IntegerField() - @property - def author_order(self): - return self.order - - def email(self): - return None if self.author.address.startswith("unknown-email") else self.author.address - - def final_author_order(self): - return self.order - - class Meta: - proxy = True - -class DocumentComment(DocEvent): - objects = TranslatingManager(dict(comment_text="desc", - date="time" - )) - - BALLOT_DISCUSS = 1 - BALLOT_COMMENT = 2 - BALLOT_CHOICES = ( - (BALLOT_DISCUSS, 'discuss'), - (BALLOT_COMMENT, 'comment'), - ) - #document = models.ForeignKey(IDInternal) - @property - def document(self): - return self.doc - #rfc_flag = models.IntegerField(null=True, blank=True) - #public_flag = models.BooleanField() #unused - #date = models.DateField(db_column='comment_date', default=datetime.date.today) - @property - def date(self): - return self.time.date() - #time = models.CharField(db_column='comment_time', max_length=20, default=lambda: datetime.datetime.now().strftime("%H:%M:%S")) - #version = models.CharField(blank=True, max_length=3) - @property - def version(self): - e = self.doc.latest_event(NewRevisionDocEvent, type="new_revision", time__lte=self.time) - return e.rev if e else "0" - #comment_text = models.TextField(blank=True) - @property - def comment_text(self): - return self.desc - #created_by = BrokenForeignKey(IESGLogin, db_column='created_by', null=True, null_values=(0, 999)) - #result_state = BrokenForeignKey(IDState, db_column='result_state', null=True, related_name="comments_leading_to_state", null_values=(0, 99)) - #origin_state = models.ForeignKey(IDState, db_column='origin_state', null=True, related_name="comments_coming_from_state") - #ballot = models.IntegerField(null=True, choices=BALLOT_CHOICES) - def get_absolute_url(self): - return "/doc/%s/" % self.doc.name - def get_author(self): - return self.by.plain_name() - def get_username(self): - return unicode(self.by) - def get_fullname(self): - return self.by.plain_name() - def datetime(self): - return self.time - def doc_id(self): - return self.doc_id - def doc_name(self): - return self.doc.name - def __str__(self): - return "\"%s...\" by %s" % (self.comment_text[:20], self.get_author()) - - class Meta: - proxy = True - - -class Position(BallotPositionDocEvent): - def from_object(self, base): - for f in base._meta.fields: - if not f.name in ('discuss', 'ad', 'ballot', ): # don't overwrite properties - setattr(self, f.name, getattr(base, f.name)) - - self.orig = base - return self - - #ballot = models.ForeignKey(BallotInfo, related_name='positions') - @property - def ballot(self): - return self.doc # FIXME: doesn't emulate old interface - - # ad = models.ForeignKey(IESGLogin) # same name - @property - def ad(self): - from ietf.person.proxy import IESGLogin - return IESGLogin().from_object(self.orig.ad if hasattr(self, "orig") else super(Position, self).ad) - - #yes = models.IntegerField(db_column='yes_col') - @property - def yes(self): - return self.pos_id == "yes" - #noobj = models.IntegerField(db_column='no_col') - @property - def noobj(self): - return self.pos_id == "noobj" - #abstain = models.IntegerField() - @property - def abstain(self): - return self.pos_id == "abstain" - #approve = models.IntegerField(default=0) # unused - #discuss = models.IntegerField() - # needs special treatment because of clash with attribute on base class - def get_discuss(self): - return self.pos_id == "discuss" - def set_discuss(self, x): - pass - discuss = property(get_discuss, set_discuss) - #recuse = models.IntegerField() - @property - def recuse(self): - return self.pos_id == "recuse" - def __str__(self): - return "Position for %s on %s" % ( self.ad, self.ballot ) - def abstain_ind(self): - if self.recuse: - return 'R' - if self.abstain: - return 'X' - else: - return ' ' - def name(self): - return self.pos.name if self.pos else "No Record" - - class Meta: - proxy = True - -class DraftLikeDocAlias(DocAlias): - # this class is mostly useful for the IPR part - - def __str__(self): - return str(unicode(self)) - - def __unicode__(self): - if self.name.startswith("rfc"): - return "RFC%04d" % int(self.name[3:]) - else: - return self.name - - @property - def id_document_tag(self): - return self.name - - @property - def title(self): - return self.document.title - - @property - def filename(self): - return self.name - - @property - def ipr(self): - from ietf.ipr.models import IprDraftProxy - return IprDraftProxy.objects.filter(doc_alias=self.pk) - - class Meta: - proxy = True - -class ObjectHistoryEntryProxy(DocEvent): - #date = models.DateTimeField(_('Date'), auto_now_add=True) - @property - def date(self): - return self.time - #comment = models.TextField(_('Comment')) - @property - def comment(self): - return "" - #person = models.ForeignKey(PersonOrOrgInfo) - @property - def person(self): - return self.by - - def get_real_instance(self): - return self - - def describe_change(self): - return u"

%s

" % self.desc - - class Meta: - proxy = True - -class IDStatus(State): - def from_object(self, base): - for f in base._meta.fields: - setattr(self, f.name, getattr(base, f.name)) - return self - - #status_id = models.AutoField(primary_key=True) - - #status = models.CharField(max_length=25, db_column='status_value') - @property - def status(self): - return self.name - - def __unicode__(self): - return super(self.__class__, self).__unicode__() - - class Meta: - proxy = True - -class IDState(State): - PUBLICATION_REQUESTED = 10 - LAST_CALL_REQUESTED = 15 - IN_LAST_CALL = 16 - WAITING_FOR_WRITEUP = 18 - WAITING_FOR_AD_GO_AHEAD = 19 - IESG_EVALUATION = 20 - IESG_EVALUATION_DEFER = 21 - APPROVED_ANNOUNCEMENT_SENT = 30 - AD_WATCHING = 42 - DEAD = 99 - DO_NOT_PUBLISH_STATES = (33, 34) - - objects = TranslatingManager(dict(pk=lambda v: ("order", v, "type", "draft-iesg"), - document_state_id=lambda v: ("order", v, "type", "draft-iesg"), - document_state_id__in=lambda v: ("order__in", v, "type", "draft-iesg")), - always_filter=dict(type="draft-iesg")) - - def from_object(self, base): - for f in base._meta.fields: - setattr(self, f.name, getattr(base, f.name)) - return self - - #document_state_id = models.AutoField(primary_key=True) - @property - def document_state_id(self): - return self.order - - #state = models.CharField(max_length=50, db_column='document_state_val') - @property - def state(self): - return self.name - - #equiv_group_flag = models.IntegerField(null=True, blank=True) # unused - #description = models.TextField(blank=True, db_column='document_desc') - @property - def description(self): - return self.desc - - @property - def nextstate(self): - # simulate related queryset - return IDState.objects.filter(pk__in=[x.pk for x in self.next_states.all()]) - - @property - def next_state(self): - # simulate IDNextState - return self - - def __str__(self): - return self.state - - @staticmethod - def choices(): - return [(state.pk, state.name) for state in IDState.objects.all()] - - class Meta: - proxy = True - - diff --git a/ietf/doc/templatetags/ballot_icon.py b/ietf/doc/templatetags/ballot_icon.py index 3604beaa8..18ca432cb 100644 --- a/ietf/doc/templatetags/ballot_icon.py +++ b/ietf/doc/templatetags/ballot_icon.py @@ -40,31 +40,35 @@ from django.utils.safestring import mark_safe from ietf.ietfauth.utils import user_is_person, has_role from ietf.doc.models import BallotDocEvent, BallotPositionDocEvent, IESG_BALLOT_ACTIVE_STATES, IESG_SUBSTATE_TAGS +from ietf.name.models import BallotPositionName register = template.Library() -def render_ballot_icon(user, doc): +@register.filter +def showballoticon(doc): + if doc.type_id == "draft": + if doc.get_state_slug("draft-iesg") not in IESG_BALLOT_ACTIVE_STATES: + return False + elif doc.type_id == "charter": + if doc.get_state_slug() not in ("intrev", "iesgrev"): + return False + elif doc.type_id == "conflrev": + if doc.get_state_slug() not in ("iesgeval","defer"): + return False + elif doc.type_id == "statchg": + if doc.get_state_slug() not in ("iesgeval","defer"): + return False + + return True + + +def render_ballot_icon(doc, user): if not doc: return "" - # FIXME: temporary backwards-compatibility hack - from ietf.doc.models import Document - if not isinstance(doc, Document): - doc = doc._draft - - if doc.type_id == "draft": - if doc.get_state_slug("draft-iesg") not in IESG_BALLOT_ACTIVE_STATES: - return "" - elif doc.type_id == "charter": - if doc.get_state_slug() not in ("intrev", "iesgrev"): - return "" - elif doc.type_id == "conflrev": - if doc.get_state_slug() not in ("iesgeval","defer"): - return "" - elif doc.type_id == "statchg": - if doc.get_state_slug() not in ("iesgeval","defer"): - return "" + if not showballoticon(doc): + return "" ballot = doc.active_ballot() if not ballot: @@ -119,7 +123,7 @@ class BallotIconNode(template.Node): self.doc_var = doc_var def render(self, context): doc = template.resolve_variable(self.doc_var, context) - return render_ballot_icon(context.get("user"), doc) + return render_ballot_icon(doc, context.get("user")) def do_ballot_icon(parser, token): try: @@ -132,29 +136,24 @@ register.tag('ballot_icon', do_ballot_icon) @register.filter -def my_position(doc, user): - if not has_role(user, "Area Director"): +def ballotposition(doc, user): + if not showballoticon(doc) or not has_role(user, "Area Director"): return None - # FIXME: temporary backwards-compatibility hack - from ietf.doc.models import Document - if not isinstance(doc, Document): - doc = doc._draft ballot = doc.active_ballot() - pos = "No Record" - if ballot: - changed_pos = doc.latest_event(BallotPositionDocEvent, type="changed_ballot_position", ad__user=user, ballot=ballot) - if changed_pos: - pos = changed_pos.pos.name; + if not ballot: + return None + + changed_pos = doc.latest_event(BallotPositionDocEvent, type="changed_ballot_position", ad__user=user, ballot=ballot) + if changed_pos: + pos = changed_pos.pos + else: + pos = BallotPositionName.objects.get(slug="norecord") return pos -@register.filter() -def state_age_colored(doc): - # FIXME: temporary backwards-compatibility hack - from ietf.doc.models import Document - if not isinstance(doc, Document): - doc = doc._draft +@register.filter +def state_age_colored(doc): if doc.type_id == 'draft': if not doc.get_state_slug() in ["active", "rfc"]: # Don't show anything for expired/withdrawn/replaced drafts @@ -174,7 +173,6 @@ def state_age_colored(doc): Q(desc__istartswith="State Changes to ")| Q(desc__istartswith="Sub state has been changed to ")| Q(desc__istartswith="State has been changed to ")| - Q(desc__istartswith="IESG has approved and state has been changed to")| Q(desc__istartswith="IESG process started in state") ).order_by('-time')[0].time.date() except IndexError: diff --git a/ietf/doc/templatetags/ietf_filters.py b/ietf/doc/templatetags/ietf_filters.py index 1b9b8b493..b27df3580 100644 --- a/ietf/doc/templatetags/ietf_filters.py +++ b/ietf/doc/templatetags/ietf_filters.py @@ -9,14 +9,13 @@ from django.template.defaultfilters import linebreaksbr, wordwrap, stringfilter, from django.template import resolve_variable from django.utils.safestring import mark_safe, SafeData from django.utils import simplejson -try: - from email import utils as emailutils -except ImportError: - from email import Utils as emailutils +from django.utils.html import strip_tags +from django.template import RequestContext + +from email.utils import parseaddr import re import datetime import types -from django.template import RequestContext register = template.Library() @@ -73,14 +72,23 @@ def parse_email_list(value): addrs = re.split(", ?", value) ret = [] for addr in addrs: - (name, email) = emailutils.parseaddr(addr) + (name, email) = parseaddr(addr) if not(name): name = email ret.append('%s' % ( fix_ampersands(email), escape(name) )) - return ", ".join(ret) + return mark_safe(", ".join(ret)) else: return value - + +@register.filter +def strip_email(value): + """Get rid of email part of name/email string like 'Some Name '.""" + if not value: + return "" + if "@" not in value: + return value + return parseaddr(value)[0] + @register.filter(name='fix_angle_quotes') def fix_angle_quotes(value): if "<" in value: @@ -92,7 +100,7 @@ def fix_angle_quotes(value): @register.filter(name='make_one_per_line') def make_one_per_line(value): """ - Turn a comma-separated list into a carraige-return-seperated list. + Turn a comma-separated list into a carriage-return-seperated list. >>> make_one_per_line("a, b, c") 'a\\nb\\nc' @@ -276,6 +284,10 @@ def truncate_ellipsis(text, arg): else: return escape(text) +@register.filter +def split(text, splitter=None): + return text.split(splitter) + @register.filter(name="wrap_long_lines") def wrap_long_lines(text): """Wraps long lines without loosing the formatting and indentation @@ -405,25 +417,13 @@ def expires_soon(x,request): days = 14 return x > -days -@register.filter(name='equal') -def equal(x, y): - return str(x)==str(y) - @register.filter(name='startswith') def startswith(x, y): return unicode(x).startswith(y) -# based on http://www.djangosnippets.org/snippets/847/ by 'whiteinge' -@register.filter -def in_group(user, groups): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - return has_role(user, groups.replace("Area_Director", "Area Director")) - - return user and user.is_authenticated() and bool(user.groups.filter(name__in=groups.split(',')).values('name')) - @register.filter def has_role(user, role_names): - from ietf.ietfauth.decorators import has_role + from ietf.ietfauth.utils import has_role if not user: return False return has_role(user, role_names.split(',')) @@ -475,6 +475,18 @@ def state(doc, slug): slug = "%s-stream-%s" % (doc.type_id, doc.stream_id) return doc.get_state(slug) +@register.filter +def statehelp(state): + "Output help icon with tooltip for state." + from django.core.urlresolvers import reverse as urlreverse + tooltip = escape(strip_tags(state.desc)) + url = urlreverse("state_help", kwargs=dict(type=state.type_id)) + "#" + state.slug + return mark_safe('?' % (url, tooltip)) + +@register.filter +def sectionlevel(section_number): + return section_number.count(".") + 1 + def _test(): import doctest doctest.testmod() @@ -483,13 +495,13 @@ if __name__ == "__main__": _test() @register.filter -def plural(text, list, arg=u's'): +def plural(text, seq, arg=u's'): "Similar to pluralize, but looks at the text, too" from django.template.defaultfilters import pluralize if text.endswith('s'): return text else: - return text + pluralize(len(list), arg) + return text + pluralize(len(seq), arg) @register.filter def ics_esc(text): diff --git a/ietf/doc/templatetags/streams_menu.py b/ietf/doc/templatetags/streams_menu.py new file mode 100644 index 000000000..82f62620e --- /dev/null +++ b/ietf/doc/templatetags/streams_menu.py @@ -0,0 +1,32 @@ +from django import template +from django.conf import settings +from django.core.urlresolvers import reverse as urlreverse +from django.contrib.auth.models import AnonymousUser + +from ietf.ietfauth.utils import has_role +from ietf.group.models import Group +from ietf.name.models import StreamName + +register = template.Library() + +@register.inclusion_tag('base/streams_menu.html', takes_context=True) +def streams_menu(context): + editable_streams = [] + + user = context["request"].user if "request" in context else AnonymousUser() + + if user.is_authenticated(): + streams = StreamName.objects.exclude(slug="legacy") + + if has_role(user, "Secretariat"): + editable_streams.extend(streams) + else: + acronyms = Group.objects.filter(acronym__in=(s.slug for s in streams), + role__name="chair", + role__person__user=user).distinct().values_list("acronym", flat=True) + + for s in streams: + if s.slug in acronyms: + editable_streams.append(s) + + return { 'editable_streams': editable_streams } diff --git a/ietf/doc/templatetags/wg_menu.py b/ietf/doc/templatetags/wg_menu.py index 4f58eb6c1..079757734 100644 --- a/ietf/doc/templatetags/wg_menu.py +++ b/ietf/doc/templatetags/wg_menu.py @@ -61,7 +61,7 @@ class WgMenuNode(template.Node): areas = [a for a in areas if a.active_groups] - res = loader.render_to_string('base_wgmenu.html', {'areas':areas}) + res = loader.render_to_string('base/wg_menu.html', {'areas':areas}) cache.set('base_left_wgmenu', x, 30*60) return res diff --git a/ietf/doc/tests.py b/ietf/doc/tests.py index 7873da9fb..9126c3e06 100644 --- a/ietf/doc/tests.py +++ b/ietf/doc/tests.py @@ -24,9 +24,6 @@ from ietf.doc.tests_status_change import * class SearchTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] - def test_search(self): draft = make_test_data() @@ -127,9 +124,6 @@ class SearchTestCase(TestCase): class DocTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] - def test_document_draft(self): draft = make_test_data() @@ -251,9 +245,6 @@ class DocTestCase(TestCase): class AddCommentTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] - def test_add_comment(self): draft = make_test_data() url = urlreverse('doc_add_comment', kwargs=dict(name=draft.name)) diff --git a/ietf/doc/tests_ballot.py b/ietf/doc/tests_ballot.py index a4ed02c63..d39212cc7 100644 --- a/ietf/doc/tests_ballot.py +++ b/ietf/doc/tests_ballot.py @@ -20,10 +20,7 @@ from ietf.utils.test_data import make_test_data from ietf.utils.mail import outbox from ietf.utils import TestCase -class EditPositionTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] - +class EditPositionTests(TestCase): def test_edit_position(self): draft = make_test_data() url = urlreverse('ietf.doc.views_ballot.edit_position', kwargs=dict(name=draft.name, @@ -170,10 +167,7 @@ class EditPositionTestCase(TestCase): self.assertTrue("Test!" in str(m)) -class DeferBallotTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] - +class DeferBallotTests(TestCase): def test_defer_ballot(self): draft = make_test_data() draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="iesg-eva")) @@ -217,10 +211,8 @@ class DeferBallotTestCase(TestCase): draft = Document.objects.get(name=draft.name) self.assertEquals(draft.get_state_slug("draft-iesg"), "iesg-eva") -class BallotWriteupsTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] +class BallotWriteupsTests(TestCase): def test_edit_last_call_text(self): draft = make_test_data() url = urlreverse('doc_ballot_lastcall', kwargs=dict(name=draft.name)) @@ -409,10 +401,8 @@ class BallotWriteupsTestCase(TestCase): draft = Document.objects.get(name=draft.name) self.assertTrue("Subject: Results of IETF-conflict review" in draft.latest_event(WriteupDocEvent, type="changed_ballot_approval_text").text) -class ApproveBallotTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] +class ApproveBallotTests(TestCase): def test_approve_ballot(self): draft = make_test_data() draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="iesg-eva")) # make sure it's approvable @@ -460,10 +450,8 @@ class ApproveBallotTestCase(TestCase): self.assertEquals(len(outbox), mailbox_before + 3) self.assertTrue("NOT be published" in str(outbox[-1])) -class MakeLastCallTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] +class MakeLastCallTests(TestCase): def test_make_last_call(self): draft = make_test_data() draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="lc-req")) diff --git a/ietf/doc/tests_conflict_review.py b/ietf/doc/tests_conflict_review.py index a61b2b752..7f9acf0e8 100644 --- a/ietf/doc/tests_conflict_review.py +++ b/ietf/doc/tests_conflict_review.py @@ -22,10 +22,7 @@ from ietf.group.models import Person from ietf.iesg.models import TelechatDate -class ConflictReviewTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] - +class ConflictReviewTests(TestCase): def test_start_review(self): doc = Document.objects.get(name='draft-imaginary-independent-submission') @@ -254,10 +251,7 @@ class ConflictReviewTestCase(TestCase): make_test_data() -class ConflictReviewSubmitTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names',] - +class ConflictReviewSubmitTests(TestCase): def test_initial_submission(self): doc = Document.objects.get(name='conflict-review-imaginary-irtf-submission') url = urlreverse('conflict_review_submit',kwargs=dict(name=doc.name)) diff --git a/ietf/doc/tests_draft.py b/ietf/doc/tests_draft.py index 28e5f1e27..dc35b1a32 100644 --- a/ietf/doc/tests_draft.py +++ b/ietf/doc/tests_draft.py @@ -1,7 +1,5 @@ -import unittest import StringIO -import os, shutil -from datetime import date, timedelta, time +import os, shutil, datetime from django.core.urlresolvers import reverse as urlreverse from django.conf import settings @@ -10,6 +8,7 @@ from pyquery import PyQuery import debug from ietf.doc.models import * +from ietf.doc.utils import * from ietf.name.models import * from ietf.group.models import * from ietf.person.models import * @@ -21,10 +20,7 @@ from ietf.utils.mail import outbox from ietf.utils import TestCase -class ChangeStateTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] - +class ChangeStateTests(TestCase): def test_change_state(self): draft = make_test_data() draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="ad-eval")) @@ -178,10 +174,7 @@ class ChangeStateTestCase(TestCase): self.assertTrue("Last call was requested" in draft.latest_event().desc) -class EditInfoTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] - +class EditInfoTests(TestCase): def test_edit_info(self): draft = make_test_data() url = urlreverse('doc_edit_info', kwargs=dict(name=draft.name)) @@ -361,10 +354,7 @@ class EditInfoTestCase(TestCase): self.assertEqual(draft.latest_event(ConsensusDocEvent, type="changed_consensus").consensus, True) -class ResurrectTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] - +class ResurrectTests(TestCase): def test_request_resurrect(self): draft = make_test_data() draft.set_state(State.objects.get(used=True, type="draft", slug="expired")) @@ -429,10 +419,7 @@ class ResurrectTestCase(TestCase): self.assertEquals(len(outbox), mailbox_before + 1) -class ExpireIDsTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] - +class ExpireIDsTests(TestCase): def setUp(self): self.id_dir = os.path.abspath("tmp-id-dir") self.archive_dir = os.path.abspath("tmp-id-archive") @@ -459,15 +446,15 @@ class ExpireIDsTestCase(TestCase): Meeting.objects.create(number="123", type=MeetingTypeName.objects.get(slug="ietf"), - date=date.today()) + date=datetime.date.today()) second_cut_off = Meeting.get_second_cut_off() ietf_monday = Meeting.get_ietf_monday() - self.assertTrue(not in_draft_expire_freeze(datetime.datetime.combine(second_cut_off - datetime.timedelta(days=7), time(0, 0, 0)))) - self.assertTrue(not in_draft_expire_freeze(datetime.datetime.combine(second_cut_off, time(0, 0, 0)))) - self.assertTrue(in_draft_expire_freeze(datetime.datetime.combine(second_cut_off + datetime.timedelta(days=7), time(0, 0, 0)))) - self.assertTrue(in_draft_expire_freeze(datetime.datetime.combine(ietf_monday - datetime.timedelta(days=1), time(0, 0, 0)))) - self.assertTrue(not in_draft_expire_freeze(datetime.datetime.combine(ietf_monday, time(0, 0, 0)))) + self.assertTrue(not in_draft_expire_freeze(datetime.datetime.combine(second_cut_off - datetime.timedelta(days=7), datetime.time(0, 0, 0)))) + self.assertTrue(not in_draft_expire_freeze(datetime.datetime.combine(second_cut_off, datetime.time(0, 0, 0)))) + self.assertTrue(in_draft_expire_freeze(datetime.datetime.combine(second_cut_off + datetime.timedelta(days=7), datetime.time(0, 0, 0)))) + self.assertTrue(in_draft_expire_freeze(datetime.datetime.combine(ietf_monday - datetime.timedelta(days=1), datetime.time(0, 0, 0)))) + self.assertTrue(not in_draft_expire_freeze(datetime.datetime.combine(ietf_monday, datetime.time(0, 0, 0)))) def test_warn_expirable_drafts(self): from ietf.doc.expire import get_soon_to_expire_drafts, send_expire_warning_for_draft @@ -612,10 +599,8 @@ class ExpireIDsTestCase(TestCase): self.assertTrue(not os.path.exists(os.path.join(self.id_dir, txt))) self.assertTrue(os.path.exists(os.path.join(self.archive_dir, "deleted_tombstones", txt))) -class ExpireLastCallTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] +class ExpireLastCallTests(TestCase): def test_expire_last_call(self): from ietf.doc.lastcall import get_expired_last_calls, expire_last_call @@ -662,10 +647,8 @@ class ExpireLastCallTestCase(TestCase): self.assertEquals(len(outbox), mailbox_before + 1) self.assertTrue("Last Call Expired" in outbox[-1]["Subject"]) -class IndividualInfoFormsTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] +class IndividualInfoFormsTests(TestCase): def test_doc_change_stream(self): url = urlreverse('doc_change_stream', kwargs=dict(name=self.docname)) login_testing_unauthorized(self, "secretary", url) @@ -890,10 +873,8 @@ class IndividualInfoFormsTestCase(TestCase): self.docname='draft-ietf-mars-test' self.doc = Document.objects.get(name=self.docname) -class SubmitToIesgTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] +class SubmitToIesgTests(TestCase): def verify_permissions(self): def verify_fail(remote_user): @@ -951,10 +932,8 @@ class SubmitToIesgTestCase(TestCase): self.doc = Document.objects.get(name=self.docname) self.doc.unset_state('draft-iesg') -class RequestPublicationTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] +class RequestPublicationTests(TestCase): def test_request_publication(self): draft = make_test_data() draft.stream = StreamName.objects.get(slug="iab") @@ -990,3 +969,123 @@ class RequestPublicationTestCase(TestCase): # the IANA copy self.assertTrue("Document Action" in outbox[-1]['Subject']) self.assertTrue(not outbox[-1]['CC']) + +class AdoptDraftTests(TestCase): + def test_adopt_document(self): + draft = make_test_data() + draft.stream = None + draft.group = Group.objects.get(type="individ") + draft.save() + draft.unset_state("draft-stream-ietf") + + url = urlreverse('doc_adopt_draft', kwargs=dict(name=draft.name)) + login_testing_unauthorized(self, "marschairman", url) + + # get + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + self.assertEqual(len(q('form select[name="group"] option')), 1) # we can only select "mars" + + # adopt in mars WG + mailbox_before = len(outbox) + events_before = draft.docevent_set.count() + r = self.client.post(url, + dict(comment="some comment", + group=Group.objects.get(acronym="mars").pk, + weeks="10")) + self.assertEqual(r.status_code, 302) + + draft = Document.objects.get(pk=draft.pk) + self.assertEqual(draft.group.acronym, "mars") + self.assertEqual(draft.stream_id, "ietf") + self.assertEqual(draft.docevent_set.count() - events_before, 4) + self.assertEqual(len(outbox), mailbox_before + 1) + self.assertTrue("adopted" in outbox[-1]["Subject"].lower()) + self.assertTrue("wgchairman@ietf.org" in unicode(outbox[-1])) + self.assertTrue("wgdelegate@ietf.org" in unicode(outbox[-1])) + +class ChangeStreamStateTests(TestCase): + def test_set_tags(self): + draft = make_test_data() + draft.tags = DocTagName.objects.filter(slug="w-expert") + draft.group.unused_tags.add("w-refdoc") + + url = urlreverse('doc_change_stream_state', kwargs=dict(name=draft.name, state_type="draft-stream-ietf")) + login_testing_unauthorized(self, "marschairman", url) + + # get + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + # make sure the unused tags are hidden + unused = draft.group.unused_tags.values_list("slug", flat=True) + for t in q("input[name=tags]"): + self.assertTrue(t.attrib["value"] not in unused) + + # set tags + mailbox_before = len(outbox) + events_before = draft.docevent_set.count() + r = self.client.post(url, + dict(new_state=draft.get_state("draft-stream-%s" % draft.stream_id).pk, + comment="some comment", + weeks="10", + tags=["need-aut", "sheph-u"], + )) + self.assertEqual(r.status_code, 302) + + draft = Document.objects.get(pk=draft.pk) + self.assertEqual(draft.tags.count(), 2) + self.assertEqual(draft.tags.filter(slug="w-expert").count(), 0) + self.assertEqual(draft.tags.filter(slug="need-aut").count(), 1) + self.assertEqual(draft.tags.filter(slug="sheph-u").count(), 1) + self.assertEqual(draft.docevent_set.count() - events_before, 2) + self.assertEqual(len(outbox), mailbox_before + 1) + self.assertTrue("tags changed" in outbox[-1]["Subject"].lower()) + self.assertTrue("wgchairman@ietf.org" in unicode(outbox[-1])) + self.assertTrue("wgdelegate@ietf.org" in unicode(outbox[-1])) + self.assertTrue("plain@example.com" in unicode(outbox[-1])) + + def test_set_state(self): + draft = make_test_data() + + url = urlreverse('doc_change_stream_state', kwargs=dict(name=draft.name, state_type="draft-stream-ietf")) + login_testing_unauthorized(self, "marschairman", url) + + # get + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + # make sure the unused states are hidden + unused = draft.group.unused_states.values_list("pk", flat=True) + for t in q("select[name=new_state]").find("option[name=tags]"): + self.assertTrue(t.attrib["value"] not in unused) + self.assertEqual(len(q('select[name=new_state]')), 1) + + # set new state + old_state = draft.get_state("draft-stream-%s" % draft.stream_id ) + new_state = State.objects.get(used=True, type="draft-stream-%s" % draft.stream_id, slug="parked") + self.assertNotEqual(old_state, new_state) + mailbox_before = len(outbox) + events_before = draft.docevent_set.count() + + r = self.client.post(url, + dict(new_state=new_state.pk, + comment="some comment", + weeks="10", + tags=[t.pk for t in draft.tags.filter(slug__in=get_tags_for_stream_id(draft.stream_id))], + )) + self.assertEqual(r.status_code, 302) + + draft = Document.objects.get(pk=draft.pk) + self.assertEqual(draft.get_state("draft-stream-%s" % draft.stream_id), new_state) + self.assertEqual(draft.docevent_set.count() - events_before, 2) + reminder = DocReminder.objects.filter(event__doc=draft, type="stream-s") + self.assertEqual(len(reminder), 1) + due = datetime.datetime.now() + datetime.timedelta(weeks=10) + self.assertTrue(due - datetime.timedelta(days=1) <= reminder[0].due <= due + datetime.timedelta(days=1)) + self.assertEqual(len(outbox), mailbox_before + 1) + self.assertTrue("state changed" in outbox[-1]["Subject"].lower()) + self.assertTrue("wgchairman@ietf.org" in unicode(outbox[-1])) + self.assertTrue("wgdelegate@ietf.org" in unicode(outbox[-1])) + diff --git a/ietf/doc/tests_status_change.py b/ietf/doc/tests_status_change.py index b3f4d23d4..36666440d 100644 --- a/ietf/doc/tests_status_change.py +++ b/ietf/doc/tests_status_change.py @@ -22,10 +22,7 @@ from ietf.group.models import Person from ietf.iesg.models import TelechatDate -class StatusChangeTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] - +class StatusChangeTests(TestCase): def test_start_review(self): url = urlreverse('start_rfc_status_change',kwargs=dict(name="")) @@ -353,10 +350,7 @@ class StatusChangeTestCase(TestCase): make_test_data() -class StatusChangeSubmitTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] - +class StatusChangeSubmitTests(TestCase): def test_initial_submission(self): doc = Document.objects.get(name='status-change-imaginary-mid-review') url = urlreverse('status_change_submit',kwargs=dict(name=doc.name)) diff --git a/ietf/doc/urls.py b/ietf/doc/urls.py index e49bc94b5..0bd6e14d0 100644 --- a/ietf/doc/urls.py +++ b/ietf/doc/urls.py @@ -68,7 +68,6 @@ urlpatterns += patterns('', url(r'^(?P[A-Za-z0-9._+-]+)/ballot/$', views_doc.document_ballot, name="doc_ballot"), (r'^(?P[A-Za-z0-9._+-]+)/doc.json$', views_doc.document_json), (r'^(?P[A-Za-z0-9._+-]+)/ballotpopup/(?P[0-9]+)/$', views_doc.ballot_popup), - #(r'^(?P[A-Za-z0-9._+-]+)/ballot.json$', views_doc.ballot_json), # legacy view url(r'^(?P[A-Za-z0-9._+-]+)/edit/state/$', views_draft.change_state, name='doc_change_state'), # IESG state url(r'^(?P[A-Za-z0-9._+-]+)/edit/state/(?Piana-action|iana-review)/$', views_draft.change_iana_state, name='doc_change_iana_state'), @@ -90,6 +89,8 @@ urlpatterns += patterns('', url(r'^(?P[A-Za-z0-9._+-]+)/edit/shepherd/$', views_draft.edit_shepherd, name='doc_edit_shepherd'), url(r'^(?P[A-Za-z0-9._+-]+)/edit/shepherdwriteup/$', views_draft.edit_shepherd_writeup, name='doc_edit_shepherd_writeup'), url(r'^(?P[A-Za-z0-9._+-]+)/edit/requestpublication/$', views_draft.request_publication, name='doc_request_publication'), + url(r'^(?P[A-Za-z0-9._+-]+)/edit/adopt/$', views_draft.adopt_draft, name='doc_adopt_draft'), + url(r'^(?P[A-Za-z0-9._+-]+)/edit/state/(?Pdraft-stream-[a-z]+)/$', views_draft.change_stream_state, name='doc_change_stream_state'), url(r'^(?P[A-Za-z0-9._+-]+)/edit/clearballot/$', views_ballot.clear_ballot, name='doc_clear_ballot'), url(r'^(?P[A-Za-z0-9._+-]+)/edit/deferballot/$', views_ballot.defer_ballot, name='doc_defer_ballot'), diff --git a/ietf/doc/utils.py b/ietf/doc/utils.py index b211e767d..52b815207 100644 --- a/ietf/doc/utils.py +++ b/ietf/doc/utils.py @@ -5,6 +5,8 @@ from django.conf import settings from ietf.utils import markup_txt from ietf.doc.models import * +from ietf.group.models import Role +from ietf.ietfauth.utils import has_role from ietf.utils import draft @@ -39,6 +41,20 @@ def get_tags_for_stream_id(stream_id): else: return [] +def can_adopt_draft(user, doc): + if not user.is_authenticated(): + return False + + if has_role(user, "Secretariat"): + return True + + return (doc.stream_id in (None, "ietf", "irtf") + and doc.group.type_id == "individ" + and Role.objects.filter(name__in=("chair", "delegate", "secr"), + group__type__in=("wg", "rg"), + group__state="active", + person__user=user).exists()) + def needed_ballot_positions(doc, active_positions): '''Returns text answering the question "what does this document need to pass?". The return value is only useful if the document @@ -227,7 +243,30 @@ def add_state_change_event(doc, by, prev_state, new_state, timestamp=None): e.time = timestamp e.save() return e - + +def update_reminder(doc, reminder_type_slug, event, due_date): + reminder_type = DocReminderTypeName.objects.get(slug=reminder_type_slug) + + try: + reminder = DocReminder.objects.get(event__doc=doc, type=reminder_type, active=True) + except DocReminder.DoesNotExist: + reminder = None + + if due_date: + # activate/update reminder + if not reminder: + reminder = DocReminder(type=reminder_type) + + reminder.event = event + reminder.due = due_date + reminder.active = True + reminder.save() + else: + # deactivate reminder + if reminder: + reminder.active = False + reminder.save() + def prettify_std_name(n): if re.match(r"(rfc|bcp|fyi|std)[0-9]+", n): return n[:3].upper() + " " + n[3:] diff --git a/ietf/doc/views_ballot.py b/ietf/doc/views_ballot.py index b33426008..e24e8aa07 100644 --- a/ietf/doc/views_ballot.py +++ b/ietf/doc/views_ballot.py @@ -16,7 +16,7 @@ from django.conf import settings import debug from ietf.utils.mail import send_mail_text, send_mail_preformatted -from ietf.ietfauth.decorators import has_role, role_required +from ietf.ietfauth.utils import has_role, role_required from ietf.iesg.models import TelechatDate from ietf.ipr.models import IprDetail from ietf.ipr.search import iprs_from_docs @@ -693,7 +693,7 @@ def approve_ballot(request, name): e = DocEvent(doc=doc, by=login) if action == "do_not_publish": e.type = "iesg_disapproved" - e.desc = "Do Not Publish note has been sent to RFC Editor" + e.desc = "Do Not Publish note has been sent to the RFC Editor" else: e.type = "iesg_approved" e.desc = "IESG has approved the document" diff --git a/ietf/doc/views_conflict_review.py b/ietf/doc/views_conflict_review.py index dfc66ddd8..d4222d97d 100644 --- a/ietf/doc/views_conflict_review.py +++ b/ietf/doc/views_conflict_review.py @@ -12,7 +12,7 @@ from ietf.doc.utils import log_state_changed, update_telechat from ietf.doc.models import save_document_in_history from ietf.doc.utils import create_ballot_if_not_open, close_open_ballots, get_document_content -from ietf.ietfauth.decorators import has_role, role_required +from ietf.ietfauth.utils import has_role, role_required from ietf.utils.textupload import get_cleaned_text_file_content from ietf.utils.mail import send_mail_preformatted from ietf.doc.mails import email_iana diff --git a/ietf/doc/views_doc.py b/ietf/doc/views_doc.py index 07f95a546..2e884bfbb 100644 --- a/ietf/doc/views_doc.py +++ b/ietf/doc/views_doc.py @@ -61,12 +61,10 @@ def render_document_top(request, doc, tab, name): ballot = doc.latest_event(BallotDocEvent, type="created_ballot") if doc.type_id in ("draft","conflrev", "statchg"): - # if doc.in_ietf_process and doc.ietf_process.has_iesg_ballot: tabs.append(("IESG Evaluation Record", "ballot", urlreverse("doc_ballot", kwargs=dict(name=name)), ballot, None if ballot else "IESG Evaluation Ballot has not been created yet")) elif doc.type_id == "charter": tabs.append(("IESG Review", "ballot", urlreverse("doc_ballot", kwargs=dict(name=name)), ballot, None if ballot else "IEST Review Ballot has not been created yet")) - # FIXME: if doc.in_ietf_process and doc.ietf_process.has_iesg_ballot: if doc.type_id not in ["conflrev", "statchg"]: tabs.append(("IESG Writeups", "writeup", urlreverse("doc_writeup", kwargs=dict(name=name)), True)) @@ -254,9 +252,11 @@ def document_main(request, name, rev=None): resurrected_by = e.by # stream info + stream_state_type_slug = None stream_state = None if doc.stream: - stream_state = doc.get_state("draft-stream-%s" % doc.stream_id) + stream_state_type_slug = "draft-stream-%s" % doc.stream_id + stream_state = doc.get_state(stream_state_type_slug) stream_tags = doc.tags.filter(slug__in=get_tags_for_stream_id(doc.stream_id)) shepherd_writeup = doc.latest_event(WriteupDocEvent, type="changed_protocol_writeup") @@ -286,13 +286,8 @@ def document_main(request, name, rev=None): # remaining actions actions = [] - if ((not doc.stream_id or doc.stream_id in ("ietf", "irtf")) and group.type_id == "individ" and - (request.user.is_authenticated() and - Role.objects.filter(person__user=request.user, name__in=("chair", "secr", "delegate"), - group__type__in=("wg","rg"), - group__state="active") - or has_role(request.user, "Secretariat"))): - actions.append(("Adopt in Group", urlreverse('edit_adopt', kwargs=dict(name=doc.name)))) + if can_adopt_draft(request.user, doc): + actions.append(("Adopt in Group", urlreverse('doc_adopt_draft', kwargs=dict(name=doc.name)))) if doc.get_state_slug() == "expired" and not resurrected_by and can_edit: actions.append(("Request Resurrect", urlreverse('doc_request_resurrect', kwargs=dict(name=doc.name)))) @@ -366,6 +361,7 @@ def document_main(request, name, rev=None): has_errata=doc.tags.filter(slug="errata"), published=doc.latest_event(type="published_rfc"), file_urls=file_urls, + stream_state_type_slug=stream_state_type_slug, stream_state=stream_state, stream_tags=stream_tags, milestones=doc.groupmilestone_set.filter(state="active"), @@ -765,48 +761,6 @@ def document_json(request, name): return HttpResponse(json.dumps(data, indent=2), mimetype='text/plain') -def ballot_json(request, name): - # REDESIGN: this view needs to be deleted or updated - def get_ballot(name): - from ietf.doc.models import DocAlias - alias = get_object_or_404(DocAlias, name=name) - d = alias.document - from ietf.idtracker.models import InternetDraft, BallotInfo - from ietf.idrfc.idrfc_wrapper import BallotWrapper, IdWrapper, RfcWrapper - id = None - bw = None - dw = None - if (d.type_id=='draft'): - id = get_object_or_404(InternetDraft, name=d.name) - try: - if not id.ballot.ballot_issued: - raise Http404 - except BallotInfo.DoesNotExist: - raise Http404 - - bw = BallotWrapper(id) # XXX Fixme: Eliminate this as we go forward - # Python caches ~100 regex'es -- explicitly compiling it inside a method - # (where you then throw away the compiled version!) doesn't make sense at - # all. - if re.search("^rfc([1-9][0-9]*)$", name): - id.viewing_as_rfc = True - dw = RfcWrapper(id) - else: - dw = IdWrapper(id) - # XXX Fixme: Eliminate 'dw' as we go forward - - try: - b = d.latest_event(BallotDocEvent, type="created_ballot") - except BallotDocEvent.DoesNotExist: - raise Http404 - - return (bw, dw, b, d) - - ballot, doc, b, d = get_ballot(name) - response = HttpResponse(mimetype='text/plain') - response.write(json.dumps(ballot.dict(), indent=2)) - return response - class AddCommentForm(forms.Form): comment = forms.CharField(required=True, widget=forms.Textarea) diff --git a/ietf/doc/views_draft.py b/ietf/doc/views_draft.py index cba26223e..0fc7cc2ec 100644 --- a/ietf/doc/views_draft.py +++ b/ietf/doc/views_draft.py @@ -15,9 +15,10 @@ from django.db.models import Max from django.conf import settings from django.forms.util import ErrorList from django.contrib.auth.decorators import login_required +from django.template.defaultfilters import pluralize from ietf.utils.mail import send_mail_text, send_mail_message -from ietf.ietfauth.decorators import role_required +from ietf.ietfauth.utils import role_required from ietf.ietfauth.utils import has_role, is_authorized_in_doc_stream, user_is_person from ietf.iesg.models import TelechatDate from ietf.doc.mails import * @@ -27,11 +28,6 @@ from ietf.person.forms import EmailsField from ietf.group.models import Group from ietf.secr.lib import jsonapi -from ietf.ietfworkflows.models import Stream -from ietf.ietfworkflows.utils import update_stream -from ietf.ietfworkflows.streams import get_stream_from_draft -from ietf.ietfworkflows.accounts import can_edit_state - from ietf.doc.models import * from ietf.doc.utils import * from ietf.name.models import IntendedStdLevelName, DocTagName, StreamName @@ -402,7 +398,7 @@ def replaces(request, name): return HttpResponseRedirect(doc.get_absolute_url()) else: form = ReplacesForm(doc=doc) - return render_to_response('idrfc/change_replaces.html', + return render_to_response('doc/draft/change_replaces.html', dict(form=form, doc=doc, ), @@ -1180,7 +1176,7 @@ def request_publication(request, name): doc = get_object_or_404(Document, type="draft", name=name, stream__in=("iab", "ise", "irtf")) - if not can_edit_state(request.user, doc): + if not is_authorized_in_doc_stream(request.user, doc): return HttpResponseForbidden("You do not have the necessary permissions to view this page") m = Message() @@ -1255,3 +1251,225 @@ def request_publication(request, name): ), context_instance = RequestContext(request)) +class AdoptDraftForm(forms.Form): + group = forms.ModelChoiceField(queryset=Group.objects.filter(type__in=["wg", "rg"], state="active").order_by("-type", "acronym"), required=True, empty_label=None) + comment = forms.CharField(widget=forms.Textarea, required=False, label="Comment", help_text="Optional comment explaining the reasons for the adoption") + weeks = forms.IntegerField(required=False, label="Expected weeks in adoption state") + + def __init__(self, *args, **kwargs): + user = kwargs.pop("user") + + super(AdoptDraftForm, self).__init__(*args, **kwargs) + + if has_role(user, "Secretariat"): + pass # all groups + else: + self.fields["group"].queryset = self.fields["group"].queryset.filter(role__person__user=user, role__name__in=("chair", "delegate", "secr")).distinct() + + self.fields['group'].choices = [(g.pk, '%s - %s' % (g.acronym, g.name)) for g in self.fields["group"].queryset] + + +@login_required +def adopt_draft(request, name): + doc = get_object_or_404(Document, type="draft", name=name) + + if not can_adopt_draft(request.user, doc): + return HttpResponseForbidden("You don't have permission to access this page") + + if request.method == 'POST': + form = AdoptDraftForm(request.POST, user=request.user) + + if form.is_valid(): + # adopt + by = request.user.get_profile() + + save_document_in_history(doc) + + doc.time = datetime.datetime.now() + + group = form.cleaned_data["group"] + if group.type.slug == "rg": + new_stream = StreamName.objects.get(slug="irtf") + adopt_state_slug = "active" + else: + new_stream = StreamName.objects.get(slug="ietf") + adopt_state_slug = "c-adopt" + + # stream + if doc.stream != new_stream: + e = DocEvent(type="changed_stream", time=doc.time, by=by, doc=doc) + e.desc = u"Changed stream to %s" % new_stream.name + if doc.stream: + e.desc += u" from %s" % doc.stream.name + e.save() + doc.stream = new_stream + + # group + if group != doc.group: + e = DocEvent(type="changed_group", time=doc.time, by=by, doc=doc) + e.desc = u"Changed group to %s (%s)" % (group.name, group.acronym.upper()) + if doc.group.type_id != "individ": + e.desc += " from %s (%s)" % (doc.group.name, doc.group.acronym.upper()) + e.save() + doc.group = group + + doc.save() + + # state + prev_state = doc.get_state("draft-stream-%s" % doc.stream_id) + new_state = State.objects.get(slug=adopt_state_slug, type="draft-stream-%s" % doc.stream_id, used=True) + if new_state != prev_state: + doc.set_state(new_state) + e = add_state_change_event(doc, by, prev_state, new_state, doc.time) + + due_date = None + if form.cleaned_data["weeks"] != None: + due_date = datetime.date.today() + datetime.timedelta(weeks=form.cleaned_data["weeks"]) + + update_reminder(doc, "stream-s", e, due_date) + + # comment + comment = form.cleaned_data["comment"].strip() + if comment: + e = DocEvent(type="added_comment", time=doc.time, by=by, doc=doc) + e.desc = comment + e.save() + + email_draft_adopted(request, doc, by, comment) + + return HttpResponseRedirect(doc.get_absolute_url()) + else: + form = AdoptDraftForm(user=request.user) + + return render_to_response('doc/draft/adopt_draft.html', + {'doc': doc, + 'form': form, + }, + context_instance=RequestContext(request)) + +class ChangeStreamStateForm(forms.Form): + new_state = forms.ModelChoiceField(queryset=State.objects.filter(used=True), label='State', help_text=u"Only select 'Submitted to IESG for Publication' to correct errors. Use the document's main page to request publication.") + weeks = forms.IntegerField(label='Expected weeks in state',required=False) + comment = forms.CharField(widget=forms.Textarea, required=False, help_text="Optional comment for the document history") + tags = forms.ModelMultipleChoiceField(queryset=DocTagName.objects.filter(used=True), widget=forms.CheckboxSelectMultiple, required=False) + + def __init__(self, *args, **kwargs): + doc = kwargs.pop("doc") + state_type = kwargs.pop("state_type") + super(ChangeStreamStateForm, self).__init__(*args, **kwargs) + + f = self.fields["new_state"] + f.queryset = f.queryset.filter(type=state_type) + if doc.group: + unused_states = doc.group.unused_states.values_list("pk", flat=True) + f.queryset = f.queryset.exclude(pk__in=unused_states) + f.label = state_type.label + + f = self.fields['tags'] + f.queryset = f.queryset.filter(slug__in=get_tags_for_stream_id(doc.stream_id)) + if doc.group: + unused_tags = doc.group.unused_tags.values_list("pk", flat=True) + f.queryset = f.queryset.exclude(pk__in=unused_tags) + +def next_states_for_stream_state(doc, state_type, current_state): + # find next states + next_states = [] + if current_state: + next_states = current_state.next_states.all() + + if doc.stream_id == "ietf" and doc.group: + transitions = doc.group.groupstatetransitions_set.filter(state=current_state) + if transitions: + next_states = transitions[0].next_states.all() + else: + # return the initial state + states = State.objects.filter(used=True, type=state_type).order_by('order') + if states: + next_states = states[:1] + + if doc.group: + unused_states = doc.group.unused_states.values_list("pk", flat=True) + next_states = [n for n in next_states if n.pk not in unused_states] + + return next_states + +@login_required +def change_stream_state(request, name, state_type): + doc = get_object_or_404(Document, type="draft", name=name) + if not doc.stream: + raise Http404 + + state_type = get_object_or_404(StateType, slug=state_type) + + if not is_authorized_in_doc_stream(request.user, doc): + return HttpResponseForbidden("You don't have permission to access this page") + + prev_state = doc.get_state(state_type.slug) + next_states = next_states_for_stream_state(doc, state_type, prev_state) + + if request.method == 'POST': + form = ChangeStreamStateForm(request.POST, doc=doc, state_type=state_type) + if form.is_valid(): + by = request.user.get_profile() + + save_document_in_history(doc) + + doc.time = datetime.datetime.now() + comment = form.cleaned_data["comment"].strip() + + # state + new_state = form.cleaned_data["new_state"] + if new_state != prev_state: + doc.set_state(new_state) + e = add_state_change_event(doc, by, prev_state, new_state, doc.time) + + due_date = None + if form.cleaned_data["weeks"] != None: + due_date = datetime.date.today() + datetime.timedelta(weeks=form.cleaned_data["weeks"]) + + update_reminder(doc, "stream-s", e, due_date) + + email_stream_state_changed(request, doc, prev_state, new_state, by, comment) + + # tags + existing_tags = set(doc.tags.all()) + new_tags = set(form.cleaned_data["tags"]) + + if existing_tags != new_tags: + doc.tags = new_tags + + e = DocEvent(type="changed_document", time=doc.time, by=by, doc=doc) + added_tags = new_tags - existing_tags + removed_tags = existing_tags - new_tags + l = [] + if added_tags: + l.append(u"Tag%s %s set." % (pluralize(added_tags), ", ".join(t.name for t in added_tags))) + if removed_tags: + l.append(u"Tag%s %s cleared." % (pluralize(removed_tags), ", ".join(t.name for t in removed_tags))) + e.desc = " ".join(l) + e.save() + + email_stream_tags_changed(request, doc, added_tags, removed_tags, by, comment) + + # comment + if comment: + e = DocEvent(type="added_comment", time=doc.time, by=by, doc=doc) + e.desc = comment + e.save() + + return HttpResponseRedirect(doc.get_absolute_url()) + else: + form = ChangeStreamStateForm(initial=dict(new_state=prev_state.pk if prev_state else None), + doc=doc, state_type=state_type) + + milestones = doc.groupmilestone_set.all() + + + return render_to_response("doc/draft/change_stream_state.html", + {"doc": doc, + "form": form, + "milestones": milestones, + "state_type": state_type, + "next_states": next_states, + }, + context_instance=RequestContext(request)) diff --git a/ietf/doc/views_help.py b/ietf/doc/views_help.py index f8493346d..b4b41ae54 100644 --- a/ietf/doc/views_help.py +++ b/ietf/doc/views_help.py @@ -4,12 +4,14 @@ from django.template import RequestContext from django.http import Http404 from ietf.doc.models import * +from ietf.doc.utils import get_tags_for_stream_id def state_help(request, type): slug, title = { "draft-iesg": ("draft-iesg", "IESG States For Internet-Drafts"), "draft-rfceditor": ("draft-rfceditor", "RFC Editor States For Internet-Drafts"), "draft-iana-action": ("draft-iana-action", "IANA Action States For Internet-Drafts"), + "draft-stream-ietf": ("draft-stream-ietf", "IETF Stream States For Internet-Drafts"), "charter": ("charter", "Charter States"), "conflict-review": ("conflrev", "Conflict Review States"), "status-change": ("statchg", "RFC Status Change States"), @@ -36,6 +38,9 @@ def state_help(request, type): states.insert(0, fake_state) tags = DocTagName.objects.filter(slug__in=IESG_SUBSTATE_TAGS) + elif state_type.slug.startswith("draft-stream-"): + possible = get_tags_for_stream_id(state_type.slug.replace("draft-stream-", "")) + tags = DocTagName.objects.filter(slug__in=possible) return render_to_response("doc/state_help.html", { "title": title, diff --git a/ietf/doc/views_status_change.py b/ietf/doc/views_status_change.py index d83254867..27841f2b2 100644 --- a/ietf/doc/views_status_change.py +++ b/ietf/doc/views_status_change.py @@ -12,7 +12,7 @@ from ietf.doc.utils import log_state_changed, update_telechat from ietf.doc.models import save_document_in_history from ietf.doc.utils import create_ballot_if_not_open, close_open_ballots, get_document_content -from ietf.ietfauth.decorators import has_role, role_required +from ietf.ietfauth.utils import has_role, role_required from ietf.utils.textupload import get_cleaned_text_file_content from ietf.utils.mail import send_mail_preformatted from ietf.doc.models import State, Document, DocHistory, DocAlias diff --git a/ietf/group/ajax.py b/ietf/group/ajax.py index d4c0bd1cd..568420eea 100644 --- a/ietf/group/ajax.py +++ b/ietf/group/ajax.py @@ -1,17 +1,15 @@ -from django.utils import simplejson as json -from dajaxice.core import dajaxice_functions -from dajaxice.decorators import dajaxice_register -from ietf.ietfauth.decorators import group_required -from django.shortcuts import get_object_or_404 -from django.http import HttpResponseRedirect, HttpResponse, Http404 - -from ietf.group.models import Group import datetime import logging import sys -from ietf.settings import LOG_DIR -log = logging.getLogger(__name__) +from django.utils import simplejson as json +from django.shortcuts import get_object_or_404 +from django.http import HttpResponseRedirect, HttpResponse, Http404 + +from dajaxice.core import dajaxice_functions +from dajaxice.decorators import dajaxice_register + +from ietf.group.models import Group def group_json(request, groupname): group = get_object_or_404(Group, acronym=groupname) diff --git a/ietf/group/fixtures/groupgroup.json b/ietf/group/fixtures/groupgroup.json index 97e7c7353..11d68fd97 100644 --- a/ietf/group/fixtures/groupgroup.json +++ b/ietf/group/fixtures/groupgroup.json @@ -1,11 +1,11 @@ [ {"pk": 1, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ietf", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-02-26 00:21:36", "unused_tags": [], "list_archive": "", "type": "ietf", "name": "IETF"}}, -{"pk": 2, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1, "list_email": "iesg@ietf.org", "acronym": "iesg", "comments": "", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ietf", "name": "Internet Engineering Steering Group"}}, +{"pk": 2, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1, "list_email": "iesg@ietf.org", "acronym": "iesg", "comments": "", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ietf", "name": "Internet Engineering Steering Group"}}, {"pk": 3, "model": "group.group", "fields": {"charter": null, "unused_states": [81, 82, 83, 84, 85, 86, 87, 88, 1, 2, 3, 4, 5, 6, 16, 13, 21, 14, 15, 19, 20, 12, 18, 9, 10, 17, 7, 22, 23, 11, 8, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 79, 80, 77, 78], "ad": null, "parent": null, "list_email": "", "acronym": "irtf", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-02-26 00:21:36", "unused_tags": ["app-min", "errata", "iesg-com", "missref", "need-sh", "ref", "rfc-rev", "via-rfc", "w-dep", "need-ed", "point", "w-expert", "ad-f-up", "w-extern", "w-part", "extpty", "w-merge", "w-review", "need-aut", "sh-f-up", "need-rev", "w-refdoc", "w-refing", "rev-wglc", "rev-ad", "rev-iesg", "sheph-u", "other"], "list_archive": "", "type": "irtf", "name": "IRTF"}}, {"pk": 4, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "secretariat", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-02-26 00:21:36", "unused_tags": [], "list_archive": "", "type": "ietf", "name": "IETF Secretariat"}}, {"pk": 5, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ise", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-02-26 00:21:36", "unused_tags": [], "list_archive": "", "type": "ietf", "name": "Independent Submission Editor"}}, {"pk": 6, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "rsoc", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-02-26 00:21:36", "unused_tags": [], "list_archive": "", "type": "ietf", "name": "RFC Series Oversight Committee"}}, -{"pk": 7, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1, "list_email": "iab@iab.org", "acronym": "iab", "comments": "1st meeting at 35th IETF - Los Angeles, CA - March 1996", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ietf", "name": "Internet Architecture Board"}}, +{"pk": 7, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1, "list_email": "iab@iab.org", "acronym": "iab", "comments": "1st meeting at 35th IETF - Los Angeles, CA - March 1996", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ietf", "name": "Internet Architecture Board"}}, {"pk": 8, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "iana", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-02-26 00:21:36", "unused_tags": [], "list_archive": "", "type": "ietf", "name": "IANA"}}, {"pk": 9, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "iepg", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-02-26 00:21:36", "unused_tags": [], "list_archive": "", "type": "ietf", "name": "IEPG"}}, {"pk": 10, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "nomcom1992", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2012-02-26 00:21:36", "unused_tags": [], "list_archive": "", "type": "ietf", "name": "IAB/IESG Nominating Committee 1992/1993"}}, @@ -85,34 +85,34 @@ {"pk": 84, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "itu-t-sg-12", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-02-26 00:21:37", "unused_tags": [], "list_archive": "", "type": "sdo", "name": "ITU-T SG 12"}}, {"pk": 925, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "vgmib@hprnd.rose.hp.com", "acronym": "vgmib", "comments": "1st meeting 32nd IETF Danvers, MA April 3-7, 1995 mw (BOF)\r\n\r\nAD was Burgan", "list_subscribe": "vgmib-request@hprnd.rose.hp.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://rosegarden.external.hp.com/pub/vgmib", "type": "wg", "name": "100VG-AnyLAN MIB"}}, {"pk": 926, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-asid@umich.edu", "acronym": "asid", "comments": "1st IETF Meeting: Seattle: 94-03: BOF Name change 5/95 from Access/Synchronization of the Internet Directories WG /mw", "list_subscribe": "ietf-asid-request@umich.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://terminator.rs.itd.umich.edu/ietf-asid/archive", "type": "wg", "name": "Access, Searching and Indexing of Directories"}}, -{"pk": 927, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": 1092, "list_email": "addrconf@cisco.com", "acronym": "addrconf", "comments": "", "list_subscribe": "addrconf-request@cisco.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://munnari.oz.au/addrconf/list-archive", "type": "wg", "name": "Address Autoconfiguration"}}, -{"pk": 928, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "aeiou", "comments": "1st MEETING: Seattle 94-03: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Address Extension by IP Option Usage"}}, -{"pk": 929, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": 1092, "list_email": "ipv4-ale@ftp.com", "acronym": "ale", "comments": "Met as a BOF in Houston. 93-11; merged with cidr on 3/16/95.", "list_subscribe": "ipv4-ale-request@ftp.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "research.ftp.com:pub/ale/", "type": "wg", "name": "Address Lifetime Expectations"}}, -{"pk": 930, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "alert-man@merit.edu", "acronym": "alertman", "comments": "Still has two documents to get published as experimental.", "list_subscribe": "alert-man-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Alert Management"}}, +{"pk": 927, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1092, "list_email": "addrconf@cisco.com", "acronym": "addrconf", "comments": "", "list_subscribe": "addrconf-request@cisco.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://munnari.oz.au/addrconf/list-archive", "type": "wg", "name": "Address Autoconfiguration"}}, +{"pk": 928, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "aeiou", "comments": "1st MEETING: Seattle 94-03: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Address Extension by IP Option Usage"}}, +{"pk": 929, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1092, "list_email": "ipv4-ale@ftp.com", "acronym": "ale", "comments": "Met as a BOF in Houston. 93-11; merged with cidr on 3/16/95.", "list_subscribe": "ipv4-ale-request@ftp.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "research.ftp.com:pub/ale/", "type": "wg", "name": "Address Lifetime Expectations"}}, +{"pk": 930, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1157, "list_email": "alert-man@merit.edu", "acronym": "alertman", "comments": "Still has two documents to get published as experimental.", "list_subscribe": "alert-man-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Alert Management"}}, {"pk": 931, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-aaarg@imc.org", "acronym": "aaarg", "comments": "1st meeting held at 39th IETF - Munich, Germany", "list_subscribe": "ietf-aaarg-request@imc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www/imc.org/ietf-aaarg", "type": "wg", "name": "Application Authentication/Authorization Review Gr"}}, {"pk": 932, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-acap+@andrew.cmu.edu", "acronym": "acap", "comments": "1st meeting at 36th IETF - Montreal, Canada", "list_subscribe": "majordomo@lists.andrew.cmu.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "anonymous IMAP: cyrus.andrew.cmu.edu:archive.ietf-acap", "type": "wg", "name": "Application Configuration Access Protocol"}}, {"pk": 933, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "applmib@ietf.verio.net", "acronym": "applmib", "comments": "1st meeting, 34th IETF Dallas, TX December 4-8, 1995 mw", "list_subscribe": "applmib-request@ietf.verio.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ietf.verio.net/pub/applmib/archive", "type": "wg", "name": "Application MIB"}}, {"pk": 934, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 2, "list_email": "", "acronym": "app", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-02-26 00:21:37", "unused_tags": [], "list_archive": "", "type": "area", "name": "Applications Area"}}, -{"pk": 936, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 18321, "parent": 934, "list_email": "", "acronym": "apparea", "comments": "First meeting at 35th IETF in Los Angeles, CA - March 1996", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ag", "name": "Applications Area Open Meeting"}}, +{"pk": 936, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "apparea", "comments": "First meeting at 35th IETF in Los Angeles, CA - March 1996", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ag", "name": "Applications Area Open Meeting"}}, {"pk": 937, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "apptsv", "comments": "1st meeting at 35th IETF - Los Angeles - March 1996", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ag", "name": "Applications/Transport Joint Session"}}, -{"pk": 938, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2372, "parent": 1199, "list_email": "ietf-osi-nsap@osi3.ncsl.nist.gov", "acronym": "osinsap", "comments": "", "list_subscribe": "ietf-osi-nsap-request@osi3.ncsl.nist.gov", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Assignment of OSI NSAP Addresses"}}, -{"pk": 939, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 188, "parent": null, "list_email": "", "acronym": "afic", "comments": "1st met as BOF 33rd IETF: Stockholm: 17-21 1995 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "ATM Forum/IETF Cooperation BOF"}}, +{"pk": 938, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1199, "list_email": "ietf-osi-nsap@osi3.ncsl.nist.gov", "acronym": "osinsap", "comments": "", "list_subscribe": "ietf-osi-nsap-request@osi3.ncsl.nist.gov", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Assignment of OSI NSAP Addresses"}}, +{"pk": 939, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "afic", "comments": "1st met as BOF 33rd IETF: Stockholm: 17-21 1995 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "ATM Forum/IETF Cooperation BOF"}}, {"pk": 940, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "atommib@research.telcordia.com", "acronym": "atommib", "comments": "Met as atmmib BOF in Ohio. O-start 4/15/93, concluded 8/25/94", "list_subscribe": "atommib-request@research.telcordia.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.research.telcordia.com/pub/Group.archive/atommib", "type": "wg", "name": "AToM MIB"}}, -{"pk": 941, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "avt@ietf.org", "acronym": "avt", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/avt", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/avt/", "type": "wg", "name": "Audio/Video Transport"}}, +{"pk": 941, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "avt@ietf.org", "acronym": "avt", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/avt", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/avt/", "type": "wg", "name": "Audio/Video Transport"}}, {"pk": 942, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "aft@socks.nec.com", "acronym": "aft", "comments": "1st meeting December 1994 IETF, San Jose /mw", "list_subscribe": "aft-request@socks.nec.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.socks.nec.com/aftmail/", "type": "wg", "name": "Authenticated Firewall Traversal"}}, {"pk": 943, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "ietf-aac@isi.edu", "acronym": "aac", "comments": "Work of the WG to be subsumed by CAT WG.", "list_subscribe": "ietf-aac-request@isi.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "prospero.isi.edu:~/pub/aac/*", "type": "wg", "name": "Authorization and Access Control"}}, {"pk": 944, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-list-wg@utdallas.edu", "acronym": "list", "comments": "", "list_subscribe": "ietf-list-wg-request@utdallas.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "pub/ietf-list-wg@ftp.utdallas.edu", "type": "wg", "name": "Automated Internet Mailing List Services"}}, -{"pk": 945, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 101568, "parent": 1193, "list_email": "bmwg@ietf.org", "acronym": "bmwg", "comments": "", "list_subscribe": "bmwg-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/bmwg/", "type": "wg", "name": "Benchmarking Methodology"}}, -{"pk": 946, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": 1193, "list_email": "bgpd@merit.edu", "acronym": "bgpdepl", "comments": "Not really concluded. Renamed to Cidr Deployment (cidrp)", "list_subscribe": "bgpd-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "merit.edu:~/pub/bgpd-archive", "type": "wg", "name": "BGP Deployment and Application"}}, +{"pk": 945, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "bmwg@ietf.org", "acronym": "bmwg", "comments": "", "list_subscribe": "bmwg-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/bmwg/", "type": "wg", "name": "Benchmarking Methodology"}}, +{"pk": 946, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "bgpd@merit.edu", "acronym": "bgpdepl", "comments": "Not really concluded. Renamed to Cidr Deployment (cidrp)", "list_subscribe": "bgpd-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "merit.edu:~/pub/bgpd-archive", "type": "wg", "name": "BGP Deployment and Application"}}, {"pk": 947, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "bgp@ans.net", "acronym": "bgp", "comments": "BGP merged with IPIDRP to become IDR.", "list_subscribe": "bgp-request@ans.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp.ans.net:/pub/archive/iwg", "type": "wg", "name": "Border Gateway Protocol"}}, {"pk": 948, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "bridge-mib@ietf.org", "acronym": "bridge", "comments": "mailing list was at nsl.dec.com. Ended 9/30/93. Reactivated 2/21/96", "list_subscribe": "bridge-mib-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/bridge-mib/", "type": "wg", "name": "Bridge MIB"}}, {"pk": 949, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-calendar@imc.org", "acronym": "calsch", "comments": "", "list_subscribe": "ietf-calendar-request@imc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.imc.org/ietf-calendar/mail-archive/", "type": "wg", "name": "Calendaring and Scheduling"}}, -{"pk": 950, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "char-mib@decwrl.dec.com", "acronym": "charmib", "comments": "Started 8/1/90. Reactivated on 4/15/93", "list_subscribe": "char-mib-request@decwrl.dec.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Character MIB"}}, +{"pk": 950, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1157, "list_email": "char-mib@decwrl.dec.com", "acronym": "charmib", "comments": "Started 8/1/90. Reactivated on 4/15/93", "list_subscribe": "char-mib-request@decwrl.dec.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Character MIB"}}, {"pk": 951, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-charsets@innosoft.com", "acronym": "charset", "comments": "", "list_subscribe": "ietf-charsets-request@innosoft.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Character Set Policy"}}, -{"pk": 953, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "chassismib@cs.utk.edu", "acronym": "chassis", "comments": "", "list_subscribe": "chassismib-request@cs.utk.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Chassis MIB"}}, -{"pk": 954, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": 1193, "list_email": "cidrd@iepg.org", "acronym": "cidrd", "comments": "Renamed from BGP Deployment (bgpdpl). Subsumed ale wg on 3/16/95.", "list_subscribe": "cidrd-request@iepg.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://aarnet.edu.au/pub/mailing-lists/cidrd*", "type": "wg", "name": "CIDR Deployment"}}, +{"pk": 953, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1157, "list_email": "chassismib@cs.utk.edu", "acronym": "chassis", "comments": "", "list_subscribe": "chassismib-request@cs.utk.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Chassis MIB"}}, +{"pk": 954, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "cidrd@iepg.org", "acronym": "cidrd", "comments": "Renamed from BGP Deployment (bgpdpl). Subsumed ale wg on 3/16/95.", "list_subscribe": "cidrd-request@iepg.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://aarnet.edu.au/pub/mailing-lists/cidrd*", "type": "wg", "name": "CIDR Deployment"}}, {"pk": 955, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "", "acronym": "cidr", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "CIDR Supernetting"}}, -{"pk": 956, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "netman@gateway.mitre.org", "acronym": "cmot", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "CMIP Over TCP"}}, +{"pk": 956, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1157, "list_email": "netman@gateway.mitre.org", "acronym": "cmot", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "CMIP Over TCP"}}, {"pk": 957, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "colip-atm@necom830.cc.titech.ac.jp", "acronym": "colip", "comments": "1st meeting, 32nd IETF Danvers, MA April 3-7, 1995 mw", "list_subscribe": "colip-atm-request@necom830.cc.titech.ac.jp", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "CO and CL IP Transport over ATM"}}, {"pk": 958, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "cipso@wdl1.wdl.loral.com", "acronym": "cipso", "comments": "This group is an external group working to join the IETF framework for some of their specific tasks. Associated w/TSIG", "list_subscribe": "cipso-request@wdl1.wdl.loral.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "archive-server@wdl1.wdl.loral.com", "type": "wg", "name": "Commercial Internet Protocol Security Option"}}, {"pk": 959, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1092, "list_email": "catnip@world.std.com", "acronym": "catnip", "comments": "Originally named TPIX.", "list_subscribe": "catnip-request@world.std.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://world.std.com/pub/catnip/*", "type": "wg", "name": "Common Architecture for Next Generation IP"}}, @@ -124,87 +124,87 @@ {"pk": 965, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "ietf-coredb@imc.org", "acronym": "coredb", "comments": "1st Meeting at 38th IETF - Memphis, TN Charter submitted 5/6/97. WG not established.", "list_subscribe": "ietf-coredb-request@imc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.imc.org/ietf-coredb/mail-archive/", "type": "wg", "name": "Council of Registrars Database"}}, {"pk": 966, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "dlsw", "comments": "1st IETF meeting: Seattle: 94-03: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Data Link Switching"}}, {"pk": 967, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "aiw-dlsw-mib@networking.raleigh.ibm.com", "acronym": "dlswmib", "comments": "1st meeting in San Jose: December 5-9, 1994", "list_subscribe": "aiw-dlsw-mib-request@networking.raleigh.ibm.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://host name/pub/standards/aiw/maillogs/mib.mail", "type": "wg", "name": "Data Link Switching MIB"}}, -{"pk": 968, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": 1193, "list_email": "", "acronym": "ddniwg", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "DDN Interconnectivity"}}, -{"pk": 969, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "phiv-mib@pa.dec.com", "acronym": "decnetiv", "comments": "Started 5/1/90. Went dormant 6/2/92, reactivated 4/15/93", "list_subscribe": "phiv-mib-request@pa.dec.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "DECnet Phase IV MIB"}}, +{"pk": 968, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "ddniwg", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "DDN Interconnectivity"}}, +{"pk": 969, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1157, "list_email": "phiv-mib@pa.dec.com", "acronym": "decnetiv", "comments": "Started 5/1/90. Went dormant 6/2/92, reactivated 4/15/93", "list_subscribe": "phiv-mib-request@pa.dec.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "DECnet Phase IV MIB"}}, {"pk": 970, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "drums@cs.utk.edu", "acronym": "drums", "comments": "", "list_subscribe": "drums-request@cs.utk.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://cs.utk.edu/pub/drums/mail-archive/", "type": "wg", "name": "Detailed Revision/Update of Message Standards"}}, -{"pk": 971, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "opmeas", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Developing Operational Measurement Criteria"}}, -{"pk": 972, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "roamreq", "comments": "1st meeting at 36th IETF - Montreal, Canada", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Dialup Roaming Requirements BOF"}}, -{"pk": 973, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "disi@merit.edu", "acronym": "disi", "comments": "", "list_subscribe": "disi-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "pub/disi-archive@merit.edu", "type": "wg", "name": "Directory Information Services Infrastructure"}}, +{"pk": 971, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "opmeas", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Developing Operational Measurement Criteria"}}, +{"pk": 972, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "roamreq", "comments": "1st meeting at 36th IETF - Montreal, Canada", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Dialup Roaming Requirements BOF"}}, +{"pk": 973, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "disi@merit.edu", "acronym": "disi", "comments": "", "list_subscribe": "disi-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "pub/disi-archive@merit.edu", "type": "wg", "name": "Directory Information Services Infrastructure"}}, {"pk": 974, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-dis@bacon.gmu.edu", "acronym": "lamug", "comments": "1st meeting - Montreal, Canada June 1996", "list_subscribe": "ietf-dis-request@bacon.gmu.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "DIS Large-Scale Multicast Usage"}}, -{"pk": 975, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2744, "parent": null, "list_email": "dfs-wg@citi.umich.edu", "acronym": "dfs", "comments": "", "list_subscribe": "dfs-wg-request@citi.umich.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Distributed File Systems"}}, +{"pk": 975, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "dfs-wg@citi.umich.edu", "acronym": "dfs", "comments": "", "list_subscribe": "dfs-wg-request@citi.umich.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Distributed File Systems"}}, {"pk": 976, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "dis", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Distributed Interactive Simulation"}}, -{"pk": 977, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 6699, "parent": 1193, "list_email": "disman@ietf.org", "acronym": "disman", "comments": "1st meeting 32nd IETF, Danvers April 3-7. 1995 mw\r\nOld Archvies at: ftp://ftp.ietf.org/ietf-mail-archive/disman/", "list_subscribe": "disman-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/disman/", "type": "wg", "name": "Distributed Management"}}, +{"pk": 977, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "disman@ietf.org", "acronym": "disman", "comments": "1st meeting 32nd IETF, Danvers April 3-7. 1995 mw\r\nOld Archvies at: ftp://ftp.ietf.org/ietf-mail-archive/disman/", "list_subscribe": "disman-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/disman/", "type": "wg", "name": "Distributed Management"}}, {"pk": 978, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "chronos@boombox.micro.umn.edu", "acronym": "chronos", "comments": "", "list_subscribe": "chronos-request@boombox.micro.umn.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "/pub/chronos @boombox.micro.umn.edu", "type": "wg", "name": "Distributed Scheduling Protocol"}}, -{"pk": 979, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "", "acronym": "dawg", "comments": "1st IETF Meeting: Seattle: 94-03: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Distribution and Announcement"}}, -{"pk": 980, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2744, "parent": null, "list_email": "", "acronym": "dnsfutur", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "DNS Future Work"}}, +{"pk": 979, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "", "acronym": "dawg", "comments": "1st IETF Meeting: Seattle: 94-03: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Distribution and Announcement"}}, +{"pk": 980, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "dnsfutur", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "DNS Future Work"}}, {"pk": 981, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "dns2", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "DNS II"}}, {"pk": 982, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "namedroppers@internic.net", "acronym": "dnsind", "comments": "BOF in Seattle, then turned into WG.", "list_subscribe": "namedroppers-request@internic.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://rs.internic.net/archives/namedroppers", "type": "wg", "name": "DNS IXFR, Notification, and Dynamic Update"}}, {"pk": 983, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "dnsbof", "comments": "1st meeting at Los Angeles - 35th IETF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Domain Name Server BOF"}}, -{"pk": 984, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2744, "parent": 934, "list_email": "namedroppers@nic.ddn.mil", "acronym": "dns", "comments": "Archive disappeared.", "list_subscribe": "namedroppers-request@nic.ddn.mil", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "nicfs.nic.ddn.mil:~/namedroppers/*.Z", "type": "wg", "name": "Domain Name System"}}, +{"pk": 984, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "namedroppers@nic.ddn.mil", "acronym": "dns", "comments": "Archive disappeared.", "list_subscribe": "namedroppers-request@nic.ddn.mil", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "nicfs.nic.ddn.mil:~/namedroppers/*.Z", "type": "wg", "name": "Domain Name System"}}, {"pk": 985, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "dns-security@lists.tislabs.com", "acronym": "dnssec", "comments": "Moved from SAP to SEC on 10 May 1994 by JWS.", "list_subscribe": "dns-security-request@lists.tislabs.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.tis.com/pub/lists/dns-security", "type": "wg", "name": "Domain Name System Security"}}, {"pk": 986, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "trunk-mib@external.cisco.com", "acronym": "trunkmib", "comments": "Orig. Start: 1/23/92; End: 2/18/93. Restarted in Stockholm. Tracy Cox Brown was co-chair for the first group. mw\r\n\r\nAD was Burgan", "list_subscribe": "trunk-mib-request@cisco.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "DS1/DS3 MIB"}}, {"pk": 987, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "dcnl-ietf@cray.com", "acronym": "dcnl", "comments": "Likely to become a Working Group", "list_subscribe": "dcnl-ietf-request@cray.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Dynamic Creation of Network Links (T3 Circuits)"}}, -{"pk": 988, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "dhcwg@ietf.org", "acronym": "dhc", "comments": "", "list_subscribe": "http://www.ietf.org/mailman/listinfo/dhcwg", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dhcwg/", "type": "wg", "name": "Dynamic Host Configuration"}}, +{"pk": 988, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "dhcwg@ietf.org", "acronym": "dhc", "comments": "", "list_subscribe": "http://www.ietf.org/mailman/listinfo/dhcwg", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dhcwg/", "type": "wg", "name": "Dynamic Host Configuration"}}, {"pk": 989, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-edi@byu.edu", "acronym": "edi", "comments": "1st IETF Meeting: Seattle: 94-03: BOF", "list_subscribe": "listserv@byu.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.sterling.com/edi/lists/ietf-edi", "type": "wg", "name": "Electronic Data Interchange"}}, {"pk": 990, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-ediint@imc.org", "acronym": "ediint", "comments": "1st meeting at 36th IETF - Montreal, Canada", "list_subscribe": "ietf-ediint-request@imc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.imc.org/ietf-ediint/", "type": "wg", "name": "Electronic Data Interchange-Internet Integration"}}, {"pk": 991, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "mailreq", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Email Requirements"}}, -{"pk": 992, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": 1193, "list_email": "", "acronym": "eii", "comments": "1st meeting San Jose, December 5-9, 1994 mw CANCELLED", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Emergency Information Infrastructure"}}, -{"pk": 993, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "eid", "comments": "1st meeting Toronto IETF. mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Endpoint Identifier"}}, +{"pk": 992, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "eii", "comments": "1st meeting San Jose, December 5-9, 1994 mw CANCELLED", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Emergency Information Infrastructure"}}, +{"pk": 993, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "eid", "comments": "1st meeting Toronto IETF. mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Endpoint Identifier"}}, {"pk": 994, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "entmib@ietf.org", "acronym": "entmib", "comments": "1st session 33rd IETF, Stockholm 17-21 July mw", "list_subscribe": "http://www.ietf.org/mailman/listinfo/entmib", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/entmib/", "type": "wg", "name": "Entity MIB"}}, -{"pk": 995, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "opera", "comments": "1st IETF Meeting: Seattle: 94-03: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Establishing a Forum for Operational Issues"}}, -{"pk": 996, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "enet_mib@ftp.com", "acronym": "ethermib", "comments": "to resolve the ethernet controversy....", "list_subscribe": "enet_mib-request@ftp.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Ethernet MIB"}}, -{"pk": 997, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "earthen", "comments": "1st meeting at 35th IETF - Los Angeles, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Explorations of Alternate Routing & Topology to He"}}, +{"pk": 995, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "opera", "comments": "1st IETF Meeting: Seattle: 94-03: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Establishing a Forum for Operational Issues"}}, +{"pk": 996, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1157, "list_email": "enet_mib@ftp.com", "acronym": "ethermib", "comments": "to resolve the ethernet controversy....", "list_subscribe": "enet_mib-request@ftp.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Ethernet MIB"}}, +{"pk": 997, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "earthen", "comments": "1st meeting at 35th IETF - Los Angeles, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Explorations of Alternate Routing & Topology to He"}}, {"pk": 998, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ftpext@ietf.org", "acronym": "ftpext", "comments": "Was a San Diego BOF", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ftpext", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ftpext/", "type": "wg", "name": "Extensions to FTP"}}, {"pk": 999, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "osiextnd", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Extensions to OSI for use in the Internet"}}, -{"pk": 1000, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "fddi-mib@CS.UTK.EDU", "acronym": "fddimib", "comments": "This working group is newly revived to work on the draft FDDI MIB. Concluded the first time on 8/1/91.", "list_subscribe": "fddi-mib-request@CS.UTK.EDU", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "FDDI MIB"}}, -{"pk": 1001, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 188, "parent": 1179, "list_email": "", "acronym": "wg2", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "File Transfer, Access and Management"}}, +{"pk": 1000, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1157, "list_email": "fddi-mib@CS.UTK.EDU", "acronym": "fddimib", "comments": "This working group is newly revived to work on the draft FDDI MIB. Concluded the first time on 8/1/91.", "list_subscribe": "fddi-mib-request@CS.UTK.EDU", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "FDDI MIB"}}, +{"pk": 1001, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1179, "list_email": "", "acronym": "wg2", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "File Transfer, Access and Management"}}, {"pk": 1002, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "frnetmib@sunroof.eng.sun.com", "acronym": "frnetmib", "comments": "Orig. conclude date: 3/18/94. reactivated 4/19/96", "list_subscribe": "majordomo@sunroof.eng.sun.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.ietf.org/ietf-mail-archive/frnetmib/", "type": "wg", "name": "Frame Relay Service MIB"}}, {"pk": 1003, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "pages", "comments": "1st IETF Meeting: Seattle: 94-03: BOF eventually became whip WG", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Framework for White Pages Service in the Internet"}}, {"pk": 1004, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "ftpftam", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "FTP-FTAM Gateway"}}, -{"pk": 1005, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 188, "parent": 1179, "list_email": "", "acronym": "wg5", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Full Screen Services"}}, +{"pk": 1005, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1179, "list_email": "", "acronym": "wg5", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Full Screen Services"}}, {"pk": 1006, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "fddifs", "comments": "1st meeting at 38th IETF - Memphis, TN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Future Directions for Differential Services"}}, {"pk": 1007, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "grip-wg@uu.net", "acronym": "grip", "comments": "1st meeting Toronto IETF 7/94. mw The 'G and R' stand for 'Guidelines and Recommendations'", "list_subscribe": "grip-wg-request@uu.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www-ext.eng.uu.net/grip-wg/grip-wg.txt", "type": "wg", "name": "G & R for Security Incident Processing"}}, {"pk": 1008, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 2, "list_email": "", "acronym": "gen", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-02-26 00:21:37", "unused_tags": [], "list_archive": "", "type": "area", "name": "General Area"}}, -{"pk": 1009, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": null, "list_email": "gisd-wg@ripe.net", "acronym": "gisd", "comments": "Bof in Amsterdam (Jul 93). Acronym WAS giss (Generic Internet Svs. Spec.) David replaced Daniel Karrenberg & Tony Bates 6/94 mw", "list_subscribe": "majordomo@ripe.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.ripe.net/ripe/archives/gisd-wg/current", "type": "wg", "name": "Generic Internet Service Description"}}, -{"pk": 1010, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "", "acronym": "gopher", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "GOPHER"}}, -{"pk": 1011, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2853, "parent": 1179, "list_email": "stdguide@midnight.com", "acronym": "stdguide", "comments": "Developed from prottest bof which met in Danvers. mw", "list_subscribe": "majordomo@midnight.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.midnight.com/pub/stdguide-archive", "type": "wg", "name": "Guide for Internet Standards Writers"}}, +{"pk": 1009, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "gisd-wg@ripe.net", "acronym": "gisd", "comments": "Bof in Amsterdam (Jul 93). Acronym WAS giss (Generic Internet Svs. Spec.) David replaced Daniel Karrenberg & Tony Bates 6/94 mw", "list_subscribe": "majordomo@ripe.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.ripe.net/ripe/archives/gisd-wg/current", "type": "wg", "name": "Generic Internet Service Description"}}, +{"pk": 1010, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "", "acronym": "gopher", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "GOPHER"}}, +{"pk": 1011, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1179, "list_email": "stdguide@midnight.com", "acronym": "stdguide", "comments": "Developed from prottest bof which met in Danvers. mw", "list_subscribe": "majordomo@midnight.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.midnight.com/pub/stdguide-archive", "type": "wg", "name": "Guide for Internet Standards Writers"}}, {"pk": 1012, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "guts", "comments": "1st meeting at 35th IETF - Los Angeles, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Guidelines for UDP and TCP Based Systems"}}, -{"pk": 1013, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "peering", "comments": "Scheduled on-site 31st IETF/San Jose (December 5-9, 1994) mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "High Speed 34 Megabit Atlantic Peering"}}, +{"pk": 1013, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "peering", "comments": "Scheduled on-site 31st IETF/San Jose (December 5-9, 1994) mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "High Speed 34 Megabit Atlantic Peering"}}, {"pk": 1014, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "hops", "comments": "1st meeting at 38th IETF - Memphis, TN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Host Proximity Service"}}, {"pk": 1015, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "ietf-hosts@NNSC.NSF.NET", "acronym": "hostreq", "comments": "", "list_subscribe": "ietf-hosts-request@NNSC.NSF.NET", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Host Requirements"}}, -{"pk": 1016, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "hostmib@andrew.cmu.edu", "acronym": "hostmib", "comments": "", "list_subscribe": "hostmib-request@andrew.cmu.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Host Resources MIB"}}, +{"pk": 1016, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1157, "list_email": "hostmib@andrew.cmu.edu", "acronym": "hostmib", "comments": "", "list_subscribe": "hostmib-request@andrew.cmu.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Host Resources MIB"}}, {"pk": 1017, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "httpsec", "comments": "Scheduled on-site at 31st IETF/San Jose (December 5-9, 1994) mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "HTTP Secure"}}, -{"pk": 1018, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "harts@isi.edu", "acronym": "harts", "comments": "This group was formed from the arts bof mw. A fake conclude msg sent 8/1. When last ID published, will conclude record.", "list_subscribe": "harts-request@isi.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://nfs/ftp/harts/harts.mail", "type": "wg", "name": "Humanities and Arts"}}, +{"pk": 1018, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "harts@isi.edu", "acronym": "harts", "comments": "This group was formed from the arts bof mw. A fake conclude msg sent 8/1. When last ID published, will conclude record.", "list_subscribe": "harts-request@isi.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://nfs/ftp/harts/harts.mail", "type": "wg", "name": "Humanities and Arts"}}, {"pk": 1019, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "www-html@w3.org", "acronym": "html", "comments": "", "list_subscribe": "www-html-request@w3.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ics.uci.edu/pub/ietf/html/", "type": "wg", "name": "HyperText Markup Language"}}, {"pk": 1020, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "http-wg@hplb.hp.com", "acronym": "http", "comments": "", "list_subscribe": "http-wg-request@hplb.hp.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ics.uci.edu/pub/ietf/http/hypermail", "type": "wg", "name": "HyperText Transfer Protocol"}}, -{"pk": 1021, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": null, "list_email": "", "acronym": "httpmib", "comments": "First meeting held at 35th IETF in Los Angeles, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "HyperText Transfer Protocol MIB"}}, -{"pk": 1022, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 6699, "parent": 1193, "list_email": "hubmib@ietf.org", "acronym": "hubmib", "comments": "Orig. Start: 7/1/91; End: 9/10/93. Restarted. mw", "list_subscribe": "hubmib-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/hubmib/", "type": "wg", "name": "Ethernet Interfaces and Hub MIB"}}, -{"pk": 1023, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 188, "parent": 1179, "list_email": "", "acronym": "ietfgrow", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IETF Growth"}}, -{"pk": 1024, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 188, "parent": null, "list_email": "", "acronym": "dnsevolv", "comments": "1st met as BOF at 34th IETF, Dallas 12/4-8 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IETF Role in DNS Evolution"}}, -{"pk": 1026, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": null, "list_email": "", "acronym": "emailmgt", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IFIP Electronic Mail Management"}}, -{"pk": 1027, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "none", "comments": "This is here so that 'none' can be entered in, for example, idform.", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "individ", "name": "Individual Submissions"}}, -{"pk": 1028, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 188, "parent": 1179, "list_email": "", "acronym": "wg-isus", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Informational Services and User Support"}}, -{"pk": 1029, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "check", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Installation Checklist"}}, +{"pk": 1021, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "httpmib", "comments": "First meeting held at 35th IETF in Los Angeles, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "HyperText Transfer Protocol MIB"}}, +{"pk": 1022, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "hubmib@ietf.org", "acronym": "hubmib", "comments": "Orig. Start: 7/1/91; End: 9/10/93. Restarted. mw", "list_subscribe": "hubmib-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/hubmib/", "type": "wg", "name": "Ethernet Interfaces and Hub MIB"}}, +{"pk": 1023, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1179, "list_email": "", "acronym": "ietfgrow", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IETF Growth"}}, +{"pk": 1024, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "dnsevolv", "comments": "1st met as BOF at 34th IETF, Dallas 12/4-8 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IETF Role in DNS Evolution"}}, +{"pk": 1026, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "emailmgt", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IFIP Electronic Mail Management"}}, +{"pk": 1027, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "none", "comments": "This is here so that 'none' can be entered in, for example, idform.", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "individ", "name": "Individual Submissions"}}, +{"pk": 1028, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1179, "list_email": "", "acronym": "wg-isus", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Informational Services and User Support"}}, +{"pk": 1029, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "check", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Installation Checklist"}}, {"pk": 1030, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-ids@umich.edu", "acronym": "ids", "comments": "Changed from USV to APPs on 4/12/95.", "list_subscribe": "ietf-ids-request@umich.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://terminator.rs.itd.umich.edu/ietf-ids/archive", "type": "wg", "name": "Integrated Directory Services"}}, {"pk": 1031, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "iia", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Integrated Information Architecture"}}, {"pk": 1032, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "", "acronym": "ipnni", "comments": "1st meeting at 35th IETF - Los Angeles, CA - March 1996", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Integrated PNNI"}}, {"pk": 1033, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "int-serv@isi.edu", "acronym": "intserv", "comments": "1st IETF Meeting: Seattle: 94-03: BOF.", "list_subscribe": "int-serv-request@isi.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.isi.edu/int-serv/int-serv.mail", "type": "wg", "name": "Integrated Services"}}, {"pk": 1034, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "isfoo", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Integrated Services over Foo"}}, {"pk": 1035, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "issll@mercury.lcs.mit.edu", "acronym": "issll", "comments": "", "list_subscribe": "issll-request@mercury.lcs.mit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://mercury.lcs.mit.edu/pub/issll/mail/", "type": "wg", "name": "Integrated Services over Specific Link Layers"}}, -{"pk": 1037, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "iiir@merit.edu", "acronym": "iiir", "comments": "Charter updated 1/29/93", "list_subscribe": "iiir-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://merit.edu/pub/iiir-archive", "type": "wg", "name": "Integration of Internet Information Resources"}}, -{"pk": 1038, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 188, "parent": 1179, "list_email": "intprop-wg@lm.com", "acronym": "intprop", "comments": "1st meeting San Jose, 31st IETF December 5-9, 1994 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Intellectual Property of the IETF"}}, +{"pk": 1037, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "iiir@merit.edu", "acronym": "iiir", "comments": "Charter updated 1/29/93", "list_subscribe": "iiir-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://merit.edu/pub/iiir-archive", "type": "wg", "name": "Integration of Internet Information Resources"}}, +{"pk": 1038, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1179, "list_email": "intprop-wg@lm.com", "acronym": "intprop", "comments": "1st meeting San Jose, 31st IETF December 5-9, 1994 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Intellectual Property of the IETF"}}, {"pk": 1039, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "idmr@cs.ucl.ac.uk", "acronym": "idmr", "comments": "Paul resigned just prior to 31st IETF. 12/5/94 mw", "list_subscribe": "idmr-request@cs.ucl.ac.uk", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.ietf.org/ietf-mail-archive/idmr/", "type": "wg", "name": "Inter-Domain Multicast Routing"}}, {"pk": 1040, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "idpr-wg@bbn.com", "acronym": "idpr", "comments": "", "list_subscribe": "idpr-wg-request@bbn.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Inter-Domain Policy Routing"}}, -{"pk": 1041, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2329, "parent": 1249, "list_email": "idr@ietf.org", "acronym": "idr", "comments": "This working group resulted from BGP and IPIDRP merging.", "list_subscribe": "idr-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/idr/", "type": "wg", "name": "Inter-Domain Routing"}}, -{"pk": 1042, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 188, "parent": 1324, "list_email": "", "acronym": "imm", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Interactive Multimedia"}}, +{"pk": 1041, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "idr@ietf.org", "acronym": "idr", "comments": "This working group resulted from BGP and IPIDRP merging.", "list_subscribe": "idr-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/idr/", "type": "wg", "name": "Inter-Domain Routing"}}, +{"pk": 1042, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "imm", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Interactive Multimedia"}}, {"pk": 1043, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "", "acronym": "iwg", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Interconnectivity Working Group"}}, {"pk": 1044, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "ifmib@ietf.org", "acronym": "ifmib", "comments": "Orig. Start: 5/13/93; End: 12/29/94. Restarted to elevate RFC to next status level.", "list_subscribe": "http://www.ietf.org/mailman/listinfo/ifmib", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://thumper.bellcore.com/pub/Group.archive/if-mib", "type": "wg", "name": "Interfaces MIB"}}, -{"pk": 1045, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2853, "parent": 1179, "list_email": "", "acronym": "iahc", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "International Ad Hoc Committee"}}, -{"pk": 1046, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 188, "parent": 1179, "list_email": "", "acronym": "inaparch", "comments": "1st meeting 31st IETF San Jose: December 1994 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "International Networking and the NAP Architecture"}}, -{"pk": 1047, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "accounting-wg@wugate.wustl.edu", "acronym": "acct", "comments": "", "list_subscribe": "accounting-wg-request@wugate.wustl.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet Accounting"}}, -{"pk": 1048, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": null, "list_email": "accounting-wg@wugate.wustl.edu", "acronym": "acct2", "comments": "1st met as BOF Seattle IETF, March 1994 mw", "list_subscribe": "accounting-wg-request@wugate.wustl.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet Accounting 2"}}, -{"pk": 1049, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "ioh", "comments": "1st met as BOF, 33rd IETF Stockholm 17-21 July 1995", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet and OSI Harmonisation"}}, -{"pk": 1050, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "iafa@cc.mcgill.ca", "acronym": "iafa", "comments": "", "list_subscribe": "iafa-request@cc.mcgill.ca", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "archive.cc.mcgill.ca:~/pub/mailing-lists/iafa-archive", "type": "wg", "name": "Internet Anonymous FTP Archives"}}, +{"pk": 1045, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1179, "list_email": "", "acronym": "iahc", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "International Ad Hoc Committee"}}, +{"pk": 1046, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1179, "list_email": "", "acronym": "inaparch", "comments": "1st meeting 31st IETF San Jose: December 1994 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "International Networking and the NAP Architecture"}}, +{"pk": 1047, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1157, "list_email": "accounting-wg@wugate.wustl.edu", "acronym": "acct", "comments": "", "list_subscribe": "accounting-wg-request@wugate.wustl.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet Accounting"}}, +{"pk": 1048, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "accounting-wg@wugate.wustl.edu", "acronym": "acct2", "comments": "1st met as BOF Seattle IETF, March 1994 mw", "list_subscribe": "accounting-wg-request@wugate.wustl.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet Accounting 2"}}, +{"pk": 1049, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ioh", "comments": "1st met as BOF, 33rd IETF Stockholm 17-21 July 1995", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet and OSI Harmonisation"}}, +{"pk": 1050, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "iafa@cc.mcgill.ca", "acronym": "iafa", "comments": "", "list_subscribe": "iafa-request@cc.mcgill.ca", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "archive.cc.mcgill.ca:~/pub/mailing-lists/iafa-archive", "type": "wg", "name": "Internet Anonymous FTP Archives"}}, {"pk": 1052, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 2, "list_email": "", "acronym": "int", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-02-26 00:21:37", "unused_tags": [], "list_archive": "", "type": "area", "name": "Internet Area"}}, {"pk": 1053, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "icp", "comments": "1st meeting at 37th IETF - San Jose", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet Cache Protocol"}}, {"pk": 1054, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-fax@imc.org", "acronym": "fax", "comments": "1st meeting at 37th IETF - San Jose, CA", "list_subscribe": "ietf-fax-request@imc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.imc.org/ietf-fax/", "type": "wg", "name": "Internet Fax"}}, @@ -212,29 +212,29 @@ {"pk": 1056, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "imp-interest@thumper.bellcore.com", "acronym": "imp", "comments": "", "list_subscribe": "imp-interest-request@thumper.bellcore.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "thumper.bellcore.com:pub/devetzis/imp/imp-archive", "type": "wg", "name": "Internet Mercantile Protocols"}}, {"pk": 1057, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "imap@cac.washington.edu", "acronym": "imap", "comments": "Originally met as Interactive Mail Access Protocol BOF. 93-07. Name changed 11/5/93 with Area Director approval. mw", "list_subscribe": "imap-request@cac.washington.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp.cac.washington.edu:~/imap/imap_archive", "type": "wg", "name": "Internet Message Access Protocol"}}, {"pk": 1058, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-822@dimacs.rutgers.edu", "acronym": "822ext", "comments": "", "list_subscribe": "ietf-822-request@dimacs.rutgers.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ietf.cnri.reston.va.us:~/ietf-mail-archive/822ext/*", "type": "wg", "name": "Internet Message Extensions"}}, -{"pk": 1059, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": 934, "list_email": "mib-wg@nnsc.nsf.net", "acronym": "mib", "comments": "", "list_subscribe": "mib-wg-request@nnsc.nsf.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet MIB"}}, -{"pk": 1060, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 188, "parent": null, "list_email": "", "acronym": "ima", "comments": "1st meeting Toronto IETF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet Middleware"}}, +{"pk": 1059, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "mib-wg@nnsc.nsf.net", "acronym": "mib", "comments": "", "list_subscribe": "mib-wg-request@nnsc.nsf.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet MIB"}}, +{"pk": 1060, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ima", "comments": "1st meeting Toronto IETF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet Middleware"}}, {"pk": 1061, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "rap@ops.ietf.org", "acronym": "rap", "comments": "1st Meeting at 37th IETF - San Jose, CA\r\nChanged from TSV to OPS on 11/23/99.", "list_subscribe": "rap-request@ops.ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "https://ops.ietf.org/lists/rap", "type": "wg", "name": "Resource Allocation Protocol"}}, {"pk": 1062, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ipp@pwg.org", "acronym": "ipp", "comments": "", "list_subscribe": "ipp-request@pwg.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.pwg.org/pub/pwg/ipp/", "type": "wg", "name": "Internet Printing Protocol"}}, -{"pk": 1063, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": null, "list_email": "ire@apnic.net", "acronym": "ire", "comments": "1st meeting at 36th IETF - Montreal, Canada", "list_subscribe": "ire-request@apnic.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.apnic.net/mailing-lists/ire", "type": "wg", "name": "Internet Registry Evolution"}}, -{"pk": 1064, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "isn-wg@nasa.gov", "acronym": "isn", "comments": "", "list_subscribe": "listmanager@nasa.gov", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet School Networking"}}, -{"pk": 1065, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "isn-wg@unmvma.unm.edu", "acronym": "isn2", "comments": "1st meeting 32nd IETF, Danvers, MA April 3-7, 1995, primarily for local teachers to attend. 3/17/95 mw", "list_subscribe": "listserv@unmvma.unm.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet School Networking 2"}}, +{"pk": 1063, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "ire@apnic.net", "acronym": "ire", "comments": "1st meeting at 36th IETF - Montreal, Canada", "list_subscribe": "ire-request@apnic.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.apnic.net/mailing-lists/ire", "type": "wg", "name": "Internet Registry Evolution"}}, +{"pk": 1064, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "isn-wg@nasa.gov", "acronym": "isn", "comments": "", "list_subscribe": "listmanager@nasa.gov", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet School Networking"}}, +{"pk": 1065, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "isn-wg@unmvma.unm.edu", "acronym": "isn2", "comments": "1st meeting 32nd IETF, Danvers, MA April 3-7, 1995, primarily for local teachers to attend. 3/17/95 mw", "list_subscribe": "listserv@unmvma.unm.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet School Networking 2"}}, {"pk": 1066, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "ietf-payments@cc.bellcore.com", "acronym": "ispp", "comments": "1st BOF meeting 33rd IETF/Stockholm 17-21 July 1995 mw", "list_subscribe": "majordomo@cc.bellcore.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.bellcore.com/pub/rubin/", "type": "wg", "name": "Internet Secure Payments Protocol"}}, {"pk": 1067, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "spwg@nri.reston.va.us", "acronym": "spwg", "comments": "", "list_subscribe": "spwg-request@nri.reston.va.us", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet Security Policy"}}, -{"pk": 1068, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 188, "parent": null, "list_email": "", "acronym": "isoc", "comments": "Mike Roberts led an isoc bof at the 28th IETF in Houston, November 1-5, 1993 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet Society Advisory Council"}}, +{"pk": 1068, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "isoc", "comments": "Mike Roberts led an isoc bof at the 28th IETF in Houston, November 1-5, 1993 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet Society Advisory Council"}}, {"pk": 1069, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "st@bbn.com", "acronym": "st2", "comments": "Lou Berger replaces Steve DeJarnett 6/28/94 mw", "list_subscribe": "st-request@bbn.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.bbn.com/pub/st/st-archive", "type": "wg", "name": "Internet Stream Protocol V2"}}, -{"pk": 1070, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "usergloss@xylogics.com", "acronym": "userglos", "comments": "Orig. Start: 12/02/90; End: 1/12/93. Restarted to elevate RFC to next status level. Meet at 33rd IETF in Stockholm.", "list_subscribe": "usergloss-request@xylogics.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://xylogics.com/pub/users/gmalkin/usergloss/usergloss-arc", "type": "wg", "name": "Internet User Glossary"}}, -{"pk": 1071, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "ietf@venera.isi.edu", "acronym": "iup", "comments": "", "list_subscribe": "ietf-request@venera.isi.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet User Population"}}, +{"pk": 1070, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "usergloss@xylogics.com", "acronym": "userglos", "comments": "Orig. Start: 12/02/90; End: 1/12/93. Restarted to elevate RFC to next status level. Meet at 33rd IETF in Stockholm.", "list_subscribe": "usergloss-request@xylogics.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://xylogics.com/pub/users/gmalkin/usergloss/usergloss-arc", "type": "wg", "name": "Internet User Glossary"}}, +{"pk": 1071, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "ietf@venera.isi.edu", "acronym": "iup", "comments": "", "list_subscribe": "ietf-request@venera.isi.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet User Population"}}, {"pk": 1072, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "wps@SURFnet.nl", "acronym": "whip", "comments": "Working group formed as result of pages BOF from Seattle in March 1994.", "list_subscribe": "wps-request@SURFnet.nl", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.es.net/pub/ietf/wps", "type": "wg", "name": "Internet White Pages Requirements"}}, {"pk": 1073, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "ion@sunroof.eng.sun.com", "acronym": "ion", "comments": "", "list_subscribe": "majordomo@sunroof.eng.sun.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.ietf.org/ietf-mail-archive/ion", "type": "wg", "name": "Internetworking Over NBMA"}}, {"pk": 1074, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "ip-encaps@sunroof.eng.sun.com", "acronym": "ipae", "comments": "", "list_subscribe": "ip-encaps-request@sunroof.eng.sun.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "parcftp.xerox.com:~/pub/ip-encaps/", "type": "wg", "name": "IP Address Encapsulation"}}, -{"pk": 1075, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "ipaddr", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IP Addressing Plan"}}, +{"pk": 1075, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ipaddr", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IP Addressing Plan"}}, {"pk": 1076, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ipacad", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IP Applications Over Cable Data Network"}}, {"pk": 1077, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "awg@bitsy.mit.edu", "acronym": "ipauth", "comments": "This WG has died an unnatural death.", "list_subscribe": "awg-request@bitsy.mit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IP Authentication"}}, {"pk": 1078, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "mtudwg@decwrl.dec.com", "acronym": "mtudisc", "comments": "", "list_subscribe": "mtudwg-request@decwrl.dec.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IP MTU Discovery"}}, {"pk": 1079, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "apple-ip@apple.com", "acronym": "appleip", "comments": "", "list_subscribe": "apple-ip-request@apple.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IP Over AppleTalk"}}, {"pk": 1080, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "ip-atm@matmos.hpl.hp.com", "acronym": "ipatm", "comments": "Combined with rolc to become ION", "list_subscribe": "majordomo@matmos.hpl.hp.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.hep.net/ftp/lists-archive/atm", "type": "wg", "name": "IP Over Asynchronous Transfer Mode"}}, -{"pk": 1081, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 6699, "parent": 1193, "list_email": "ipcdn@ietf.org", "acronym": "ipcdn", "comments": "", "list_subscribe": "http://www.ietf.org/mailman/listinfo/ipcdn", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipcdn/", "type": "wg", "name": "IP over Cable Data Network"}}, +{"pk": 1081, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "ipcdn@ietf.org", "acronym": "ipcdn", "comments": "", "list_subscribe": "http://www.ietf.org/mailman/listinfo/ipcdn", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipcdn/", "type": "wg", "name": "IP over Cable Data Network"}}, {"pk": 1082, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "FDDI@merit.edu", "acronym": "fddi", "comments": "", "list_subscribe": "FDDI-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IP Over FDDI"}}, {"pk": 1083, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "ipfc@standards.gadzoox.com", "acronym": "ipfc", "comments": "BOF met first in November 1992; second meeting Toronto 1994. Name changed from\r\nfibreip for the 41st IETF-Los Angeles", "list_subscribe": "ipfc-request@standards.gadzoox.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "standards.gadzoox.com/pub/archives/ipfc/ipfc", "type": "wg", "name": "IP over Fibre Channel"}}, {"pk": 1084, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "hippi-ietf@cray.com", "acronym": "hippi", "comments": "This is a placeholder for the IP over HIPPI internet draft", "list_subscribe": "hippi-ietf-request@cray.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IP Over HIPPI"}}, @@ -242,39 +242,39 @@ {"pk": 1086, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "iplpdn@cnri.reston.va.us", "acronym": "iplpdn", "comments": "", "list_subscribe": "iplpdn-request@cnri.reston.va.us", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ietf.cnri.reston.va.us:~/ietf-mail-archive/iplpdn/*", "type": "wg", "name": "IP Over Large Public Data Networks"}}, {"pk": 1087, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "smds@cnri.reston.va.us", "acronym": "smds", "comments": "", "list_subscribe": "smds-request@cnri.reston.va.us", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ietf.cnri.reston.va.us:~/ietf-mail-archive/iplpdn", "type": "wg", "name": "IP Over Switched Megabit Data Service"}}, {"pk": 1088, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "ippcp@external.cisco.com", "acronym": "ippcp", "comments": "Conclude message sent August 6, 1998.", "list_subscribe": "mailer@cisco.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp-eng.cisco.com/ippcp/ippcp", "type": "wg", "name": "IP Payload Compression Protocol"}}, -{"pk": 1089, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 110856, "parent": 1324, "list_email": "ippm@ietf.org", "acronym": "ippm", "comments": "1st meeting 32nd IETF Danvers, MA April 3-7, 1995 mw", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ippm", "state": "active", "time": "2012-11-27 10:42:51", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ippm/", "type": "wg", "name": "IP Performance Metrics"}}, +{"pk": 1089, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "ippm@ietf.org", "acronym": "ippm", "comments": "1st meeting 32nd IETF Danvers, MA April 3-7, 1995 mw", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ippm", "state": "active", "time": "2012-11-27 10:42:51", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ippm/", "type": "wg", "name": "IP Performance Metrics"}}, {"pk": 1090, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "mobile-ip@sunroof.eng.sun.com", "acronym": "mobileip", "comments": "Kannan replaced Deering as co-Chair 6/1/94. Li repl Minshall 10/12/94. Solomon repl Alagappan 3/10/95.Nordmark repl Li 6/7/96. Patil repl Solomon 4/6/99", "list_subscribe": "mobile-ip-request@sunroof.eng.sun.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://playground.sun.com/mobile-ip/", "type": "wg", "name": "IP Routing for Wireless/Mobile Hosts"}}, {"pk": 1091, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "ipsec@ietf.org", "acronym": "ipsec", "comments": "", "list_subscribe": "ipsec-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipsec/", "type": "wg", "name": "IP Security Protocol"}}, {"pk": 1092, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 2, "list_email": "", "acronym": "ipng", "comments": "This is an area with a specific charter. When IPng is 'over', this area will conclude.", "list_subscribe": "", "state": "unknown", "time": "2012-02-26 00:21:37", "unused_tags": [], "list_archive": "", "type": "area", "name": "IP: Next Generation Area"}}, {"pk": 1093, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "ipng@sunroof.eng.sun.com", "acronym": "ipngwg", "comments": "1st meeting Toronto IETF. mw This is to be *the* IPng Working Group, and this meeting as a BOF is its 'proto-WG' meeting. /jws", "list_subscribe": "majordomo@sunroof.eng.sun.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://playground.sun.com/pub/ipng/mail-archive", "type": "wg", "name": "IPNG"}}, {"pk": 1094, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ipdecide", "comments": "1st IETF Meeting: Amsterdam: 97-03: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPng Decision Process"}}, -{"pk": 1095, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "ngdir", "comments": "1st IETF MEETING: Seattle IETF: 94-03", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPNG Directorate"}}, -{"pk": 1096, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "ngreqs", "comments": "1st IETF Meeting: Seattle: 94-03: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPng Requirements"}}, +{"pk": 1095, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ngdir", "comments": "1st IETF MEETING: Seattle IETF: 94-03", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPNG Directorate"}}, +{"pk": 1096, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ngreqs", "comments": "1st IETF Meeting: Seattle: 94-03: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPng Requirements"}}, {"pk": 1097, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "6bone@isi.edu", "acronym": "6bonebof", "comments": "1st meeting at 36th IETF - Montreal, Canada", "list_subscribe": "majordomo@isi.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Transitions Planning"}}, {"pk": 1098, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "ip6mib@research.ftp.com", "acronym": "ipv6mib", "comments": "AD was Burgan", "list_subscribe": "ip6mib-request@research.ftp.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://research.ftp.com/pub/ip6mib/archive", "type": "wg", "name": "IPv6 MIB"}}, {"pk": 1099, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "nbmav6", "comments": "1st meeting at 35th IETF - Los Angeles, CA - March 1996", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPv6 over NBMA"}}, {"pk": 1100, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "", "acronym": "bigaddr", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPv7 Addressing"}}, {"pk": 1101, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-ircup@imc.org", "acronym": "ircup", "comments": "1st meeting at 38th IETF - Memphis, TN\r\n2nd meeting at 41st IETF - Los Angeles, CA", "list_subscribe": "http://www.imc.org/ietf-ircup", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.imc.org/ietf-ircup/mail-archive/", "type": "wg", "name": "IRC Update"}}, -{"pk": 1102, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 104198, "parent": 1249, "list_email": "isis-wg@ietf.org", "acronym": "isis", "comments": "ISIS-wg now hosted at IETF site.", "list_subscribe": "isis-wg-request@ietf.org", "state": "active", "time": "2012-06-14 12:06:58", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/isis-wg/", "type": "wg", "name": "IS-IS for IP Internets"}}, +{"pk": 1102, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "isis-wg@ietf.org", "acronym": "isis", "comments": "ISIS-wg now hosted at IETF site.", "list_subscribe": "isis-wg-request@ietf.org", "state": "active", "time": "2012-06-14 12:06:58", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/isis-wg/", "type": "wg", "name": "IS-IS for IP Internets"}}, {"pk": 1103, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "isdn-mib@cisco.com", "acronym": "isdnmib", "comments": "1st meeting 32nd IETF, Danvers, MA 1/18/95 mw (BOF) List 'owner': owner-isdn-mib@cisco.com\r\n\r\nAD was Jeff Burgan", "list_subscribe": "isdn-mib-request@cisco.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp-eng.cisco.com/ftp/isdn-mib/isdn-mib", "type": "wg", "name": "ISDN MIB"}}, -{"pk": 1104, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": 1193, "list_email": "njm@merit.edu", "acronym": "jomann", "comments": "", "list_subscribe": "njm-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Joint Monitoring Access for Adjacent Networks NSF"}}, -{"pk": 1105, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "lanmanwg@cnd.hp.com", "acronym": "lanman", "comments": "Microsoft took back control of the Lan Manager protocol and MIB. There is no further work for the working group.", "list_subscribe": "lanmanwg-request@cnd.hp.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "LAN Manager"}}, +{"pk": 1104, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "njm@merit.edu", "acronym": "jomann", "comments": "", "list_subscribe": "njm-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Joint Monitoring Access for Adjacent Networks NSF"}}, +{"pk": 1105, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1157, "list_email": "lanmanwg@cnd.hp.com", "acronym": "lanman", "comments": "Microsoft took back control of the Lan Manager protocol and MIB. There is no further work for the working group.", "list_subscribe": "lanmanwg-request@cnd.hp.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "LAN Manager"}}, {"pk": 1106, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "lsma@gmu.edu", "acronym": "lsma", "comments": "", "list_subscribe": "lsma-request@gmu.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Large Scale Multicast Applications"}}, {"pk": 1107, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "lsthdr", "comments": "1st meeting at 38th IETF - Memphis", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Listheader"}}, -{"pk": 1108, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "", "acronym": "livdoc", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Living Documents"}}, -{"pk": 1109, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "", "acronym": "loip", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Low Cost IP Hardware Wish List"}}, -{"pk": 1110, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 188, "parent": 1179, "list_email": "", "acronym": "wg-llt", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Lower Layers Technology"}}, +{"pk": 1108, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "", "acronym": "livdoc", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Living Documents"}}, +{"pk": 1109, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "", "acronym": "loip", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Low Cost IP Hardware Wish List"}}, +{"pk": 1110, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1179, "list_email": "", "acronym": "wg-llt", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Lower Layers Technology"}}, {"pk": 1111, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "madman@innosoft.com", "acronym": "madman", "comments": "Orig End 1/11/94. Reactivated for Dallas IETF as Applications Area WG.", "list_subscribe": "mailserv@innosoft.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://innosoft.com/anon/files/ietf-madman/archive.digest", "type": "wg", "name": "Mail and Directory Management"}}, -{"pk": 1112, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 188, "parent": 934, "list_email": "", "acronym": "wg-msg", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Mail and Messaging"}}, +{"pk": 1112, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "wg-msg", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Mail and Messaging"}}, {"pk": 1113, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "mailext@list.cren.net", "acronym": "mailext", "comments": "1st meeting 30th IETF, Toronto July 1994 BOF mw.", "list_subscribe": "listproc@list.cren.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Mail Extensions"}}, -{"pk": 1114, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2744, "parent": null, "list_email": "", "acronym": "mailftp", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Mail-based File Distribution"}}, -{"pk": 1115, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 188, "parent": 1179, "list_email": "", "acronym": "wg8", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Management of Network Application Services"}}, -{"pk": 1116, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "msiwg@decwrl.dec.com", "acronym": "msi", "comments": "Took the better part of valor", "list_subscribe": "msiwg-request@decwrl.dec.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Management Services Interface"}}, -{"pk": 1117, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": null, "list_email": "", "acronym": "atmmib", "comments": "Bacame the atommib WG after the Boston Meeting.", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Managing ATM with SNMP"}}, -{"pk": 1118, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 101568, "parent": 1193, "list_email": "mboned@ietf.org", "acronym": "mboned", "comments": "AD was Harald", "list_subscribe": "https://www.ietf.org/mailman/listinfo/mboned", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mboned", "type": "wg", "name": "MBONE Deployment"}}, -{"pk": 1119, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "mboneng", "comments": "1st meeting BOF: 34th IETF: Dallas, TX December 4-8, 1995 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "MBone Engineering"}}, -{"pk": 1120, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "mbone", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "MBONE Engineering and Operations"}}, -{"pk": 1121, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 188, "parent": 1179, "list_email": "", "acronym": "wg1", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Message Handeling Systems"}}, +{"pk": 1114, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "mailftp", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Mail-based File Distribution"}}, +{"pk": 1115, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1179, "list_email": "", "acronym": "wg8", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Management of Network Application Services"}}, +{"pk": 1116, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1157, "list_email": "msiwg@decwrl.dec.com", "acronym": "msi", "comments": "Took the better part of valor", "list_subscribe": "msiwg-request@decwrl.dec.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Management Services Interface"}}, +{"pk": 1117, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "atmmib", "comments": "Bacame the atommib WG after the Boston Meeting.", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Managing ATM with SNMP"}}, +{"pk": 1118, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "mboned@ietf.org", "acronym": "mboned", "comments": "AD was Harald", "list_subscribe": "https://www.ietf.org/mailman/listinfo/mboned", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mboned", "type": "wg", "name": "MBONE Deployment"}}, +{"pk": 1119, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "mboneng", "comments": "1st meeting BOF: 34th IETF: Dallas, TX December 4-8, 1995 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "MBone Engineering"}}, +{"pk": 1120, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "mbone", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "MBONE Engineering and Operations"}}, +{"pk": 1121, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1179, "list_email": "", "acronym": "wg1", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Message Handeling Systems"}}, {"pk": 1122, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "msp", "comments": "1st meeting at Los Angeles IETF, 35th IETF, March 1996", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Message Security Protocol"}}, {"pk": 1123, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "mhs-ds@mercury.udev.cdc.com", "acronym": "mhsds", "comments": "Moved from SAP to APP on 10 May 1994 by JWS>", "list_subscribe": "mhs-ds-request@mercury.udev.cdc.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "mercury.udev.cdc.com:~/pub/archives/mhs-ds-archive", "type": "wg", "name": "MHS-DS"}}, {"pk": 1124, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-mixer@innosoft.com", "acronym": "mixer", "comments": "Danvers IETF, April 3-7, 1995 (closed session)", "list_subscribe": "mailserv@innosoft.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.innosoft.com/ietf-mixer/", "type": "wg", "name": "MIME - X.400 Gateway"}}, @@ -285,52 +285,52 @@ {"pk": 1129, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "pgpmime", "comments": "1st Meeting at 37th IETF - San Jose", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "MIME Security with Pretty Good Privacy"}}, {"pk": 1130, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "mime-mhs@surfnet.nl", "acronym": "mimemhs", "comments": "", "list_subscribe": "mime-mhs-request@surfnet.nl", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "MIME-MHS Interworking"}}, {"pk": 1131, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "thinosi@ulcc.ac.uk", "acronym": "thinosi", "comments": "Moved from SAP to TSV on 10 May 1994 by JWS.", "list_subscribe": "thinosi-request@ulcc.ac.uk", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "pluto.ulcc.ac.uk:/ulcc/thinosi/thinosi-mail-archive.txt", "type": "wg", "name": "Minimal OSI Upper-Layers"}}, -{"pk": 1132, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 104198, "parent": 1249, "list_email": "manet@ietf.org", "acronym": "manet", "comments": "", "list_subscribe": "manet-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/manet/", "type": "wg", "name": "Mobile Ad-hoc Networks"}}, +{"pk": 1132, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "manet@ietf.org", "acronym": "manet", "comments": "", "list_subscribe": "manet-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/manet/", "type": "wg", "name": "Mobile Ad-hoc Networks"}}, {"pk": 1133, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "mmnet@itd.nrl.navy.mil", "acronym": "mmnet", "comments": "1st met as BOF, 34th IETF: Dallas, Tx December 4-8, 1995 mw", "list_subscribe": "majordomo@itd.nrl.navy.mil", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://mars.itd.nrl.navy.mil/pub/mmnet", "type": "wg", "name": "Mobile Mesh Networks"}}, -{"pk": 1134, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "modemmgt@Telebit.com", "acronym": "modemmgt", "comments": "", "list_subscribe": "majordomo@Telebit.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp.telebit.com:~/pub/modemmgt", "type": "wg", "name": "Modem Management"}}, +{"pk": 1134, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1157, "list_email": "modemmgt@Telebit.com", "acronym": "modemmgt", "comments": "", "list_subscribe": "majordomo@Telebit.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp.telebit.com:~/pub/modemmgt", "type": "wg", "name": "Modem Management"}}, {"pk": 1135, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "mmbwg@fibercom.com", "acronym": "mmb", "comments": "", "list_subscribe": "mmbwg-request@fibercom.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Multi-Media Bridging"}}, {"pk": 1136, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "mospf@gated.cornell.edu", "acronym": "mospf", "comments": "", "list_subscribe": "mospf-request@gated.cornell.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Multicast Extensions to OSPF"}}, {"pk": 1137, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "mcwww", "comments": "1st meeting at 38th IETF - Memphis, TN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Multicast WWW"}}, -{"pk": 1138, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "mmusic@ietf.org", "acronym": "mmusic", "comments": "", "list_subscribe": "mmusic-request@ietf.org", "state": "active", "time": "2013-01-11 09:15:28", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mmusic/", "type": "wg", "name": "Multiparty Multimedia Session Control"}}, -{"pk": 1139, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": null, "list_email": "", "acronym": "mplxmib", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Multiplexing SNMP Agents BOF"}}, -{"pk": 1140, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 104198, "parent": 1249, "list_email": "mpls@ietf.org", "acronym": "mpls", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/mpls", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mpls/", "type": "wg", "name": "Multiprotocol Label Switching"}}, +{"pk": 1138, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "mmusic@ietf.org", "acronym": "mmusic", "comments": "", "list_subscribe": "mmusic-request@ietf.org", "state": "active", "time": "2013-01-11 09:15:28", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mmusic/", "type": "wg", "name": "Multiparty Multimedia Session Control"}}, +{"pk": 1139, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "mplxmib", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Multiplexing SNMP Agents BOF"}}, +{"pk": 1140, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "mpls@ietf.org", "acronym": "mpls", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/mpls", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mpls/", "type": "wg", "name": "Multiprotocol Label Switching"}}, {"pk": 1141, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "mptrans", "comments": "1st meeting 31st IETF (December 5-9, 1994/San Jose) mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Multiprotocol Transport"}}, {"pk": 1142, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "napmime", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "NAPLPS Graphics and Character Sets as a MIME"}}, {"pk": 1143, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "nasreqng", "comments": "1st meeting at 42nd IETF - Chicago, IL; 2nd meeting at 43rd IETF - Orlando, FL\r\nAD was Harald", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Next Generation Network Access Server Requirements"}}, {"pk": 1145, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "rtqos", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Net Support for QOS and Real-Time Traffic"}}, -{"pk": 1146, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "", "acronym": "abby", "comments": "1st meeting Toronto IETF (30th), Martyne Hallgren chaired. mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Netiquette"}}, +{"pk": 1146, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "", "acronym": "abby", "comments": "1st meeting Toronto IETF (30th), Martyne Hallgren chaired. mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Netiquette"}}, {"pk": 1147, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "nasreq@ops.ietf.org", "acronym": "nasreq", "comments": "Ostart: 14jul92,concluded 7mar95.", "list_subscribe": "nasreq-request@ops.ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://ops.ietf.org/lists/nasreq/", "type": "wg", "name": "Network Access Server Requirements"}}, {"pk": 1148, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "nat@ietf.org", "acronym": "nat", "comments": "", "list_subscribe": "nat-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.ietf.org/ietf-mail-archive/nat/", "type": "wg", "name": "Network Address Translators"}}, -{"pk": 1149, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 188, "parent": 1179, "list_email": "", "acronym": "wg-nap", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Applications Support"}}, -{"pk": 1150, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2744, "parent": 934, "list_email": "ietf-ndb@ucdavis.edu", "acronym": "netdata", "comments": "", "list_subscribe": "ietf-ndb-request@ucdavis.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Database"}}, +{"pk": 1149, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1179, "list_email": "", "acronym": "wg-nap", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Applications Support"}}, +{"pk": 1150, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-ndb@ucdavis.edu", "acronym": "netdata", "comments": "", "list_subscribe": "ietf-ndb-request@ucdavis.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Database"}}, {"pk": 1151, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "netfax@stubbs.ucop.edu", "acronym": "netfax", "comments": "", "list_subscribe": "netfax-request@stubbs.ucop.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "/pub/netfax@stubbs.ucop.edu", "type": "wg", "name": "Network Fax"}}, -{"pk": 1152, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 105519, "parent": 1324, "list_email": "nfsv4@ietf.org", "acronym": "nfsv4", "comments": "1st meeting at 37th IETF - San Jose, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/nfsv4", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/nfsv4/", "type": "wg", "name": "Network File System Version 4"}}, +{"pk": 1152, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "nfsv4@ietf.org", "acronym": "nfsv4", "comments": "1st meeting at 37th IETF - San Jose, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/nfsv4", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/nfsv4/", "type": "wg", "name": "Network File System Version 4"}}, {"pk": 1153, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "netgraph@nri.reston.va.us", "acronym": "netgraph", "comments": "", "list_subscribe": "netgraph-request@nri.reston.va.us", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Graphics"}}, -{"pk": 1154, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "nisi@merit.edu", "acronym": "nisi", "comments": "Pat Smith resigned as co-chair in April 1994 mw", "list_subscribe": "nisi-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Information Services Infrastructure"}}, -{"pk": 1155, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": 1193, "list_email": "njm@merit.edu", "acronym": "njm", "comments": "", "list_subscribe": "njm-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Joint Management"}}, -{"pk": 1156, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 188, "parent": null, "list_email": "", "acronym": "x3s3.3", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Level Standards"}}, +{"pk": 1154, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "nisi@merit.edu", "acronym": "nisi", "comments": "Pat Smith resigned as co-chair in April 1994 mw", "list_subscribe": "nisi-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Information Services Infrastructure"}}, +{"pk": 1155, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "njm@merit.edu", "acronym": "njm", "comments": "", "list_subscribe": "njm-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Joint Management"}}, +{"pk": 1156, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "x3s3.3", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Level Standards"}}, {"pk": 1157, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 2, "list_email": "", "acronym": "mgt", "comments": "", "list_subscribe": "", "state": "unknown", "time": "2012-02-26 00:21:37", "unused_tags": [], "list_archive": "", "type": "area", "name": "Network Management Area"}}, -{"pk": 1158, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": null, "list_email": "", "acronym": "nmarea", "comments": "formerly met as the SNMP Network Management Directorate", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Management Area Open Meeting"}}, +{"pk": 1158, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "nmarea", "comments": "formerly met as the SNMP Network Management Directorate", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Management Area Open Meeting"}}, {"pk": 1159, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-nntp@turbo.bio.net", "acronym": "nntp", "comments": "", "list_subscribe": "ietf-nntp-request@turbo.bio.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network News Transport Protocol"}}, -{"pk": 1160, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 188, "parent": 1179, "list_email": "", "acronym": "wg-nop", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Operations"}}, -{"pk": 1161, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 188, "parent": 1179, "list_email": "", "acronym": "wg4", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Operations and X.25"}}, -{"pk": 1162, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": 1199, "list_email": "noop@merit.edu", "acronym": "noop", "comments": "", "list_subscribe": "noop-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "merit.edu:~/pub/noop-archive", "type": "wg", "name": "Network OSI Operations"}}, -{"pk": 1163, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2744, "parent": 934, "list_email": "print-wg@pa.dec.com", "acronym": "npp", "comments": "", "list_subscribe": "print-wg-request@pa.dec.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Printing Protocol"}}, -{"pk": 1164, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": 1193, "list_email": "njm@merit.edu", "acronym": "netstat", "comments": "", "list_subscribe": "njm-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Status Reports"}}, -{"pk": 1165, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "network-training-tf@mailbase.ac.uk", "acronym": "trainmat", "comments": "", "list_subscribe": "mailbase@mailbase.ac.uk", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://mailbase.ac.uk/pub/lists/network-training-tf/archives/", "type": "wg", "name": "Network Training Materials"}}, -{"pk": 1166, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "nir@mailbase.ac.uk", "acronym": "nir", "comments": "", "list_subscribe": "mailbase@mailbase.ac.uk", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "mailbase.ac.uk:~/pub/nir", "type": "wg", "name": "Networked Information Retrieval"}}, +{"pk": 1160, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1179, "list_email": "", "acronym": "wg-nop", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Operations"}}, +{"pk": 1161, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1179, "list_email": "", "acronym": "wg4", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Operations and X.25"}}, +{"pk": 1162, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1199, "list_email": "noop@merit.edu", "acronym": "noop", "comments": "", "list_subscribe": "noop-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "merit.edu:~/pub/noop-archive", "type": "wg", "name": "Network OSI Operations"}}, +{"pk": 1163, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "print-wg@pa.dec.com", "acronym": "npp", "comments": "", "list_subscribe": "print-wg-request@pa.dec.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Printing Protocol"}}, +{"pk": 1164, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "njm@merit.edu", "acronym": "netstat", "comments": "", "list_subscribe": "njm-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Status Reports"}}, +{"pk": 1165, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "network-training-tf@mailbase.ac.uk", "acronym": "trainmat", "comments": "", "list_subscribe": "mailbase@mailbase.ac.uk", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://mailbase.ac.uk/pub/lists/network-training-tf/archives/", "type": "wg", "name": "Network Training Materials"}}, +{"pk": 1166, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "nir@mailbase.ac.uk", "acronym": "nir", "comments": "", "list_subscribe": "mailbase@mailbase.ac.uk", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "mailbase.ac.uk:~/pub/nir", "type": "wg", "name": "Networked Information Retrieval"}}, {"pk": 1167, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "multiapp", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Networking Multimedia Applications"}}, {"pk": 1168, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "nimrod-wg@bbn.com", "acronym": "nimrod", "comments": "1st IETF Meeting: Santa Fe: 91-11: BOF", "list_subscribe": "nimrod-wg-request@bbn.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://bbn.com/pub/nimrod-wg/nimrod-wg.archive", "type": "wg", "name": "New Internet Routing and Addressing Architecture"}}, {"pk": 1169, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "nttcp", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "New Technology TCP"}}, -{"pk": 1170, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "newdom", "comments": "1st meeting at 37th IETF - San Jose", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "New Top Level Domains"}}, -{"pk": 1171, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": null, "list_email": "nosi@sunroof.eng.sun.com", "acronym": "nosi", "comments": "1st meeting, San Jose December 5-9, 1994 mw", "list_subscribe": "majordomo@sunroof.eng.sun.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Next Generation and OSI"}}, -{"pk": 1172, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2853, "parent": 1179, "list_email": "", "acronym": "newgen", "comments": "1st meeting at 37th IETF - San Jose, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Next Generation Internet Initiative"}}, +{"pk": 1170, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "newdom", "comments": "1st meeting at 37th IETF - San Jose", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "New Top Level Domains"}}, +{"pk": 1171, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "nosi@sunroof.eng.sun.com", "acronym": "nosi", "comments": "1st meeting, San Jose December 5-9, 1994 mw", "list_subscribe": "majordomo@sunroof.eng.sun.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Next Generation and OSI"}}, +{"pk": 1172, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1179, "list_email": "", "acronym": "newgen", "comments": "1st meeting at 37th IETF - San Jose, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Next Generation Internet Initiative"}}, {"pk": 1173, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "tcpng", "comments": "1st meeting December 1994 IETF, San Jose. mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Next Generation TCP"}}, {"pk": 1174, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "ngtrans@sunroof.eng.sun.com", "acronym": "ngtrans", "comments": "1st meeting 31st IETF, San Jose 5-9 December 1994 BOF mw.", "list_subscribe": "majordomo@sunroof.eng.sun.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.ietf.org/ietf-mail-archive/ngtrans/", "type": "wg", "name": "Next Generation Transition"}}, -{"pk": 1175, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2744, "parent": null, "list_email": "", "acronym": "onc", "comments": "1st IETF Meeting: Amsterdam: 93-07: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "NFS and ONC IETF Standards Effort"}}, +{"pk": 1175, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "onc", "comments": "1st IETF Meeting: Amsterdam: 93-07: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "NFS and ONC IETF Standards Effort"}}, {"pk": 1176, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-nntp@lists.eyrie.org", "acronym": "nntpext", "comments": "WG Information: http://www.academ.com/academ/nntp/ietf.html", "list_subscribe": "http://lists.eyrie.org/mailman/listinfo/ietf-nntp", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.eyrie.org/pipermail/ietf-nntp/", "type": "wg", "name": "NNTP Extensions"}}, -{"pk": 1177, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "noctools@merit.edu", "acronym": "noctool2", "comments": "", "list_subscribe": "noctools-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "NOC-Tool Catalogue Revisions"}}, -{"pk": 1178, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "noctools@merit.edu", "acronym": "noctools", "comments": "", "list_subscribe": "noctools-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "NOC-Tools"}}, +{"pk": 1177, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "noctools@merit.edu", "acronym": "noctool2", "comments": "", "list_subscribe": "noctools-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "NOC-Tool Catalogue Revisions"}}, +{"pk": 1178, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "noctools@merit.edu", "acronym": "noctools", "comments": "", "list_subscribe": "noctools-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "NOC-Tools"}}, {"pk": 1179, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 2, "list_email": "", "acronym": "adm", "comments": "", "list_subscribe": "", "state": "unknown", "time": "2012-02-26 00:21:37", "unused_tags": [], "list_archive": "", "type": "area", "name": "ops"}}, {"pk": 1180, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "notifications@cs.utk.edu", "acronym": "notary", "comments": "", "list_subscribe": "notifications-request@cs.utk.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Notifications and Acknowledgements Requirements"}}, {"pk": 1182, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ios", "comments": "1st meeting San Jose 12/94: mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Object/Document Security"}}, @@ -338,67 +338,67 @@ {"pk": 1184, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "oncrpc-wg@sunroof.eng.sun.com", "acronym": "oncrpc", "comments": "1st IETF Meeting: Seattle: 94-03: WG. Moved from SAP to TSV on 10 May 1994 by JWS.", "list_subscribe": "oncrpc-wg-request@sunroof.eng.sun.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://playground.sun.com/pub/oncrpc", "type": "wg", "name": "ONC Remote Procedure Call"}}, {"pk": 1185, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "ietf-otp@research.telcordia.com", "acronym": "otp", "comments": "Met as skey BOF in Danvers.", "list_subscribe": "ietf-otp-request@research.telcordia.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.research.telcordia.com/pub/ietf-otp/archive", "type": "wg", "name": "One Time Password Authentication"}}, {"pk": 1186, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "odvigp@rutgers.edu", "acronym": "odv", "comments": "", "list_subscribe": "odvigp-request@rutgers.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Open Distance Vector IGP"}}, -{"pk": 1187, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "saag@mit.edu", "acronym": "saag", "comments": "6/7/94 Jeff Schiller closed to form Security Area Directorate. 10/94 Jeff want SAAG for open meeting, SECDIR for closed. mw", "list_subscribe": "saag-request@mit.edu", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ag", "name": "Security Area Open Meeting"}}, -{"pk": 1188, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2329, "parent": 1249, "list_email": "ospf@ietf.org", "acronym": "ospf", "comments": "Additional Working Group Site: http://rtg.ietf.org/ospf/", "list_subscribe": "ospf-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ospf/", "type": "wg", "name": "Open Shortest Path First IGP"}}, +{"pk": 1187, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "saag@mit.edu", "acronym": "saag", "comments": "6/7/94 Jeff Schiller closed to form Security Area Directorate. 10/94 Jeff want SAAG for open meeting, SECDIR for closed. mw", "list_subscribe": "saag-request@mit.edu", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ag", "name": "Security Area Open Meeting"}}, +{"pk": 1188, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "ospf@ietf.org", "acronym": "ospf", "comments": "Additional Working Group Site: http://rtg.ietf.org/ospf/", "list_subscribe": "ospf-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ospf/", "type": "wg", "name": "Open Shortest Path First IGP"}}, {"pk": 1189, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "otsv", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Open Transport Area Meeting"}}, {"pk": 1190, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 2, "list_email": "", "acronym": "ops-old", "comments": "", "list_subscribe": "", "state": "unknown", "time": "2012-02-26 00:21:37", "unused_tags": [], "list_archive": "", "type": "area", "name": "Operational Requirements Area"}}, -{"pk": 1191, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": null, "list_email": "orad@sdsc.edu", "acronym": "orad", "comments": "", "list_subscribe": "orad-request@sdsc.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Operational Requirements Area Directorate"}}, -{"pk": 1192, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": 1193, "list_email": "oswg-l@wugate.wustl.edu", "acronym": "opstat", "comments": "Henry and Nevil replaced Phill Gross and Bernhard Stockman as chairs", "list_subscribe": "oswg-l-request@wugate.wustl.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://wuarchive.wustl.edu/doc/mailing-lists/oswg-l", "type": "wg", "name": "Operational Statistics"}}, +{"pk": 1191, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "orad@sdsc.edu", "acronym": "orad", "comments": "", "list_subscribe": "orad-request@sdsc.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Operational Requirements Area Directorate"}}, +{"pk": 1192, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "oswg-l@wugate.wustl.edu", "acronym": "opstat", "comments": "Henry and Nevil replaced Phill Gross and Bernhard Stockman as chairs", "list_subscribe": "oswg-l-request@wugate.wustl.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://wuarchive.wustl.edu/doc/mailing-lists/oswg-l", "type": "wg", "name": "Operational Statistics"}}, {"pk": 1193, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 2, "list_email": "", "acronym": "ops", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-02-26 00:21:37", "unused_tags": [], "list_archive": "", "type": "area", "name": "Operations and Management Area"}}, {"pk": 1194, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "omarea", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Operations and Management Open Area Meeting"}}, {"pk": 1195, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "dce", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "OSF Distributed Computing Environment"}}, {"pk": 1196, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-osi-ds@cs.ucl.ac.uk", "acronym": "osids", "comments": "", "list_subscribe": "ietf-osi-ds-request@cs.ucl.ac.uk", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "OSI Directory Services"}}, -{"pk": 1197, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2372, "parent": 1199, "list_email": "ietf-osi@cs.wisc.edu", "acronym": "osigen", "comments": "", "list_subscribe": "ietf-osi-request@cs.wisc.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "janeb.cs.wisc.edu:/pub/archives/ietf-osi", "type": "wg", "name": "OSI General"}}, +{"pk": 1197, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1199, "list_email": "ietf-osi@cs.wisc.edu", "acronym": "osigen", "comments": "", "list_subscribe": "ietf-osi-request@cs.wisc.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "janeb.cs.wisc.edu:/pub/archives/ietf-osi", "type": "wg", "name": "OSI General"}}, {"pk": 1198, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "idrp-for-ip@merit.edu", "acronym": "ipidrp", "comments": "IPIDRP merged with BGP to make IDR.", "list_subscribe": "idrp-for-ip-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "merit.edu:~/pub/archive/idrp", "type": "wg", "name": "OSI IDRP for IP Over IP"}}, {"pk": 1199, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 2, "list_email": "", "acronym": "osi", "comments": "", "list_subscribe": "", "state": "unknown", "time": "2012-02-26 00:21:37", "unused_tags": [], "list_archive": "", "type": "area", "name": "OSI Integration Area"}}, -{"pk": 1200, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "oim@mbunix.mitre.org", "acronym": "oim", "comments": "", "list_subscribe": "oim-request@mbunix.mitre.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "OSI Internet Management"}}, -{"pk": 1201, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2372, "parent": null, "list_email": "", "acronym": "ositrans", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "OSI Transition"}}, +{"pk": 1200, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1157, "list_email": "oim@mbunix.mitre.org", "acronym": "oim", "comments": "", "list_subscribe": "oim-request@mbunix.mitre.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "OSI Internet Management"}}, +{"pk": 1201, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ositrans", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "OSI Transition"}}, {"pk": 1202, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1199, "list_email": "skinstak@ulcc.ac.uk", "acronym": "skinstak", "comments": "Replaced by the Thinosi WG.", "list_subscribe": "skinstak-request@ulcc.ac.uk", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ulcc/skinstak@ulcc.ac.uk", "type": "wg", "name": "OSI Upper-Layer Communications for Applications"}}, -{"pk": 1203, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2372, "parent": 1199, "list_email": "ietf-osi-x400@cs.wisc.edu", "acronym": "osix400", "comments": "Superceded by the X.400 Operations working group (x400ops)", "list_subscribe": "ietf-osi-x400-request@cs.wisc.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "janeb.cs.wisc.edu:/pub/archives/ietf-osi-x400", "type": "wg", "name": "OSI X.400"}}, -{"pk": 1204, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": 1052, "list_email": "pip@thumper.bellcore.com", "acronym": "pip", "comments": "Merged with sip to become the sipp working group.", "list_subscribe": "pip-request@thumper.bellcore.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "thumper.bellcore.com:~/pub/tsuchiya/pip-archive", "type": "wg", "name": "P. Internet Protocol"}}, +{"pk": 1203, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1199, "list_email": "ietf-osi-x400@cs.wisc.edu", "acronym": "osix400", "comments": "Superceded by the X.400 Operations working group (x400ops)", "list_subscribe": "ietf-osi-x400-request@cs.wisc.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "janeb.cs.wisc.edu:/pub/archives/ietf-osi-x400", "type": "wg", "name": "OSI X.400"}}, +{"pk": 1204, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "pip@thumper.bellcore.com", "acronym": "pip", "comments": "Merged with sip to become the sipp working group.", "list_subscribe": "pip-request@thumper.bellcore.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "thumper.bellcore.com:~/pub/tsuchiya/pip-archive", "type": "wg", "name": "P. Internet Protocol"}}, {"pk": 1205, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "pktway@isi.edu", "acronym": "pktway", "comments": "Was names MessageWay (msgway). Changed to PacketWay (pktway) on 8/28/96.", "list_subscribe": "http://WWW.ERC.MsState.Edu/packetway/mail-list.html", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.isi.edu/pktway/pktway.mail", "type": "wg", "name": "PacketWay"}}, {"pk": 1206, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "ietf-perf@gateway.mitre.org", "acronym": "pcc", "comments": "", "list_subscribe": "ietf-perf-request@gateway.mitre.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Performance and Congestion Control"}}, -{"pk": 1207, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 188, "parent": null, "list_email": "", "acronym": "nsfnet", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Perspectives on the Next Generation of the NSFnet"}}, +{"pk": 1207, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "nsfnet", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Perspectives on the Next Generation of the NSFnet"}}, {"pk": 1208, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "ptopo@3com.com", "acronym": "ptopomib", "comments": "AD was Harald", "list_subscribe": "ptopo-request@3com.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp ftp.3com.com (login: ptopo, passwd: ptopo)", "type": "wg", "name": "Physical Topology MIB"}}, {"pk": 1209, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "ietf-ppp@ucdavis.edu", "acronym": "ppp", "comments": "", "list_subscribe": "ietf-ppp-request@ucdavis.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Point-to-Point Protocol"}}, -{"pk": 1210, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 100664, "parent": 1052, "list_email": "pppext@ietf.org", "acronym": "pppext", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/pppext", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pppext/", "type": "wg", "name": "Point-to-Point Protocol Extensions"}}, -{"pk": 1211, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2853, "parent": 1179, "list_email": "poised@tis.com", "acronym": "poised95", "comments": "Rechartered as the Poisson WG.", "list_subscribe": "poised-request@tis.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://tis.com/pub/ietf/poised/poised.mbox", "type": "wg", "name": "Poised 95"}}, +{"pk": 1210, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "pppext@ietf.org", "acronym": "pppext", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/pppext", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pppext/", "type": "wg", "name": "Point-to-Point Protocol Extensions"}}, +{"pk": 1211, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1179, "list_email": "poised@tis.com", "acronym": "poised95", "comments": "Rechartered as the Poisson WG.", "list_subscribe": "poised-request@tis.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://tis.com/pub/ietf/poised/poised.mbox", "type": "wg", "name": "Poised 95"}}, {"pk": 1212, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-pop@dbc.mtview.ca.us", "acronym": "pop", "comments": "Waiting for the chair to lift a 'hold for SMP' O-Proposed & Start: 6/10/92", "list_subscribe": "ietf-pop-request@dbc.mtview.ca.us", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Post Office Protocol"}}, -{"pk": 1213, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "piara", "comments": "1st meeting at Montreal, Canada - 36th IETF June 1996", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Pricing for Internet Addresses and Route Assignmen"}}, -{"pk": 1214, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": null, "list_email": "", "acronym": "printjob", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Print Job Management"}}, +{"pk": 1213, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "piara", "comments": "1st meeting at Montreal, Canada - 36th IETF June 1996", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Pricing for Internet Addresses and Route Assignmen"}}, +{"pk": 1214, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "printjob", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Print Job Management"}}, {"pk": 1215, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "pmp@pwg.org", "acronym": "printmib", "comments": "Met as a bof in Houston. Orig-Prop: 1/19/94, start 1/31/94, conclude 3/22/95. Reactivated 11/4/96", "list_subscribe": "majordomo@pwg.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.pwg.org/hypermail/pmp/", "type": "wg", "name": "Printer MIB"}}, {"pk": 1216, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "pem-dev@tis.com", "acronym": "pem", "comments": "", "list_subscribe": "pem-dev-request@tis.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "pem-dev-request@tis.com", "type": "wg", "name": "Privacy-Enhanced Electronic Mail"}}, {"pk": 1217, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "pdn-wg@bbn.com", "acronym": "pdnrout", "comments": "", "list_subscribe": "pdn-request@bbn.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Private Data Network Routing"}}, {"pk": 1218, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "pier@isi.edu", "acronym": "pier", "comments": "1st meeting 34th IETF, Dallas (December 4-8, 1996) mw\r\nAD was Harald", "list_subscribe": "pier-request@isi.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.isi.edu/pier-archive", "type": "wg", "name": "Procedures for Internet/Enterprise Renumbering"}}, -{"pk": 1219, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2853, "parent": 1179, "list_email": "poised@tis.com", "acronym": "poised", "comments": "POISED was never concluded, but as of the Seattle IETF, it was informally reactivated in doing its 'two-year checkup'.", "list_subscribe": "poised-request@tis.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ietf.cnri.reston.va.us:~/ietf-mail-archive/poised/*", "type": "wg", "name": "Process for Organization of Internet Standards"}}, -{"pk": 1220, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "poised@lists.tislabs.com", "acronym": "poisson", "comments": "Was named Poised95. Renamed with new charter and milestones on 7/25.", "list_subscribe": "poised-request@lists.tislabs.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.tis.com/pub/lists/poised/poised.yymm", "type": "wg", "name": "Process for Organization of Internet Standards ONgoing"}}, -{"pk": 1221, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "prottest", "comments": "1st meeting 32nd IETF Danvers, MA (April 3-7, 1995) mw has now been chartered as the stdguide WG. 10/31/95 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Protocol Testing"}}, +{"pk": 1219, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1179, "list_email": "poised@tis.com", "acronym": "poised", "comments": "POISED was never concluded, but as of the Seattle IETF, it was informally reactivated in doing its 'two-year checkup'.", "list_subscribe": "poised-request@tis.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ietf.cnri.reston.va.us:~/ietf-mail-archive/poised/*", "type": "wg", "name": "Process for Organization of Internet Standards"}}, +{"pk": 1220, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1008, "list_email": "poised@lists.tislabs.com", "acronym": "poisson", "comments": "Was named Poised95. Renamed with new charter and milestones on 7/25.", "list_subscribe": "poised-request@lists.tislabs.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.tis.com/pub/lists/poised/poised.yymm", "type": "wg", "name": "Process for Organization of Internet Standards ONgoing"}}, +{"pk": 1221, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "prottest", "comments": "1st meeting 32nd IETF Danvers, MA (April 3-7, 1995) mw has now been chartered as the stdguide WG. 10/31/95 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Protocol Testing"}}, {"pk": 1222, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "pint@lists.bell-labs.com", "acronym": "pint", "comments": "1st meeting at 38th IETF - Memphis, TN", "list_subscribe": "pint-request@lists.bell-labs.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.bell-labs.com/mailing-lists/pint/", "type": "wg", "name": "PSTN and Internet Internetworking"}}, -{"pk": 1223, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "pkix@ietf.org", "acronym": "pkix", "comments": "1st met, 34th IETF Dallas, TX (December 4-8, 1995)", "list_subscribe": "pkix-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pkix/", "type": "wg", "name": "Public-Key Infrastructure (X.509)"}}, +{"pk": 1223, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "pkix@ietf.org", "acronym": "pkix", "comments": "1st met, 34th IETF Dallas, TX (December 4-8, 1995)", "list_subscribe": "pkix-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pkix/", "type": "wg", "name": "Public-Key Infrastructure (X.509)"}}, {"pk": 1224, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "qosr@newbridge.com", "acronym": "qosr", "comments": "", "list_subscribe": "qosr-request@newbridge.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "QoS Routing"}}, {"pk": 1225, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "quality@naic.nasa.gov", "acronym": "quis", "comments": "1st meeting July 1994/Toronto mw. as of 24 oct 94, going for wg status /jws.", "list_subscribe": "listmanager@naic.nasa.gov", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "listmanager@naic.nasa.gov body=`index quality'", "type": "wg", "name": "Quality Information Services"}}, -{"pk": 1226, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "", "acronym": "rtl", "comments": "1st met as BOF 33rd IETF: Stockholm: 17-21 July 1995, jointly under USV and APPS area mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Read the Label"}}, +{"pk": 1226, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "", "acronym": "rtl", "comments": "1st met as BOF 33rd IETF: Stockholm: 17-21 July 1995, jointly under USV and APPS area mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Read the Label"}}, {"pk": 1227, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "realtime", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Realtime Packet Forwarding and Admission Control"}}, {"pk": 1228, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "rtfm@auckland.ac.nz", "acronym": "rtfm", "comments": "1st met at 34th IETF Dallas (December 4-8, 1995) mw", "list_subscribe": "majordomo@auckland.ac.nz", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.auckland.ac.nz/pub/rtfm/ml-archive", "type": "wg", "name": "Realtime Traffic Flow Measurement"}}, {"pk": 1229, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "receipt@cs.utk.edu", "acronym": "receipt", "comments": "1st met as BOF: 33rd IETF: Stockholm 17-21 July 1995 mw", "list_subscribe": "receipt-request@cs.utk.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://cs.utk.edu/pub/receipt/mail-archive", "type": "wg", "name": "Receipt Notifications for Internet Mail"}}, -{"pk": 1230, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": null, "list_email": "raidmib-l@netx.com", "acronym": "raidmib", "comments": "1st met as BOF, 34th IETF - Dallas, TX December 4-8, 1995, mw", "list_subscribe": "raidmib-l-request@netx.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Redundant Arrays of Independent Disks MIB"}}, +{"pk": 1230, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "raidmib-l@netx.com", "acronym": "raidmib", "comments": "1st met as BOF, 34th IETF - Dallas, TX December 4-8, 1995, mw", "list_subscribe": "raidmib-l-request@netx.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Redundant Arrays of Independent Disks MIB"}}, {"pk": 1231, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "ride", "comments": "1st meeting - 38th IETF - Memphis, TN; 2nd meeting - 39th IETF - Munich, Germany", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Registry Information Database Exchange Formats & P"}}, -{"pk": 1232, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "rdbmsmib@us.oracle.com", "acronym": "rdbmsmib", "comments": "", "list_subscribe": "rdbmsmib-request@us.oracle.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "gatekeeper.dec.com:~/pub/net/info/ietf", "type": "wg", "name": "Relational Database Management Systems MIB"}}, -{"pk": 1233, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2744, "parent": null, "list_email": "", "acronym": "ramp", "comments": "1st IETF Meeting: Seattle: 94-03: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Remote Account Maintenance Protocol"}}, +{"pk": 1232, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1157, "list_email": "rdbmsmib@us.oracle.com", "acronym": "rdbmsmib", "comments": "", "list_subscribe": "rdbmsmib-request@us.oracle.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "gatekeeper.dec.com:~/pub/net/info/ietf", "type": "wg", "name": "Relational Database Management Systems MIB"}}, +{"pk": 1233, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ramp", "comments": "1st IETF Meeting: Seattle: 94-03: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Remote Account Maintenance Protocol"}}, {"pk": 1234, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "ietf-radius@livingston.com", "acronym": "radius", "comments": "1st meeting 32nd IETF, Danvers, MA April 3-7, 1995 mw", "list_subscribe": "ietf-radius-request@livingston.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.livingston.com/pub/radius/archive", "type": "wg", "name": "Remote Authentication Dial-In User Service"}}, {"pk": 1235, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "rem-conf@es.net", "acronym": "remconf", "comments": "1st met as bof in Boston. 92-07", "list_subscribe": "rem-conf-request@es.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "nic.es.net:./ietf.rem-conf/rem-conf-archive", "type": "wg", "name": "Remote Conferencing"}}, {"pk": 1236, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "remmail", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Remote Mail Protocol"}}, {"pk": 1237, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "rmonmib@ietf.org", "acronym": "rmonmib", "comments": "The group was renamed from rlanmib. Original start date 8/1/90, end date 3/20/92. Mike Erlinger replaced 31 Oct. /jws", "list_subscribe": "http://www.ietf.org/mailman/listinfo/rmonmib", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rmonmib/", "type": "wg", "name": "Remote Network Monitoring"}}, -{"pk": 1238, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "tpcint", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Remote Printing on Glodal Facsimile Devices"}}, -{"pk": 1239, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 188, "parent": null, "list_email": "", "acronym": "resdisc", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Resource Discovery"}}, +{"pk": 1238, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "tpcint", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Remote Printing on Glodal Facsimile Devices"}}, +{"pk": 1239, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "resdisc", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Resource Discovery"}}, {"pk": 1240, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "rsvp@isi.edu", "acronym": "rsvp", "comments": "", "list_subscribe": "rsvp-request@isi.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.isi.edu/rsvp/rsvp.mail", "type": "wg", "name": "Resource Reservation Setup Protocol"}}, -{"pk": 1241, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "ietf-run@mailbag.intel.com", "acronym": "run", "comments": "1st meeting: San Jose 12/94 mw. Closed 10/20.95. Reactivated 10/8/96", "list_subscribe": "listserv@mailbag.intel.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.intel.com/pub/ietf-run", "type": "wg", "name": "Responsible Use of the Network"}}, +{"pk": 1241, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "ietf-run@mailbag.intel.com", "acronym": "run", "comments": "1st meeting: San Jose 12/94 mw. Closed 10/20.95. Reactivated 10/8/96", "list_subscribe": "listserv@mailbag.intel.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.intel.com/pub/ietf-run", "type": "wg", "name": "Responsible Use of the Network"}}, {"pk": 1242, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "nosi@sunroof.eng.sun.com", "acronym": "rfc1006", "comments": "1st BOF meeting 33rd IETF/Stockholm 17-21 July 1995 mw", "list_subscribe": "majordomo@sunroof.eng.sun.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "RFC1006bis/ISO TP over IPv6"}}, {"pk": 1243, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "ietf-rip@xylogics.com", "acronym": "ripv2", "comments": "Originally chartered 1/23/92, concluded 1/12/93. Rechartered to become RIP 2/28/95", "list_subscribe": "ietf-rip-request@xylogics.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://xylogics.com/gmalkin/rip/rip-arc", "type": "wg", "name": "RIP Version II"}}, {"pk": 1244, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "roamops@tdmx.rutgers.edu", "acronym": "roamops", "comments": "", "list_subscribe": "roamops-request@tdmx.rutgers.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp-no.rutgers.edu/misc/IETF/roamops", "type": "wg", "name": "Roaming Operations"}}, {"pk": 1245, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "gw-discovery@gregorio.stanford.edu", "acronym": "rdisc", "comments": "", "list_subscribe": "gw-discovery-request@gregorio.stanford.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Router Discovery"}}, {"pk": 1246, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "rreq@isi.edu", "acronym": "rreq", "comments": "Dormant for long time (3/1/93). Original chair - Phil Almquist. Jumpstarted on March 31, 1994", "list_subscribe": "rreq-request@isi.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Router Requirements"}}, -{"pk": 1247, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "rreqlist", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Router Requirements Checklist"}}, +{"pk": 1247, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "rreqlist", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Router Requirements Checklist"}}, {"pk": 1248, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "", "acronym": "road", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Routing and Addressing"}}, {"pk": 1249, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 2, "list_email": "", "acronym": "rtg", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-02-26 00:21:37", "unused_tags": [], "list_archive": "", "type": "area", "name": "Routing Area"}}, {"pk": 1250, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "rip@ietf.org", "acronym": "rip", "comments": "Rechartering of the RIPv2 WG", "list_subscribe": "rip-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rip/", "type": "wg", "name": "Routing Information Protocol"}}, @@ -413,37 +413,37 @@ {"pk": 1259, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "ietf-ssh@netbsd.org", "acronym": "secsh", "comments": "", "list_subscribe": "majordomo@netbsd.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.ietf.org/ietf-mail-archive/secsh/", "type": "wg", "name": "Secure Shell"}}, {"pk": 1260, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 2, "list_email": "", "acronym": "sec", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-02-26 00:21:37", "unused_tags": [], "list_archive": "", "type": "area", "name": "Security Area"}}, {"pk": 1261, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "saag@tis.com", "acronym": "secdir", "comments": "6/7/94 Jeff Schiller closed to form Security Area Directorate. 10/94 Jeff wants SAAG for open meeting, SECDIR for closed. mw", "list_subscribe": "saag-request@tis.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "team", "name": "Security Area Directorate"}}, -{"pk": 1262, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 188, "parent": 1179, "list_email": "", "acronym": "wg-sec", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Security Technology"}}, +{"pk": 1262, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1179, "list_email": "", "acronym": "wg-sec", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Security Technology"}}, {"pk": 1263, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "select", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Selection Criteria"}}, {"pk": 1264, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 2, "list_email": "", "acronym": "sap", "comments": "No longer exists", "list_subscribe": "", "state": "unknown", "time": "2012-02-26 00:21:37", "unused_tags": [], "list_archive": "", "type": "area", "name": "Service Applications Area"}}, {"pk": 1265, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "srvloc@srvloc.org", "acronym": "svrloc", "comments": "Moved from SAP to INT on 10 May 1994 by JWS.", "list_subscribe": "srvloc-request@srvloc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.srvloc.org/hypermail/index.htm", "type": "wg", "name": "Service Location Protocol"}}, {"pk": 1266, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ssl", "comments": "1st met as BOF 33rd IETF: Stockholm: 17-21 July 1995 mw Meet again at 35th IETF, name changed to TLS on 2/24/96 per Jeff Schiller", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Session Layer Security"}}, {"pk": 1267, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "whois", "comments": "1st meeting at 49th IETF-San Diego, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Whois Protocol"}}, -{"pk": 1268, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": 934, "list_email": "sip@caldera.usc.edu", "acronym": "sip-o", "comments": "SIP Merged with pip to become the sipp working group. Changed to SIP-O to accommodate new WG (Session Initiation Protocol) acronym.", "list_subscribe": "sip-request@caldera.usc.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Simple Internet Protocol"}}, -{"pk": 1269, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2515, "parent": 1092, "list_email": "sipp@sunroof.eng.sun.com", "acronym": "sipp", "comments": "merged pip and sip working groups", "list_subscribe": "sipp-request@sunroof.eng.sun.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "parcftp.xerox.com: pub/sipp", "type": "wg", "name": "Simple Internet Protocol Plus"}}, +{"pk": 1268, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "sip@caldera.usc.edu", "acronym": "sip-o", "comments": "SIP Merged with pip to become the sipp working group. Changed to SIP-O to accommodate new WG (Session Initiation Protocol) acronym.", "list_subscribe": "sip-request@caldera.usc.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Simple Internet Protocol"}}, +{"pk": 1269, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1092, "list_email": "sipp@sunroof.eng.sun.com", "acronym": "sipp", "comments": "merged pip and sip working groups", "list_subscribe": "sipp-request@sunroof.eng.sun.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "parcftp.xerox.com: pub/sipp", "type": "wg", "name": "Simple Internet Protocol Plus"}}, {"pk": 1270, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "skip", "comments": "1st met as BOF 33rd IETF Stockholm 17-21 July, 1995 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Simple Key Management for IP"}}, -{"pk": 1271, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": null, "list_email": "", "acronym": "smpframe", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Simple Management Protocol (SMP) Framework"}}, -{"pk": 1272, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "snmp@psi.com", "acronym": "snmp", "comments": "", "list_subscribe": "snmp-request@psi.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Simple Network Management Protocol"}}, +{"pk": 1271, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "smpframe", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Simple Management Protocol (SMP) Framework"}}, +{"pk": 1272, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1157, "list_email": "snmp@psi.com", "acronym": "snmp", "comments": "", "list_subscribe": "snmp-request@psi.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Simple Network Management Protocol"}}, {"pk": 1273, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "spki@c2.net", "acronym": "spki", "comments": "", "list_subscribe": "majordomo@c2.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Simple Public Key Infrastructure"}}, -{"pk": 1274, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "ssh@cert.org", "acronym": "ssh", "comments": "Originally concluded 3/5/91.", "list_subscribe": "ssh-request@cert.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://info.cert.org/pub/ietf/ssh", "type": "wg", "name": "Site Security Handbook"}}, -{"pk": 1275, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": null, "list_email": "", "acronym": "smibof", "comments": "1st meeting at 36th IETF - Montreal, Canada", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SMI Documentation"}}, +{"pk": 1274, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "ssh@cert.org", "acronym": "ssh", "comments": "Originally concluded 3/5/91.", "list_subscribe": "ssh-request@cert.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://info.cert.org/pub/ietf/ssh", "type": "wg", "name": "Site Security Handbook"}}, +{"pk": 1275, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "smibof", "comments": "1st meeting at 36th IETF - Montreal, Canada", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SMI Documentation"}}, {"pk": 1276, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "snadlcmib@cisco.com", "acronym": "snadlc", "comments": "replaced Jeff Hilgeman as chair 2/94 mw", "list_subscribe": "snadlcmib-request@cisco.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNA DLC Services MIB"}}, {"pk": 1277, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "snanaumib@external.cisco.com", "acronym": "snanau", "comments": "revised charter and milestones received 2/7/94. Original charter in snanau-1.desc.txt. updated 6/3/97 (prev. in snanau-2.desc.txt", "list_subscribe": "snanaumib-request@cisco.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.cisco.com/snanaumib/mail-archive", "type": "wg", "name": "SNA NAU Services MIB"}}, {"pk": 1278, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "snapper@cisco.com", "acronym": "snapper", "comments": "", "list_subscribe": "snapper-request@cisco.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNA Peer-to-Peer Networking"}}, -{"pk": 1279, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": null, "list_email": "snanaumib@thumper.bellcore.com", "acronym": "snamib", "comments": "", "list_subscribe": "snanaumib-request@thumper.bellcore.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNA Systems Management"}}, -{"pk": 1280, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": 1190, "list_email": "snmp-ng@tis.com", "acronym": "snmp-ng", "comments": "", "list_subscribe": "snmp-ng-request@tis.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.tis.com/pub/ietf/snmp-ng", "type": "wg", "name": "SNMP - Next Generation"}}, -{"pk": 1281, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": null, "list_email": "", "acronym": "snmpagen", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNMP Agent Description"}}, +{"pk": 1279, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "snanaumib@thumper.bellcore.com", "acronym": "snamib", "comments": "", "list_subscribe": "snanaumib-request@thumper.bellcore.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNA Systems Management"}}, +{"pk": 1280, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1190, "list_email": "snmp-ng@tis.com", "acronym": "snmp-ng", "comments": "", "list_subscribe": "snmp-ng-request@tis.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.tis.com/pub/ietf/snmp-ng", "type": "wg", "name": "SNMP - Next Generation"}}, +{"pk": 1281, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "snmpagen", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNMP Agent Description"}}, {"pk": 1282, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "agentx@ietf.org", "acronym": "agentx", "comments": "Old email archive at: ftp://ftp.ietf.org/ietf-mail-archive/agentx/", "list_subscribe": "agentx-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/working-groups/agentx/current/maillist.html", "type": "wg", "name": "SNMP Agent Extensibility"}}, -{"pk": 1283, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": null, "list_email": "", "acronym": "sam", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNMP Application Monitoring"}}, -{"pk": 1284, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": 1260, "list_email": "awg@bitsy.mit.edu", "acronym": "snmpauth", "comments": "This group has died in a dishonorable state.", "list_subscribe": "awg-request@bitsy.mit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNMP Authentication"}}, -{"pk": 1285, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": null, "list_email": "", "acronym": "devdisc", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNMP Device Discovery"}}, +{"pk": 1283, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "sam", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNMP Application Monitoring"}}, +{"pk": 1284, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "awg@bitsy.mit.edu", "acronym": "snmpauth", "comments": "This group has died in a dishonorable state.", "list_subscribe": "awg-request@bitsy.mit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNMP Authentication"}}, +{"pk": 1285, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "devdisc", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNMP Device Discovery"}}, {"pk": 1286, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1157, "list_email": "snmp-foo@thumper.bellcore.com", "acronym": "mpsnmp", "comments": "", "list_subscribe": "snmp-foo-request@thumper.bellcore.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "thumper.bellcore.com:~/pub/snmp-foo/archive", "type": "wg", "name": "SNMP Over a Multi-Protocol Internet"}}, -{"pk": 1287, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": null, "list_email": "", "acronym": "snmpxns", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNMP Over XNS"}}, +{"pk": 1287, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "snmpxns", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNMP Over XNS"}}, {"pk": 1288, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "snmp-sec-dev@tis.com", "acronym": "snmpsec", "comments": "The Group is continuing the work of the SNMP authentication WG.", "list_subscribe": "snmp-sec-dev-request@tis.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "snmp-sec-dev-request@tis.com", "type": "wg", "name": "SNMP Security"}}, {"pk": 1289, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "snmpseci", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNMP Security Implementors"}}, -{"pk": 1290, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "snmpv2@tis.com", "acronym": "snmpv2", "comments": "orig. prop. 8/5/92, iesg 9/1/92, start 9/27/92, end 5/3/93", "list_subscribe": "snmpv2-request@tis.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.tis.com/pub/ietf/snmpv2", "type": "wg", "name": "SNMP Version 2"}}, +{"pk": 1290, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1157, "list_email": "snmpv2@tis.com", "acronym": "snmpv2", "comments": "orig. prop. 8/5/92, iesg 9/1/92, start 9/27/92, end 5/3/93", "list_subscribe": "snmpv2-request@tis.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.tis.com/pub/ietf/snmpv2", "type": "wg", "name": "SNMP Version 2"}}, {"pk": 1291, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "snmpv3@lists.tislabs.com", "acronym": "snmpv3", "comments": "", "list_subscribe": "snmpv3-request@lists.tislabs.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.tislabs.com/pub/ietf/snmpv3", "type": "wg", "name": "SNMP Version 3"}}, -{"pk": 1292, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": null, "list_email": "", "acronym": "mibcomp", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNMPMIB Compiler"}}, +{"pk": 1292, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "mibcomp", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNMPMIB Compiler"}}, {"pk": 1293, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "sdrp@catarina.usc.edu", "acronym": "sdr", "comments": "was originally formed as Source Demand Routing Protocol (sdrp)", "list_subscribe": "sdrp-request@catarina.usc.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://catarina.usc.edu/pub/sdrp", "type": "wg", "name": "Source Demand Routing"}}, {"pk": 1294, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "ietf-hosts@nnsc.nsf.net", "acronym": "shr", "comments": "", "list_subscribe": "ietf-hosts-request@nnsc.nsf.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Special Host Requirements"}}, {"pk": 1295, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "stif", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Structured Text Interchange Format"}}, @@ -456,32 +456,32 @@ {"pk": 1302, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "tcpsat@grc.nasa.gov", "acronym": "tcpsat", "comments": "1st meeting at 38th IETF - Memphis, TN", "list_subscribe": "majordomo@grc.nasa.gov", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://tcpsat.grc.nasa.gov/tcpsat/mail.html", "type": "wg", "name": "TCP Over Satellite"}}, {"pk": 1303, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "tcpfix", "comments": "1st meeting, 34th IETF: Dallas, TX December 4-8, 1995 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "TCP Short-Term Problems"}}, {"pk": 1304, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "tuba@lanl.gov", "acronym": "tuba", "comments": "", "list_subscribe": "tuba-request@lanl.gov", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "TCP/UDP Over CLNP-Addressed Networks"}}, -{"pk": 1305, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "", "acronym": "telework", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Telecommuting"}}, +{"pk": 1305, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "", "acronym": "telework", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Telecommuting"}}, {"pk": 1306, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "teleconf", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Teleconferencing"}}, {"pk": 1307, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "telarch", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Teleconferencing Architecture"}}, {"pk": 1308, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "telnet-ietf@cray.com", "acronym": "telnet", "comments": "", "list_subscribe": "telnet-ietf-request@cray.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "TELNET"}}, {"pk": 1309, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "telnetlm", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "TELNET Linemode Working Group"}}, {"pk": 1310, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "tn3270e@list.nih.gov", "acronym": "tn3270e", "comments": "pro 4/13. iesg 4/26. start 4/29/93. concluded on 6/25/95. Reactivated for SJ-2 meeting.", "list_subscribe": "listserv@list.nih.gov", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "listserv@list.nih.gov", "type": "wg", "name": "Telnet TN3270 Enhancements"}}, -{"pk": 1311, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": null, "list_email": "auth-acct@angband.stanford.edu", "acronym": "termacct", "comments": "1st meeting 22nd IETF, Santa Fe November 18-22, 1991 mw", "list_subscribe": "auth-acct-request@angband.stanford.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Terminal Server Accounting and Authentication"}}, -{"pk": 1312, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": 934, "list_email": "dod-test@cavebear.com", "acronym": "testing", "comments": "1st meeting Toronto IETF, mw", "list_subscribe": "dod-test-request@cavebear.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Testing"}}, +{"pk": 1311, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "auth-acct@angband.stanford.edu", "acronym": "termacct", "comments": "1st meeting 22nd IETF, Santa Fe November 18-22, 1991 mw", "list_subscribe": "auth-acct-request@angband.stanford.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Terminal Server Accounting and Authentication"}}, +{"pk": 1312, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "dod-test@cavebear.com", "acronym": "testing", "comments": "1st meeting Toronto IETF, mw", "list_subscribe": "dod-test-request@cavebear.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Testing"}}, {"pk": 1313, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "tftpexts@hpindsh.cup.hp.com", "acronym": "tftpexts", "comments": "1st meeting December 1994 IETF, San Jose. mw", "list_subscribe": "tftpexts-request@hpindsh.cup.hp.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "onet2.cup.hp.com:/dist/tftpexts/tftpexts_archive", "type": "wg", "name": "TFTP Extensions"}}, -{"pk": 1314, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "", "acronym": "arts", "comments": "5/95 became the Humanities and Arts WG (harts) mw see separate record.", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "The Arts: Sharing Center Stage on the Internet"}}, +{"pk": 1314, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "", "acronym": "arts", "comments": "5/95 became the Humanities and Arts WG (harts) mw see separate record.", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "The Arts: Sharing Center Stage on the Internet"}}, {"pk": 1315, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "2000@nic.surfnet.nl", "acronym": "2000", "comments": "gopher://HEARN.nic.SURF net.nl:70/11/1.%20LISTSERVs%20public %20archives%20on%20HEARN.nic.SURFnet. NL/2000", "list_subscribe": "listserv@nic.surfnet.nl", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://listserv.surfnet.nl/archives/2000.html", "type": "wg", "name": "The Internet and the Millennium Problem"}}, -{"pk": 1316, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "rmonmib@lexcel.com", "acronym": "trmon", "comments": "", "list_subscribe": "rmonmib-request@lexcel.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Token Ring Remote Monitoring"}}, -{"pk": 1317, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": 1052, "list_email": "tpix@world.std.com", "acronym": "tpix", "comments": "Not really concluded. tpix was changed to catnip", "list_subscribe": "tpix-request@world.std.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "world.std.com:~/pub/tpix/*", "type": "wg", "name": "TP/IX"}}, +{"pk": 1316, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1157, "list_email": "rmonmib@lexcel.com", "acronym": "trmon", "comments": "", "list_subscribe": "rmonmib-request@lexcel.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Token Ring Remote Monitoring"}}, +{"pk": 1317, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "tpix@world.std.com", "acronym": "tpix", "comments": "Not really concluded. tpix was changed to catnip", "list_subscribe": "tpix-request@world.std.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "world.std.com:~/pub/tpix/*", "type": "wg", "name": "TP/IX"}}, {"pk": 1318, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "tracerte", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Traceroute"}}, -{"pk": 1319, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "trafchar", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Traffic Collection, Measurement & Characterization"}}, +{"pk": 1319, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "trafchar", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Traffic Collection, Measurement & Characterization"}}, {"pk": 1320, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "tip@tandem.com", "acronym": "tip", "comments": "1st meeting - 38th IETF, Memphis, TN; 2nd meeting - 39th IETF, Munich, Germany", "list_subscribe": "listserv@tandem.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Transaction Internet Protocol"}}, {"pk": 1321, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "ttcp", "comments": "First meeting 35th IETF - Los Angeles, CA - March 1996", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Transaction TCP"}}, -{"pk": 1322, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "tacit", "comments": "1st IETF Meeting: Seattle: 94-03: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Transition and Coexistence Including Testing"}}, -{"pk": 1323, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "trans-wg@nisc.nyser.net", "acronym": "transmib", "comments": "", "list_subscribe": "trans-wg-request@nisc.nyser.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Transmission Mib"}}, +{"pk": 1322, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "tacit", "comments": "1st IETF Meeting: Seattle: 94-03: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Transition and Coexistence Including Testing"}}, +{"pk": 1323, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1157, "list_email": "trans-wg@nisc.nyser.net", "acronym": "transmib", "comments": "", "list_subscribe": "trans-wg-request@nisc.nyser.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Transmission Mib"}}, {"pk": 1324, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 2, "list_email": "", "acronym": "tsv", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-02-26 00:21:37", "unused_tags": [], "list_archive": "", "type": "area", "name": "Transport Area"}}, {"pk": 1325, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "tsvdir", "comments": "1st met: 34th IETF: Dallas, TX December 4-8, 1995 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "team", "name": "Transport Area Directorate Open Meeting"}}, -{"pk": 1326, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "tls@ietf.org", "acronym": "tls", "comments": "Was formerly called SSL", "list_subscribe": "https://www.ietf.org/mailman/listinfo/tls", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/tls/", "type": "wg", "name": "Transport Layer Security"}}, -{"pk": 1327, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 188, "parent": null, "list_email": "", "acronym": "tadmin", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Trusted Administration"}}, +{"pk": 1326, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "tls@ietf.org", "acronym": "tls", "comments": "Was formerly called SSL", "list_subscribe": "https://www.ietf.org/mailman/listinfo/tls", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/tls/", "type": "wg", "name": "Transport Layer Security"}}, +{"pk": 1327, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "tadmin", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Trusted Administration"}}, {"pk": 1328, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "tnfs@wdl1.wdl.loral.com", "acronym": "tnfs", "comments": "Moved from SAP to SEC on 10 May 1994 by JWS. This group began in TSIG.", "list_subscribe": "tnfs-request@wdl1.wdl.loral.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "archive-server@wdl1.wdl.loral.com", "type": "wg", "name": "Trusted Network File Systems"}}, -{"pk": 1329, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 188, "parent": null, "list_email": "", "acronym": "tsess", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Trusted Sessions"}}, -{"pk": 1330, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 188, "parent": null, "list_email": "", "acronym": "txwg", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Trusted X"}}, +{"pk": 1329, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "tsess", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Trusted Sessions"}}, +{"pk": 1330, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "txwg", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Trusted X"}}, {"pk": 1331, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "tcoord", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "TSIG/IETF Coordination"}}, {"pk": 1332, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "usm", "comments": "1st meeting in Los Angeles, CA - 35th IETF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Ubiquitous Secure Mail"}}, {"pk": 1333, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "ucs", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "UCS Character Set"}}, @@ -492,25 +492,25 @@ {"pk": 1338, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "url", "comments": "1st meeting at 37th IETF - San Jose, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Uniform Resource Locators"}}, {"pk": 1339, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "urn-ietf@lists.netsol.com", "acronym": "urn", "comments": "1st met as BOF, 34th IETF, Dallas, TX Decembe4 4-8, 1995 mw", "list_subscribe": "listserv@lists.netsol.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.netsol.com/archives/urn-ietf.html", "type": "wg", "name": "Uniform Resource Names"}}, {"pk": 1340, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "ups-mib@cs.utk.edu", "acronym": "upsmib", "comments": "O-Proposed/IESG: 9/25/92. O-Start 10/5/92. Conclude 5/24/94", "list_subscribe": "ups-mib-request@cs.utk.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ucs.utk.edu:~/pub/ups-mib/mail-archive", "type": "wg", "name": "Uninterruptible Power Supply"}}, -{"pk": 1341, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "", "acronym": "udi", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Universal Document Identifiers"}}, -{"pk": 1342, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2324, "parent": null, "list_email": "ucp@nic.near.net", "acronym": "ucp", "comments": "", "list_subscribe": "ucp-request@nic.near.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "User Connectivity"}}, -{"pk": 1343, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "user-doc@nnsc.nsf.net", "acronym": "userdoc", "comments": "", "list_subscribe": "user-doc-request@nnsc.nsf.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "User Documents"}}, -{"pk": 1344, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "user-doc@merit.edu", "acronym": "userdoc2", "comments": "", "list_subscribe": "user-doc-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "User Documents Revisions"}}, -{"pk": 1345, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "uswg@isc.org", "acronym": "uswg", "comments": "", "list_subscribe": "uswg-request@isc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.isc.org/ml-archives/uswg/2000/maillist.html", "type": "wg", "name": "User Services"}}, +{"pk": 1341, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "", "acronym": "udi", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Universal Document Identifiers"}}, +{"pk": 1342, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "ucp@nic.near.net", "acronym": "ucp", "comments": "", "list_subscribe": "ucp-request@nic.near.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "User Connectivity"}}, +{"pk": 1343, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "user-doc@nnsc.nsf.net", "acronym": "userdoc", "comments": "", "list_subscribe": "user-doc-request@nnsc.nsf.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "User Documents"}}, +{"pk": 1344, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "user-doc@merit.edu", "acronym": "userdoc2", "comments": "", "list_subscribe": "user-doc-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "User Documents Revisions"}}, +{"pk": 1345, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1008, "list_email": "uswg@isc.org", "acronym": "uswg", "comments": "", "list_subscribe": "uswg-request@isc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.isc.org/ml-archives/uswg/2000/maillist.html", "type": "wg", "name": "User Services"}}, {"pk": 1346, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 2, "list_email": "", "acronym": "usv", "comments": "", "list_subscribe": "", "state": "unknown", "time": "2012-02-26 00:21:37", "unused_tags": [], "list_archive": "", "type": "area", "name": "User Services Area"}}, -{"pk": 1347, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "", "acronym": "usac", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "team", "name": "User Services Area Council"}}, -{"pk": 1348, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 104198, "parent": 1249, "list_email": "vrrp@ietf.org", "acronym": "vrrp", "comments": "1st meeting at 38th IETF - Memphis, TN", "list_subscribe": "vrrp-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/vrrp/", "type": "wg", "name": "Virtual Router Redundancy Protocol"}}, +{"pk": 1347, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "", "acronym": "usac", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "team", "name": "User Services Area Council"}}, +{"pk": 1348, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "vrrp@ietf.org", "acronym": "vrrp", "comments": "1st meeting at 38th IETF - Memphis, TN", "list_subscribe": "vrrp-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/vrrp/", "type": "wg", "name": "Virtual Router Redundancy Protocol"}}, {"pk": 1349, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "vtp", "comments": "1st meeting at 37th IETF - San Jose, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Virtual Tunneling Protocol BOF"}}, {"pk": 1350, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "vac", "comments": "1st meeting 34th IETF Dallas, December 4-8, 1995 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Voluntary Access Control"}}, -{"pk": 1351, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "", "acronym": "wais", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "WAIS and Directory Integration"}}, +{"pk": 1351, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "", "acronym": "wais", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "WAIS and Directory Integration"}}, {"pk": 1352, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "index", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Web Indexing and Related Issues"}}, {"pk": 1353, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "www-security@nsmx.rutgers.edu", "acronym": "wts", "comments": "", "list_subscribe": "www-security-request@nsmx.rutgers.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www-ns.rutgers.edu/www-security", "type": "wg", "name": "Web Transaction Security"}}, {"pk": 1354, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "atminfo", "comments": "One time BOF at Houston to provide informational update/status on the world of ATM", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Whither ATM - an update"}}, -{"pk": 1355, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "ietf-wnils@ucdavis.edu", "acronym": "wnils", "comments": "", "list_subscribe": "ietf-wnils-request@ucdavis.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ucdavis.edu/archive/wnils", "type": "wg", "name": "Whois and Network Information Lookup Service"}}, -{"pk": 1356, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 188, "parent": 1179, "list_email": "", "acronym": "wg-char", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Working Group on International Character Sets"}}, -{"pk": 1357, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "", "acronym": "www", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "World-Wide Web"}}, +{"pk": 1355, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "ietf-wnils@ucdavis.edu", "acronym": "wnils", "comments": "", "list_subscribe": "ietf-wnils-request@ucdavis.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ucdavis.edu/archive/wnils", "type": "wg", "name": "Whois and Network Information Lookup Service"}}, +{"pk": 1356, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1179, "list_email": "", "acronym": "wg-char", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Working Group on International Character Sets"}}, +{"pk": 1357, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "", "acronym": "www", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "World-Wide Web"}}, {"pk": 1358, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "w3c-dist-auth@w3.org", "acronym": "webdav", "comments": "", "list_subscribe": "w3c-dist-auth-request@w3.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.w3.org/Archives/Public/w3c-dist-auth/", "type": "wg", "name": "WWW Distributed Authoring and Versioning"}}, -{"pk": 1359, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "x25mib@dg-rtp.dg.com", "acronym": "x25mib", "comments": "", "list_subscribe": "x25mib-request@dg-rtp.dg.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "dg-rtp.dg.com:~/x25mib/Current.Mail", "type": "wg", "name": "X.25 Management Information Base"}}, +{"pk": 1359, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1157, "list_email": "x25mib@dg-rtp.dg.com", "acronym": "x25mib", "comments": "", "list_subscribe": "x25mib-request@dg-rtp.dg.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "dg-rtp.dg.com:~/x25mib/Current.Mail", "type": "wg", "name": "X.25 Management Information Base"}}, {"pk": 1360, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-osi-x400ops@cs.wisc.edu", "acronym": "x400ops", "comments": "", "list_subscribe": "ietf-osi-x400ops-request@cs.wisc.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "X.400 Operations"}}, {"pk": 1363, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ldapext@ietf.org", "acronym": "ldapext", "comments": "", "list_subscribe": "https://www1.ietf.org/mailman/listinfo/ldapext", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ldapext/", "type": "wg", "name": "LDAP Extension"}}, {"pk": 1364, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "dirdep", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Directory Deployment"}}, @@ -527,7 +527,7 @@ {"pk": 1375, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "adapts", "comments": "1st meeting at 40th IETF-Washington,DC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Adaptive Applications Support"}}, {"pk": 1376, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "vpn", "comments": "1st meeting at 40th IETF-Washington, DC; 2nd meeting at 43rd IETF-Orlando, FL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Virtual Private Networking"}}, {"pk": 1377, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "adsl@xlist.agcs.com", "acronym": "adsl", "comments": "", "list_subscribe": "mgr@xlist.agcs.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Asymmetric Digital Subscriber Line"}}, -{"pk": 1378, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "", "acronym": "webpriv", "comments": "1st Meeting - 40th IETF, Washington", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Web User Privacy: Expectations & Threats"}}, +{"pk": 1378, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "", "acronym": "webpriv", "comments": "1st Meeting - 40th IETF, Washington", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Web User Privacy: Expectations & Threats"}}, {"pk": 1379, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "mnnp", "comments": "1st meeting-40th IETF-Washington", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Multicast NetNews Protocol"}}, {"pk": 1381, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "malloc@ietf.org", "acronym": "malloc", "comments": "1st meeting-40th IETF, Washington, DC", "list_subscribe": "https://www1.ietf.org/mailman/listinfo/malloc/", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.ietf.org/ietf-mail-archive/malloc/", "type": "wg", "name": "Multicast-Address Allocation"}}, {"pk": 1382, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "posse", "comments": "1st meeting at 40th IETF, Washington, DC\r\nAD was Harald", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Packet Over SONET/SDH Examination"}}, @@ -537,31 +537,31 @@ {"pk": 1386, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "cidf@cs.ucdavis.edu", "acronym": "cidf", "comments": "1st meeting at 41st IETF-Los Angeles, CA", "list_subscribe": "cidf-request@cs.ucdavis.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Common Intrusion Detection Framework"}}, {"pk": 1387, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "ecn", "comments": "1st meeting at 41st IETF-Los Angeles, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Explicit Congestion Notification"}}, {"pk": 1388, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "diffserv@ietf.org", "acronym": "diffserv", "comments": "", "list_subscribe": "diffserv-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp.ietf.org/ietf-mail-archive/diffserv/", "type": "wg", "name": "Differentiated Services"}}, -{"pk": 1389, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 18321, "parent": 934, "list_email": "sieve@ietf.org", "acronym": "sieve", "comments": "1st meeting at 41st IETF-Los Angeles, CA; 2nd meeting at 44th IETF -Minneapolis, MN; 3rd meeting at 61st IETF", "list_subscribe": "sieve-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sieve/", "type": "wg", "name": "Sieve Mail Filtering Language"}}, +{"pk": 1389, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "sieve@ietf.org", "acronym": "sieve", "comments": "1st meeting at 41st IETF-Los Angeles, CA; 2nd meeting at 44th IETF -Minneapolis, MN; 3rd meeting at 61st IETF", "list_subscribe": "sieve-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sieve/", "type": "wg", "name": "Sieve Mail Filtering Language"}}, {"pk": 1390, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "www-webdav-dasl@w3.org", "acronym": "dasl", "comments": "1st meeting at 41st IETF-Los Angeles, CA; 2nd meeting at 42nd IETF-Chicago, IL", "list_subscribe": "www-webdav-dasl-request@w3.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.w3.org/Archives/Public/www-webdav-dasl/", "type": "wg", "name": "DAV Searching and Locating"}}, {"pk": 1391, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-http-ext@w3.org", "acronym": "httpext", "comments": "1st meeting at 41st IETF-Los Angeles", "list_subscribe": "ietf-http-ext-request@w3.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.w3.org/Archives/Public/ietf-http-ext/", "type": "wg", "name": "HTTP Extensions"}}, {"pk": 1392, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "aatn", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Avoidance of Address Translation in Networks"}}, {"pk": 1393, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "wasrv", "comments": "1st meeting at 41st IETF-Los Angeles", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Wide Area Service Location"}}, {"pk": 1394, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "rvp@iastate.edu", "acronym": "pipr", "comments": "1st meeting at 41st IETF-Los Angeles; 2nd meeting at 42nd IETF-Chicago, IL", "list_subscribe": "rvp-request@iastate.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "rvp-request@iastate.edu", "type": "wg", "name": "Presence Information Protocol Requirements"}}, {"pk": 1395, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-trade@lists.eListX.com", "acronym": "trade", "comments": "1st meeting at 41st IETF-Los Angeles", "list_subscribe": "ietf-trade-request@lists.eListX.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.eListX.com/archives/ietf-trade", "type": "wg", "name": "Internet Open Trading Protocol"}}, -{"pk": 1396, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 105682, "parent": 1193, "list_email": "adslmib@ietf.org", "acronym": "adslmib", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/adslmib", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/adslmib/", "type": "wg", "name": "ADSL MIB"}}, -{"pk": 1397, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 104198, "parent": 1249, "list_email": "pim@ietf.org", "acronym": "pim", "comments": "Full FTP archives (including old)\r\nftp://ftp.ietf.org/ietf-mail-archive/pim/", "list_subscribe": "https://www.ietf.org/mailman/listinfo/pim/", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pim/", "type": "wg", "name": "Protocol Independent Multicast"}}, +{"pk": 1396, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "adslmib@ietf.org", "acronym": "adslmib", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/adslmib", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/adslmib/", "type": "wg", "name": "ADSL MIB"}}, +{"pk": 1397, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "pim@ietf.org", "acronym": "pim", "comments": "Full FTP archives (including old)\r\nftp://ftp.ietf.org/ietf-mail-archive/pim/", "list_subscribe": "https://www.ietf.org/mailman/listinfo/pim/", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pim/", "type": "wg", "name": "Protocol Independent Multicast"}}, {"pk": 1398, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "ss7-internet@baynetworks.com", "acronym": "ss7", "comments": "1st BOF held at 42nd IETF-Chicago, IL", "list_subscribe": "majordomo@baynetworks.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.baynetworks.com/pub/outgoing/long/ss7", "type": "wg", "name": "SS7/Internet"}}, -{"pk": 1399, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 6699, "parent": 1193, "list_email": "", "acronym": "opsarea", "comments": "", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ag", "name": "Operations & Management Area Open Meeting"}}, +{"pk": 1399, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "opsarea", "comments": "", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ag", "name": "Operations & Management Area Open Meeting"}}, {"pk": 1400, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "trustmgt@east.isi.edu", "acronym": "trustmgt", "comments": "1st meeting - 42nd IETF, Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.cairn.net/trustmgt", "type": "wg", "name": "Trust Management"}}, {"pk": 1401, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "policy@ietf.org", "acronym": "policy", "comments": "1st meeting - 42nd IETF, Chicago, IL", "list_subscribe": "policy-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/policy/", "type": "wg", "name": "Policy Framework"}}, {"pk": 1402, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "stp", "comments": "1st meeting - 42nd IETF, Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Secure Transport Proxy"}}, {"pk": 1403, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "artmib", "comments": "1st meeting at 42nd IETF-Chicago, IL\r\n\r\nAD was Harald", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Application Response Time MIB"}}, -{"pk": 1404, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2329, "parent": 1249, "list_email": "", "acronym": "rtgarea", "comments": "", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ag", "name": "Routing Area Open Meeting"}}, +{"pk": 1404, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "", "acronym": "rtgarea", "comments": "", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ag", "name": "Routing Area Open Meeting"}}, {"pk": 1405, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "hmibs", "comments": "1st meeting at 42nd IETF-Chicago, IL\r\n\r\nAD was Harald", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "H.Multimedia MIBs"}}, {"pk": 1406, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "smiv2", "comments": "1st meeting - 42nd IETF, Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Structure of Management Information Version 2"}}, {"pk": 1407, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "mailrev", "comments": "1st meeting-42nd IETF, Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Review of Short Mail-related Extension Proposals"}}, -{"pk": 1408, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 6699, "parent": 1193, "list_email": "aaa-wg@merit.edu", "acronym": "aaa", "comments": "1st meeting - 42nd IETF, Chicago, IL; 2nd meeting-43rd IETF, Orlando, FL", "list_subscribe": "majordomo@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.merit.edu/mail.archives/aaa-wg/", "type": "wg", "name": "Authentication, Authorization and Accounting"}}, +{"pk": 1408, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "aaa-wg@merit.edu", "acronym": "aaa", "comments": "1st meeting - 42nd IETF, Chicago, IL; 2nd meeting-43rd IETF, Orlando, FL", "list_subscribe": "majordomo@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.merit.edu/mail.archives/aaa-wg/", "type": "wg", "name": "Authentication, Authorization and Accounting"}}, {"pk": 1409, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-imapext@imc.org", "acronym": "imapext", "comments": "1st meeting at 42nd IETF-Chicago, IL; 2nd meeting at 45th IETF-Oslo, Norway", "list_subscribe": "ietf-imapext-request@imc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.imc.org/ietf-imapext/", "type": "wg", "name": "Internet Message Access Protocol Extension"}}, {"pk": 1410, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "notify", "comments": "1st meeting at 42nd IETF-Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Event Notification Service"}}, {"pk": 1411, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "metad", "comments": "1st meeting at 42nd IETF-Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "MIME Enabled Textually Accessed Directories"}}, {"pk": 1412, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "mailcap", "comments": "1st meeting at 42nd IETF-Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Mail Recipient Capabilities"}}, -{"pk": 1413, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "enum@ietf.org", "acronym": "enum", "comments": "1st meeting at 42nd IETF-Chicago, IL; 2nd meeting at 43rd IETF-Orlando, FL", "list_subscribe": "https://www.ietf.org/mailman/listinfo/enum", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/enum/", "type": "wg", "name": "Telephone Number Mapping"}}, +{"pk": 1413, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "enum@ietf.org", "acronym": "enum", "comments": "1st meeting at 42nd IETF-Chicago, IL; 2nd meeting at 43rd IETF-Orlando, FL", "list_subscribe": "https://www.ietf.org/mailman/listinfo/enum", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/enum/", "type": "wg", "name": "Telephone Number Mapping"}}, {"pk": 1414, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "pppoe", "comments": "1st meeting at 42nd IETF-Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "PPP Over Ethernet"}}, {"pk": 1415, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "wrec@cs.utk.edu", "acronym": "wrec", "comments": "1st meeting at 42nd IETF-Chicago, IL; 2nd meeting at 43rd IETF-Orlando, FL; acronym has changed from webrepl to wrec on 1/14/99", "list_subscribe": "wrec-request@cs.utk.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://cs.utk.edu/pub/wrec", "type": "wg", "name": "Web Replication and Caching"}}, {"pk": 1416, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "findstuf", "comments": "1st meeting at 42nd IETF-Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Finding Stuff"}}, @@ -576,20 +576,20 @@ {"pk": 1425, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "impp@iastate.edu", "acronym": "impp", "comments": "", "list_subscribe": "impp-request@iastate.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.imppwg.org", "type": "wg", "name": "Instant Messaging and Presence Protocol"}}, {"pk": 1426, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "ruts", "comments": "1st meeting at 43rd IETF-Orlando, FL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Requirements for Unicast Transport/Sessions"}}, {"pk": 1427, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "pilc@ietf.org", "acronym": "pilc", "comments": "1st meeting at 43rd IETF - Orlando, FL; 2nd meeting at 44th IETF-Minneapolis, MN", "list_subscribe": "pilc-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pilc/", "type": "wg", "name": "Performance Implications of Link Characteristics"}}, -{"pk": 1428, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "eap@frascone.com", "acronym": "eap", "comments": "1st meeting at 43rd IETF-Orlando, FL", "list_subscribe": "eap-request@frascone.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://mail.frascone.com/pipermail/eap/", "type": "wg", "name": "Extensible Authentication Protocol"}}, +{"pk": 1428, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "eap@frascone.com", "acronym": "eap", "comments": "1st meeting at 43rd IETF-Orlando, FL", "list_subscribe": "eap-request@frascone.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://mail.frascone.com/pipermail/eap/", "type": "wg", "name": "Extensible Authentication Protocol"}}, {"pk": 1429, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "newsnmp", "comments": "1st meeting at 43rd IETF-Orlando, FL\r\n\r\nAD was Harald", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "New Work in the Network Management Area"}}, {"pk": 1430, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "cnrp-ietf@lists.netsol.com", "acronym": "cnrp", "comments": "1st meeting at 43rd IETF-Orlando, FL; 2nd meeting at 44th IETF-Minneapolis, MN; name changed from HFN to CNRP 3/2/99;3rd meeting at 45th IETF-Oslo, Norway", "list_subscribe": "cnrp-ietf-request@lists.netsol.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.netsol.com/archives/cnrp-ietf.html", "type": "wg", "name": "Common Name Resolution Protocol"}}, {"pk": 1431, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "ikstel", "comments": "1st meeting 43rd IETF-Orlando, FL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet Kermit Services/Outstanding Telnet Option"}}, {"pk": 1432, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "laser", "comments": "1st meeting at 43rd IETF-Orlando, FL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "LDAP Schema for E-mail Routing"}}, {"pk": 1433, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "drp", "comments": "1st meeting at 43rd IETF-Orlando, FL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Domain Registry Protocol"}}, -{"pk": 1434, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 6842, "parent": 1541, "list_email": "gsmp@ietf.org", "acronym": "gsmp", "comments": "1st meeting at 43rd IETF-Orlando, FL", "list_subscribe": "gsmp-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/gsmp/", "type": "wg", "name": "General Switch Management Protocol"}}, +{"pk": 1434, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1541, "list_email": "gsmp@ietf.org", "acronym": "gsmp", "comments": "1st meeting at 43rd IETF-Orlando, FL", "list_subscribe": "gsmp-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/gsmp/", "type": "wg", "name": "General Switch Management Protocol"}}, {"pk": 1435, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "authtime@nist.gov", "acronym": "stime", "comments": "1st meeting at 43rd IETF-Orlando, FL; 2nd meeting at 44th IETF-Minneapolis, MN; acronym changed from secntp stime 3/1/99", "list_subscribe": "listproc@nist.gov", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.nist.gov/itl/div896/emaildir/authtime/maillist.html", "type": "wg", "name": "Secure Network Time Protocol"}}, {"pk": 1436, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "ipsec-policy@vpnc.org", "acronym": "ipsp", "comments": "1st meeting at 44th IETF-Minneapolis, MN; 2nd meeting at 45th IETF-Oslo, Norway", "list_subscribe": "ipsec-policy-request@vpnc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.vpnc.org/ipsec-policy/", "type": "wg", "name": "IP Security Policy"}}, -{"pk": 1437, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 105519, "parent": 1324, "list_email": "rmt@ietf.org", "acronym": "rmt", "comments": "", "list_subscribe": "rmt-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rmt/", "type": "wg", "name": "Reliable Multicast Transport"}}, -{"pk": 1438, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "ietf-weird@imc.org", "acronym": "weird", "comments": "1st meeting at 44th IETF-Minneapolis, MN", "list_subscribe": "ietf-weird-request@imc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.imc.org/ietf-weird/", "type": "wg", "name": "Web Elucidation of Internet-Related Developments"}}, +{"pk": 1437, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "rmt@ietf.org", "acronym": "rmt", "comments": "", "list_subscribe": "rmt-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rmt/", "type": "wg", "name": "Reliable Multicast Transport"}}, +{"pk": 1438, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "ietf-weird@imc.org", "acronym": "weird", "comments": "1st meeting at 44th IETF-Minneapolis, MN", "list_subscribe": "ietf-weird-request@imc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.imc.org/ietf-weird/", "type": "wg", "name": "Web Elucidation of Internet-Related Developments"}}, {"pk": 1439, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "slums", "comments": "1st meeting at 44th IETF-Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Support for Lots of Unicast Multiplexed Sessions"}}, -{"pk": 1440, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 934, "list_email": "", "acronym": "usvarea", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ag", "name": "User Services Area Open Meeting"}}, -{"pk": 1441, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "ietf-fyiup@imc.org", "acronym": "fyiup", "comments": "1st meeting at 44th IETF-Minneapolis, MN", "list_subscribe": "ietf-fyiup-request@imc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.imc.org/ietf-fyiup/", "type": "wg", "name": "FYI Updates"}}, +{"pk": 1440, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "usvarea", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ag", "name": "User Services Area Open Meeting"}}, +{"pk": 1441, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1346, "list_email": "ietf-fyiup@imc.org", "acronym": "fyiup", "comments": "1st meeting at 44th IETF-Minneapolis, MN", "list_subscribe": "ietf-fyiup-request@imc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.imc.org/ietf-fyiup/", "type": "wg", "name": "FYI Updates"}}, {"pk": 1442, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "w3c-ietf-xmldsig@w3.org", "acronym": "xmldsig", "comments": "1st meeting at 44th IETF-Minneapolis, MN", "list_subscribe": "w3c-ietf-xmldsig-request@w3.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.w3.org/Archives/Public/w3c-ietf-xmldsig", "type": "wg", "name": "XML Digital Signatures"}}, {"pk": 1443, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "nits@merit.edu", "acronym": "nits", "comments": "1st meeting at 44th IETF-Minneapolis, MN; 2nd meeting at 45th IETF-Oslo. Became zeroconf WG", "list_subscribe": "nits-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.ietf.org/ietf-mail/archive/nits", "type": "wg", "name": "Networks in the Small - aka Home Networks"}}, {"pk": 1444, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "tfesp", "comments": "1st meeting at 44th IETF-Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Transport Friendly ESP"}}, @@ -600,39 +600,39 @@ {"pk": 1449, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "remboot", "comments": "1st meeting at 44th IETF-Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Remote Boot Protocol"}}, {"pk": 1450, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ifx@pwg.org", "acronym": "qualdocs", "comments": "1st meeting at 44th IETF-Minneapolis, MN; 2nd meeting at 46th IETF-Washington; changed name from IPP2IFAX; 3rd meeting at 47th IETF-Adelaide, AU", "list_subscribe": "majordomo@pwg.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.pwg.org/hypermail/ifx", "type": "wg", "name": "High Quality Document Transfer"}}, {"pk": 1451, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "vpim@ietf.org", "acronym": "vpim", "comments": "1st meeting at 44th IETF-Minneapolis, MN; 2nd meeting at 45th IETF-Oslo, Norway\r\nFTP Archive: ftp://ftp.ietf.org/ietf-mail-archive/rtgwg/", "list_subscribe": "vpim-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/vpim/", "type": "wg", "name": "Voice Profile for Internet Mail"}}, -{"pk": 1452, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 101568, "parent": 1193, "list_email": "dnsop@ietf.org", "acronym": "dnsop", "comments": "1st meeting at 44th IETF-Minneapolis, MN\r\n\r\nAD was Harald", "list_subscribe": "http://www.ietf.org/mailman/listinfo/dnsop", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dnsop", "type": "wg", "name": "Domain Name System Operations"}}, +{"pk": 1452, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "dnsop@ietf.org", "acronym": "dnsop", "comments": "1st meeting at 44th IETF-Minneapolis, MN\r\n\r\nAD was Harald", "list_subscribe": "http://www.ietf.org/mailman/listinfo/dnsop", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dnsop", "type": "wg", "name": "Domain Name System Operations"}}, {"pk": 1453, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "ietf-ipsra@vpnc.org", "acronym": "ipsra", "comments": "1st meeting at 44th IETF-Minneapolis, MN; 2nd meeting at 46th IETF-Washington, DC; 3rd meeting at 47th IETF-Adelaide, AU", "list_subscribe": "ietf-ipsra-request@vpnc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.vpnc.org/ietf-ipsra/mail-archive/", "type": "wg", "name": "IP Security Remote Access"}}, {"pk": 1454, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "decides", "comments": "1st meeting at 45th IETF-Oslo, Norway; 2nd meeting at 46th IETF-Washington, DC; full name is Deployment Considerations of Implementing Differentiated Services", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Deployment Considerations of Implementing Differen"}}, {"pk": 1455, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "netwklr", "comments": "1st meeting at 45th IETF-Oslo, Norway", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Layer"}}, {"pk": 1456, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "bgmp@ietf.org", "acronym": "bgmp", "comments": "1st meeting held at 45th IETF-Oslo, Norway\r\nFTP archive: ftp://ftp.ietf.org/ietf-mail-archive/bgmp/", "list_subscribe": "http://www1.ietf.org/mailman/listinfo/bgmp/", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/bgmp/", "type": "wg", "name": "Border Gateway Multicast Protocol"}}, {"pk": 1457, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "cm", "comments": "1st meeting at 45th IETF-Oslo, Norway", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Congestion Management"}}, -{"pk": 1458, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 6842, "parent": 1541, "list_email": "te-wg@ops.ietf.org", "acronym": "tewg", "comments": "1st meeting at 45th IETF-Oslo, Norway; 2nd meeting at 46th IETF-Washington, DC", "list_subscribe": "te-wg-request@ops.ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://ops.ietf.org/lists/te-wg", "type": "wg", "name": "Internet Traffic Engineering"}}, +{"pk": 1458, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1541, "list_email": "te-wg@ops.ietf.org", "acronym": "tewg", "comments": "1st meeting at 45th IETF-Oslo, Norway; 2nd meeting at 46th IETF-Washington, DC", "list_subscribe": "te-wg-request@ops.ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://ops.ietf.org/lists/te-wg", "type": "wg", "name": "Internet Traffic Engineering"}}, {"pk": 1459, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "lsd2", "comments": "1st meeting at 45th IETF-Oslo, Norway", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "LDAP Service Deployment - Take 2"}}, {"pk": 1460, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "", "acronym": "maestro", "comments": "1st meeting at 45th IETF-Oslo, Norway", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Multicast Addr. Exten. & Simple Transmitter Opti."}}, {"pk": 1461, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "zeroconf@merit.edu", "acronym": "zeroconf", "comments": "Was nits (Networks in the Small)", "list_subscribe": "zeroconf-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.merit.edu/mail.archives/zeroconf/", "type": "wg", "name": "Zero Configuration Networking"}}, {"pk": 1462, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "sip@ietf.org", "acronym": "sip", "comments": "", "list_subscribe": "sip-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sip/", "type": "wg", "name": "Session Initiation Protocol"}}, -{"pk": 1463, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 105519, "parent": 1324, "list_email": "tsvwg@ietf.org", "acronym": "tsvwg", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/tsvwg", "state": "active", "time": "2012-07-06 09:19:09", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/tsvwg/", "type": "wg", "name": "Transport Area Working Group"}}, +{"pk": 1463, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "tsvwg@ietf.org", "acronym": "tsvwg", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/tsvwg", "state": "active", "time": "2012-07-06 09:19:09", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/tsvwg/", "type": "wg", "name": "Transport Area Working Group"}}, {"pk": 1464, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "polterm", "comments": "1st meeting at 46th IETF-Washington, DC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Policy Terminology"}}, {"pk": 1465, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "cfgmgmt", "comments": "1st meeting at 46th IETF-Washington, DC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Configuration Management"}}, {"pk": 1466, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "ecm@aciri.org", "acronym": "ecm", "comments": "1st meeting at 46th IETF-Washington, DC", "list_subscribe": "ecm-request@aciri.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.ietf.org/ietf-mail-archive/", "type": "wg", "name": "Endpoint Congestion Management"}}, -{"pk": 1467, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "", "acronym": "srp", "comments": "1st meeting at 46th IETF-Washington, DC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Spatial Reuse Protocol"}}, -{"pk": 1468, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "syslog@ietf.org", "acronym": "syslog", "comments": "1st meeting at 46th IETF-Washington, DC; 2nd meeting at 47th IETF-Adelaide, AU", "list_subscribe": "syslog-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/syslog", "type": "wg", "name": "Security Issues in Network Event Logging"}}, -{"pk": 1469, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "l2tpext@ietf.org", "acronym": "l2tpext", "comments": "1st meeting at 46th IETF-Washington, DC", "list_subscribe": "l2tpext-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/l2tpext/", "type": "wg", "name": "Layer Two Tunneling Protocol Extensions"}}, +{"pk": 1467, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "srp", "comments": "1st meeting at 46th IETF-Washington, DC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Spatial Reuse Protocol"}}, +{"pk": 1468, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "syslog@ietf.org", "acronym": "syslog", "comments": "1st meeting at 46th IETF-Washington, DC; 2nd meeting at 47th IETF-Adelaide, AU", "list_subscribe": "syslog-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/syslog", "type": "wg", "name": "Security Issues in Network Event Logging"}}, +{"pk": 1469, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "l2tpext@ietf.org", "acronym": "l2tpext", "comments": "1st meeting at 46th IETF-Washington, DC", "list_subscribe": "l2tpext-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/l2tpext/", "type": "wg", "name": "Layer Two Tunneling Protocol Extensions"}}, {"pk": 1470, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "micropayments@elab.co.uk", "acronym": "micropay", "comments": "1st meeting at 46th IETF-Washington, DC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Micro Payments"}}, {"pk": 1471, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "spirits@lists.bell-lab.com", "acronym": "spirits", "comments": "", "list_subscribe": "spirits-request@lists.bell-labs.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.bell-labs.com/mailing-lists/spirits/", "type": "wg", "name": "Service in the PSTN/IN Requesting InTernet Service"}}, {"pk": 1472, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "gr303mib@tollbridgetech.com", "acronym": "gr303", "comments": "1st meeting at 46th IETF-Washington, DC", "list_subscribe": "gr303mib-request@tollbridgetech.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "GR-303 MIB"}}, {"pk": 1473, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "ecml", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Electronic Commerce Modeling Lanugage"}}, -{"pk": 1474, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 17253, "parent": 1324, "list_email": "rohc@ietf.org", "acronym": "rohc", "comments": "1st meeting at 46th IETF-Washington, DC; 2nd meeting at 47th IETF-Adelaide, AU", "list_subscribe": "rohc-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rohc/", "type": "wg", "name": "Robust Header Compression"}}, +{"pk": 1474, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "rohc@ietf.org", "acronym": "rohc", "comments": "1st meeting at 46th IETF-Washington, DC; 2nd meeting at 47th IETF-Adelaide, AU", "list_subscribe": "rohc-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rohc/", "type": "wg", "name": "Robust Header Compression"}}, {"pk": 1475, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "anycast", "comments": "1st meeting at 46th IETF-Washington, DC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Anycast"}}, {"pk": 1476, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "ippext", "comments": "1st meeting at 46th IETF-Washington, DC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPP Extensions"}}, {"pk": 1477, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "mmms", "comments": "1st meeting at 46th IETF-Washington, DC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Mobile Multimedia Messaging Service"}}, {"pk": 1478, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "idn@ops.ietf.org", "acronym": "idn", "comments": "1st meeting at 46th IETF-Washington, DC; changed area and reopened as a BOF for the 71st IETF-Philadelphia, PA", "list_subscribe": "idn-request@ops.ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ops.ietf.org/pub/lists/idn*", "type": "wg", "name": "Internationalized Domain Name"}}, -{"pk": 1479, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "dnsext@ietf.org", "acronym": "dnsext", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/dnsext", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dnsext/", "type": "wg", "name": "DNS Extensions"}}, +{"pk": 1479, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "dnsext@ietf.org", "acronym": "dnsext", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/dnsext", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dnsext/", "type": "wg", "name": "DNS Extensions"}}, {"pk": 1480, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "snmpconf@snmp.com", "acronym": "snmpconf", "comments": "", "list_subscribe": "snmpconf-request@snmp.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "mailto:snmpconf-request@snmp.com (index snmpconf in body)", "type": "wg", "name": "Configuration Management with SNMP"}}, {"pk": 1481, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "blocks", "comments": "1st meeting at 47th IETF-Adelaide, AU", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "An Application Protocol Framework & A Model Applic"}}, {"pk": 1482, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "sigprodi", "comments": "1st meeting at 47th IETF-Adelaide, AU-was cancelled", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Signaling Protocols Discussion"}}, {"pk": 1483, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "ietf-itrace@research.att.com", "acronym": "itrace", "comments": "1st meeting at 47th IETF-Adelaide, AU", "list_subscribe": "majordomo@research.att.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.research.att.com/lists/ietf-itrace", "type": "wg", "name": "ICMP Traceback"}}, -{"pk": 1484, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103264, "parent": 1541, "list_email": "ip-optical@lists.bell-labs.com", "acronym": "ipo", "comments": "1st meeting at 47th IETF-Adelaide, AU; 2nd meeting at 48th IETF-Pittsburgh, PA", "list_subscribe": "http://lists.bell-labs.com/mailman/listinfo/ip-optical", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.bell-labs.com/mailing-lists/ip-optical/", "type": "wg", "name": "IP over Optical"}}, +{"pk": 1484, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1541, "list_email": "ip-optical@lists.bell-labs.com", "acronym": "ipo", "comments": "1st meeting at 47th IETF-Adelaide, AU; 2nd meeting at 48th IETF-Pittsburgh, PA", "list_subscribe": "http://lists.bell-labs.com/mailman/listinfo/ip-optical", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.bell-labs.com/mailing-lists/ip-optical/", "type": "wg", "name": "IP over Optical"}}, {"pk": 1485, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "ips@ietf.org", "acronym": "ips", "comments": "1st meeting at 47th IETF-Adelaide, AU; 2nd meeting at 48th IETF-Pittsburgh, PA", "list_subscribe": "https://www1.ietf.org/mailman/listinfo/ips", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ips/", "type": "wg", "name": "IP Storage"}}, {"pk": 1486, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "b2bxml", "comments": "1st meeting at 47th IETF-Adelaide, AU", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Business to Business XML Data Commun. Strategies"}}, {"pk": 1487, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "vompls@lists.integralaccess.com", "acronym": "vompls", "comments": "1st meeting at 47th IETF-Adelaide, AU", "list_subscribe": "vompls-request@lists.integralaccess.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://sonic.sparklist.com/scripts/lyris.pl?enter=vompls", "type": "wg", "name": "Voice over IP over MPLS"}}, @@ -641,66 +641,66 @@ {"pk": 1490, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-spatial@research.nokia.com", "acronym": "spatial", "comments": "1st meeting at 47th IETF-Adelaide, AU; 2nd meeting at 48th IETF-Pittsburgh, PA", "list_subscribe": "majordom@oresearch.nokia.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www-nrc.nokia.com/mail-archive/ietf-spatial/", "type": "wg", "name": "Spatial Location"}}, {"pk": 1491, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "foglamps", "comments": "1st meeting at 47th IETF-Adelaide, AU", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Limitations of Multiple Addressing Realms"}}, {"pk": 1492, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "sip323", "comments": "1st meeting at 47th IETF-Adelaide, AU", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SIP and H.323 Interworking"}}, -{"pk": 1493, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 188, "parent": 934, "list_email": "iab-wireless-workshop-interest@ietf.org", "acronym": "iww", "comments": "1st meeting at 47th IETF-Adelaide, AU", "list_subscribe": "iab-wireless-workshop-interest-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IAB Wireless Workshop"}}, +{"pk": 1493, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "iab-wireless-workshop-interest@ietf.org", "acronym": "iww", "comments": "1st meeting at 47th IETF-Adelaide, AU", "list_subscribe": "iab-wireless-workshop-interest-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IAB Wireless Workshop"}}, {"pk": 1494, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "rperfman", "comments": "1st meeting at 47th IETF-Adelaide, AU", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Remote Performance Management"}}, {"pk": 1495, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "beepwg@lists.beepcore.org", "acronym": "beep", "comments": "", "list_subscribe": "beepwg-request@lists.beepcore.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.beepcore.org/mailman/listinfo/beepwg/", "type": "wg", "name": "Blocks Extensible Exchange Protocol"}}, -{"pk": 1496, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 19177, "parent": 1260, "list_email": "ietf-krb-wg@lists.anl.gov", "acronym": "krb-wg", "comments": "", "list_subscribe": "https://lists.anl.gov/mailman/listinfo/ietf-krb-wg", "state": "active", "time": "2012-10-01 09:27:45", "unused_tags": [], "list_archive": "https://lists.anl.gov/pipermail/ietf-krb-wg/", "type": "wg", "name": "Kerberos"}}, +{"pk": 1496, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "ietf-krb-wg@lists.anl.gov", "acronym": "krb-wg", "comments": "", "list_subscribe": "https://lists.anl.gov/mailman/listinfo/ietf-krb-wg", "state": "active", "time": "2012-10-01 09:27:45", "unused_tags": [], "list_archive": "https://lists.anl.gov/pipermail/ietf-krb-wg/", "type": "wg", "name": "Kerberos"}}, {"pk": 1497, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "ssm@ietf.org", "acronym": "ssm", "comments": "Old Archives at:\r\nftp://ftp.ietf.org/ietf-mail-archive/ssm/", "list_subscribe": "ssm-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ssm/", "type": "wg", "name": "Source-Specific Multicast"}}, -{"pk": 1498, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103264, "parent": 1541, "list_email": "ppvpn@nortelnetworks.com", "acronym": "ppvpn", "comments": "", "list_subscribe": "lyris@nortelnetworks.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://standards.nortelnetworks.com/ppvpn/index.htm", "type": "wg", "name": "Provider Provisioned Virtual Private Networks"}}, +{"pk": 1498, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1541, "list_email": "ppvpn@nortelnetworks.com", "acronym": "ppvpn", "comments": "", "list_subscribe": "lyris@nortelnetworks.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://standards.nortelnetworks.com/ppvpn/index.htm", "type": "wg", "name": "Provider Provisioned Virtual Private Networks"}}, {"pk": 1499, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "seamoby@ietf.org", "acronym": "seamoby", "comments": "Used to be craps (Common Radio Access Protocol Set).\r\n1st meeting at 48th IETF-Pittsburgh, PA.\r\n2nd meeting at 49th IETF-San Diego, CA", "list_subscribe": "seamoby-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/seamoby/", "type": "wg", "name": "Context Transfer, Handoff Candidate Discovery, and Dormant Mode Host Alerting"}}, {"pk": 1500, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "sgm", "comments": "1st meeting at 48th IETF-Pittsburgh, PA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Small Group Multicast"}}, {"pk": 1501, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "ietf-sacred@imc.org", "acronym": "sacred", "comments": "1st meeting at 48th IETF-Pittsburgh, PA", "list_subscribe": "ietf-sacred-request@imc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.imc.org/ietf-sacred/mail-archive/", "type": "wg", "name": "Securely Available Credentials"}}, {"pk": 1502, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "sin", "comments": "1st meeting at 48th IETF-Pittsburgh, PA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SIP/IN Interworking"}}, {"pk": 1503, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "ipobt", "comments": "1st meeting at 48th IETF-Pittsburgh, PA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IP over Bluetooth"}}, -{"pk": 1504, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 17253, "parent": 1324, "list_email": "rserpool@ietf.org", "acronym": "rserpool", "comments": "1st meeting at 48th IETF-Pittsburgh, PA", "list_subscribe": "rserpool-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rserpool/", "type": "wg", "name": "Reliable Server Pooling"}}, +{"pk": 1504, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "rserpool@ietf.org", "acronym": "rserpool", "comments": "1st meeting at 48th IETF-Pittsburgh, PA", "list_subscribe": "rserpool-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rserpool/", "type": "wg", "name": "Reliable Server Pooling"}}, {"pk": 1505, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "iporpr@ietf.org", "acronym": "iporpr", "comments": "1st meeting at 48th IETF-Pittsburgh, PA\r\nWas known as IPOPTR", "list_subscribe": "iporpr-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/iporpr/", "type": "wg", "name": "IP over Resilient Packet Rings"}}, {"pk": 1506, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-ldapbis@openldap.org", "acronym": "ldapbis", "comments": "1st meeting at 48th IETF-Pittsburgh, PA; 2nd meeting at 49th IETF-San Diego, CA", "list_subscribe": "ietf-ldapbis-request@openldap.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.openldap.org/lists/ietf-ldapbis/", "type": "wg", "name": "LDAP (v3) Revision"}}, {"pk": 1507, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "nim", "comments": "1st meeting at 48th IETF-Pittsburgh, PA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Information Model"}}, {"pk": 1508, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "ieps", "comments": "1st meeting at 48th IETF-Pittsburgh, PA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "International Emergency Preparedness Scheme"}}, {"pk": 1509, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "cnhhttp", "comments": "1st meeting at 48th IETF-Pittsburgh, PA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Content Negotiation Headers in HTTP"}}, {"pk": 1510, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "ietf-kink@vpnc.org", "acronym": "kink", "comments": "", "list_subscribe": "majordomo@vpnc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.vpnc.org/ietf-kink/", "type": "wg", "name": "Kerberized Internet Negotiation of Keys"}}, -{"pk": 1511, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "msec@ietf.org", "acronym": "msec", "comments": "1st meeting at 49th IETF-San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/msec", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/msec/", "type": "wg", "name": "Multicast Security"}}, +{"pk": 1511, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "msec@ietf.org", "acronym": "msec", "comments": "1st meeting at 49th IETF-San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/msec", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/msec/", "type": "wg", "name": "Multicast Security"}}, {"pk": 1512, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "sming@ops.ietf.org", "acronym": "sming", "comments": "1st meeting at 49th IETF-San Diego, CA", "list_subscribe": "sming-request@ops.ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://ops.ietf.org/lists/sming/", "type": "wg", "name": "Next Generation Structure of Management Information"}}, {"pk": 1513, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "rtfm2", "comments": "1st meeting at 49th IETF-San Diego, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Development of the Realtime Traffic Flow Measurement Architecture"}}, {"pk": 1514, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "domreg", "comments": "1st meeting at 49th IETF-San Diego, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Domain Registration Services"}}, {"pk": 1515, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-openproxy@imc.org", "acronym": "opes", "comments": "1st meeting at 49th IETF - San Diego, CA\r\nas Open Proxy Extended Services Architecture", "list_subscribe": "ietf-openproxy-request@imc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/newtrk", "type": "wg", "name": "Open Pluggable Edge Services"}}, {"pk": 1516, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "ceot", "comments": "1st meeting at 49th IETF - San Diego, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Circuit Emulation over Transport"}}, {"pk": 1517, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "telnet-wg@bsdi.com", "acronym": "telsec", "comments": "1st meeting at 49th IETF - San Diego, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Telnet Security"}}, -{"pk": 1518, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 104198, "parent": 1249, "list_email": "forces@ietf.org", "acronym": "forces", "comments": "1st meeting at 49th IETF - San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/forces", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/forces/", "type": "wg", "name": "Forwarding and Control Element Separation"}}, +{"pk": 1518, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "forces@ietf.org", "acronym": "forces", "comments": "1st meeting at 49th IETF - San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/forces", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/forces/", "type": "wg", "name": "Forwarding and Control Element Separation"}}, {"pk": 1519, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "cdn@ops.ietf.org", "acronym": "cdi", "comments": "1st meeting at 49th IETF-San Diego, CA; 2nd meeting at 50th IETF-Minneapolis, MN;acronym changed from CDNP to CDI for 50th IETF; 52nd IETF, Salt Lake City, Utah", "list_subscribe": "cdn-request@ops.ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ops.ietf.org/pub/lists/cdn.*", "type": "wg", "name": "Content Distribution Internetworking"}}, {"pk": 1520, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "sls", "comments": "1st meeting at 49th IETF - San Diego, CA", "list_subscribe": "http://www.ist-tequila.org/sls.html", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Service Level Specification and Usage"}}, {"pk": 1521, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "imxpbof", "comments": "1st meeting 49th IETF - San Diego, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IMXP"}}, {"pk": 1522, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "webi@equinix.com", "acronym": "webi", "comments": "", "list_subscribe": "webi-request@equinix.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.wrec.org/webi-archive/", "type": "wg", "name": "Web Intermediaries"}}, {"pk": 1523, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "c15n", "comments": "1st meeting at 49th IETF-San Diego, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Contextualization of Resolution"}}, -{"pk": 1524, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 104198, "parent": 1249, "list_email": "ccamp@ietf.org", "acronym": "ccamp", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ccamp", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ccamp/", "type": "wg", "name": "Common Control and Measurement Plane"}}, -{"pk": 1525, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 17253, "parent": 1324, "list_email": "midcom@ietf.org", "acronym": "midcom", "comments": "1st meeting at 49th IETF-San Diego, CA", "list_subscribe": "midcom-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/midcom/", "type": "wg", "name": "Middlebox Communication"}}, +{"pk": 1524, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "ccamp@ietf.org", "acronym": "ccamp", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ccamp", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ccamp/", "type": "wg", "name": "Common Control and Measurement Plane"}}, +{"pk": 1525, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "midcom@ietf.org", "acronym": "midcom", "comments": "1st meeting at 49th IETF-San Diego, CA", "list_subscribe": "midcom-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/midcom/", "type": "wg", "name": "Middlebox Communication"}}, {"pk": 1526, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "multi6@ops.ietf.org", "acronym": "multi6", "comments": "1st meeting at 49th IETF-San Diego, CA", "list_subscribe": "majordomo@ops.ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "https://ops.ietf.org/lists/multi6", "type": "wg", "name": "Site Multihoming in IPv6"}}, -{"pk": 1527, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "simple@ietf.org", "acronym": "simple", "comments": "1st meeting at 49th IETF-San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/simple", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/simple/", "type": "wg", "name": "SIP for Instant Messaging and Presence Leveraging Extensions"}}, +{"pk": 1527, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "simple@ietf.org", "acronym": "simple", "comments": "1st meeting at 49th IETF-San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/simple", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/simple/", "type": "wg", "name": "SIP for Instant Messaging and Presence Leveraging Extensions"}}, {"pk": 1528, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "prim@ml.fujitsulabs.com", "acronym": "prim", "comments": "1st meeting at 49th IETF-San Diego, CA\r\nChaired by Diacakis , Athanassios", "list_subscribe": "majordomo@ml.fujitsulabs.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.imppwg.org/prim/ml-archive/", "type": "wg", "name": "Presence and Instant Messaging Protocol"}}, {"pk": 1529, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "eos@ops.ietf.org", "acronym": "eos", "comments": "", "list_subscribe": "eos-request@ops.ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ops.ietf.org/pub/lists/eos*", "type": "wg", "name": "Evolution of SNMP"}}, {"pk": 1530, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "apexwg@lists.beepcore.org", "acronym": "apex", "comments": "", "list_subscribe": "apexwg-request@lists.beepcore.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.beepcore.org/mailman/listinfo/apexwg", "type": "wg", "name": "Application Exchange"}}, {"pk": 1531, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "https://www.ietf.org/mailman/listinfo/provreg", "acronym": "provreg", "comments": "1st meeting at 49th IETF in San Diego, called domreg.", "list_subscribe": "provreg@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/provreg/", "type": "wg", "name": "Provisioning Registry Protocol"}}, -{"pk": 1532, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "midtax", "comments": "1st meeting at 50th IETF - Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Middle box Taxonomy"}}, +{"pk": 1532, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "midtax", "comments": "1st meeting at 50th IETF - Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Middle box Taxonomy"}}, {"pk": 1533, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "furi", "comments": "1st meeting at 50th IETF - Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Future of Uniform Resource Identifiers"}}, {"pk": 1534, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "urp", "comments": "1st meeting at 50th IETF - Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "User Registration Protocol"}}, {"pk": 1535, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "ipac", "comments": "1st meeting at 50th IETF-Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet Personal Appliance Control"}}, {"pk": 1536, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "ptomaine@shrubbery.net", "acronym": "ptomaine", "comments": "1st meeting at 50th IETF-Minneapolis, MN", "list_subscribe": "majordomo@shrubbery.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.shrubbery.net/ptomaine", "type": "wg", "name": "Prefix Taxonomy Ongoing Measurement & Inter Network Experiment"}}, {"pk": 1537, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "nsis@ietf.org", "acronym": "nsis", "comments": "1st meeting at 50th IETF-Minneapolis, MN", "list_subscribe": "nsis-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/nsis/", "type": "wg", "name": "Next Steps in Signaling"}}, -{"pk": 1538, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2329, "parent": 1249, "list_email": "pwe3@ietf.org", "acronym": "pwe3", "comments": "1st meeting at 50th IETF-Minneapolis, MN", "list_subscribe": "pwe3-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pwe3/", "type": "wg", "name": "Pseudowire Emulation Edge to Edge"}}, -{"pk": 1539, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "ipoverib@ietf.org", "acronym": "ipoib", "comments": "1st meeting at 50th IETF-Minneapolis, MN\r\nwith the acronym of infinib (IP over InfiniBand plus MIBS", "list_subscribe": "ipoverib-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipoverib/", "type": "wg", "name": "IP over InfiniBand"}}, +{"pk": 1538, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "pwe3@ietf.org", "acronym": "pwe3", "comments": "1st meeting at 50th IETF-Minneapolis, MN", "list_subscribe": "pwe3-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pwe3/", "type": "wg", "name": "Pseudowire Emulation Edge to Edge"}}, +{"pk": 1539, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "ipoverib@ietf.org", "acronym": "ipoib", "comments": "1st meeting at 50th IETF-Minneapolis, MN\r\nwith the acronym of infinib (IP over InfiniBand plus MIBS", "list_subscribe": "ipoverib-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipoverib/", "type": "wg", "name": "IP over InfiniBand"}}, {"pk": 1540, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "hip_conclded", "comments": "1st meeting 50th IETF-Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Host Identity Payload"}}, {"pk": 1541, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 2, "list_email": "", "acronym": "sub", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2012-02-26 00:21:37", "unused_tags": [], "list_archive": "", "type": "area", "name": "Sub-IP Area"}}, -{"pk": 1542, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "sipping@ietf.org", "acronym": "sipping", "comments": "", "list_subscribe": "sipping-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sipping/", "type": "wg", "name": "Session Initiation Proposal Investigation"}}, -{"pk": 1543, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "geopriv@ietf.org", "acronym": "geopriv", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/geopriv", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/geopriv/", "type": "wg", "name": "Geographic Location/Privacy"}}, -{"pk": 1544, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "magma@ietf.org", "acronym": "magma", "comments": "", "list_subscribe": "magma-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/magma/", "type": "wg", "name": "Multicast & Anycast Group Membership"}}, +{"pk": 1542, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "sipping@ietf.org", "acronym": "sipping", "comments": "", "list_subscribe": "sipping-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sipping/", "type": "wg", "name": "Session Initiation Proposal Investigation"}}, +{"pk": 1543, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "geopriv@ietf.org", "acronym": "geopriv", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/geopriv", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/geopriv/", "type": "wg", "name": "Geographic Location/Privacy"}}, +{"pk": 1544, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "magma@ietf.org", "acronym": "magma", "comments": "", "list_subscribe": "magma-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/magma/", "type": "wg", "name": "Multicast & Anycast Group Membership"}}, {"pk": 1545, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "sasl@ietf.org", "acronym": "sasl", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/sasl", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sasl/", "type": "wg", "name": "Simple Authentication and Security Layer"}}, -{"pk": 1546, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 105682, "parent": 1193, "list_email": "ipfix@ietf.org", "acronym": "ipfix", "comments": "", "list_subscribe": "http://www.ietf.org/mailman/listinfo/ipfix", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipfix", "type": "wg", "name": "IP Flow Information Export"}}, -{"pk": 1547, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "ipv6@ietf.org", "acronym": "ipv6", "comments": "", "list_subscribe": "https://www1.ietf.org/mailman/listinfo/ipv6", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipv6/", "type": "wg", "name": "IP Version 6 Working Group"}}, +{"pk": 1546, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "ipfix@ietf.org", "acronym": "ipfix", "comments": "", "list_subscribe": "http://www.ietf.org/mailman/listinfo/ipfix", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipfix", "type": "wg", "name": "IP Flow Information Export"}}, +{"pk": 1547, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "ipv6@ietf.org", "acronym": "ipv6", "comments": "", "list_subscribe": "https://www1.ietf.org/mailman/listinfo/ipv6", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipv6/", "type": "wg", "name": "IP Version 6 Working Group"}}, {"pk": 1548, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "inch@nic.surfnet.nl", "acronym": "inch", "comments": "", "list_subscribe": "listserv@nic.surfnet.nl", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://listserv.surfnet.nl/archives/inch.html", "type": "wg", "name": "Extended Incident Handling"}}, {"pk": 1549, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "irnss", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet Resource Name Search Service"}}, -{"pk": 1550, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "pana@ietf.org", "acronym": "pana", "comments": "52nd IETF, Salt Lake City, Utah", "list_subscribe": "https://www1.ietf.org/mailman/listinfo/pana", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pana/", "type": "wg", "name": "Protocol for carrying Authentication for Network Access"}}, +{"pk": 1550, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "pana@ietf.org", "acronym": "pana", "comments": "52nd IETF, Salt Lake City, Utah", "list_subscribe": "https://www1.ietf.org/mailman/listinfo/pana", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pana/", "type": "wg", "name": "Protocol for carrying Authentication for Network Access"}}, {"pk": 1551, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "intloc@ops.ietf.org", "acronym": "intloc", "comments": "52nd IETF - Salt Lake City, UT", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internationalization and Localization of Internet Protocols"}}, -{"pk": 1553, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103264, "parent": 1541, "list_email": "", "acronym": "mplsoam", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "MPLS Maintenance Mechanisms"}}, +{"pk": 1553, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1541, "list_email": "", "acronym": "mplsoam", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "MPLS Maintenance Mechanisms"}}, {"pk": 1554, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ndmp-tech@ndmp.org", "acronym": "ndmp", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Data Management Protocol"}}, {"pk": 1555, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "ippt", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IP Path Tracing"}}, {"pk": 1556, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "ieprep@ietf.org", "acronym": "ieprep", "comments": "", "list_subscribe": "ieprep-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ieprep/", "type": "wg", "name": "Internet Emergency Preparedness"}}, @@ -711,290 +711,290 @@ {"pk": 1561, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "keydist@cafax.se", "acronym": "siked", "comments": "1st meeting - 53rd IETF in Minneapolis, MN.", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Secure Internet Key Distribution"}}, {"pk": 1562, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "kwns", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Keywords Naming Services"}}, {"pk": 1563, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "crisp@ietf.org", "acronym": "crisp", "comments": "1st meeting at 53rd IETF in Minneapolis, MN", "list_subscribe": "https://www.ietf.org/mailman/listinfo/crisp", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/crisp", "type": "wg", "name": "Cross Registry Information Service Protocol"}}, -{"pk": 1564, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 6699, "parent": 1193, "list_email": "psamp@ietf.org", "acronym": "psamp", "comments": "1st meeting at 53rd IETF in Minneapolis, MN", "list_subscribe": "psamp-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/psamp/", "type": "wg", "name": "Packet Sampling"}}, +{"pk": 1564, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "psamp@ietf.org", "acronym": "psamp", "comments": "1st meeting at 53rd IETF in Minneapolis, MN", "list_subscribe": "psamp-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/psamp/", "type": "wg", "name": "Packet Sampling"}}, {"pk": 1565, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "monet@nal.motlabs.com", "acronym": "monet", "comments": "1st meeting at 53rd IETF in Minneapolis, MN", "list_subscribe": "http://www.nal.motlabs.com/mailman/listinfo/monet", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.nal.motlabs.com/mailman/listinfo/monet", "type": "wg", "name": "Mobile Networks"}}, -{"pk": 1566, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "speechsc@ietf.org", "acronym": "speechsc", "comments": "1st meeting at 53rd IETF in Minneapolis, MN. Was called Control of ASR and TTS Servers (cats)", "list_subscribe": "https://www.ietf.org/mailman/listinfo/speechsc", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/speechsc/", "type": "wg", "name": "Speech Services Control"}}, +{"pk": 1566, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "speechsc@ietf.org", "acronym": "speechsc", "comments": "1st meeting at 53rd IETF in Minneapolis, MN. Was called Control of ASR and TTS Servers (cats)", "list_subscribe": "https://www.ietf.org/mailman/listinfo/speechsc", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/speechsc/", "type": "wg", "name": "Speech Services Control"}}, {"pk": 1567, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "rpsec@ietf.org", "acronym": "rpsec", "comments": "1st meeting at 53rd IETF in Minneapolis, MN", "list_subscribe": "rpsec-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rpsec/", "type": "wg", "name": "Routing Protocol Security Requirements"}}, -{"pk": 1568, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "ietf-nomcom@lists.elistx.com", "acronym": "nomcom", "comments": "", "list_subscribe": "ietf-nomcom-request@lists.elistx.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.elistx.com/archives/ietf-nomcom/", "type": "wg", "name": "Operation of the IESG/IAB Nominating and Recall Committees"}}, +{"pk": 1568, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1008, "list_email": "ietf-nomcom@lists.elistx.com", "acronym": "nomcom", "comments": "", "list_subscribe": "ietf-nomcom-request@lists.elistx.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.elistx.com/archives/ietf-nomcom/", "type": "wg", "name": "Operation of the IESG/IAB Nominating and Recall Committees"}}, {"pk": 1569, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "xmppwg@xmpp.org", "acronym": "xmpp-old", "comments": "First meeting at the 54th IETF in Yokohama, Japan.", "list_subscribe": "xmppwg-request@xmpp.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://mail.jabber.org/pipermail/xmppwg/", "type": "wg", "name": "Extensible Messaging and Presence Protocol"}}, {"pk": 1570, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "ietf-send@standards.ericsson.net", "acronym": "send", "comments": "First meeting at the 54th IETF in Yokohama, Japan.", "list_subscribe": "Majordomo@standards.ericsson.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://standards.ericsson.net/lists/ietf-send/threads.html", "type": "wg", "name": "Securing Neighbor Discovery"}}, -{"pk": 1571, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 110856, "parent": 1324, "list_email": "dccp@ietf.org", "acronym": "dccp", "comments": "", "list_subscribe": "dccp-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dccp/", "type": "wg", "name": "Datagram Congestion Control Protocol"}}, -{"pk": 1572, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "ipr-wg@ietf.org", "acronym": "ipr", "comments": "", "list_subscribe": "ipr-wg-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipr-wg/", "type": "wg", "name": "Intellectual Property Rights"}}, +{"pk": 1571, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "dccp@ietf.org", "acronym": "dccp", "comments": "", "list_subscribe": "dccp-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dccp/", "type": "wg", "name": "Datagram Congestion Control Protocol"}}, +{"pk": 1572, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1008, "list_email": "ipr-wg@ietf.org", "acronym": "ipr", "comments": "", "list_subscribe": "ipr-wg-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipr-wg/", "type": "wg", "name": "Intellectual Property Rights"}}, {"pk": 1573, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "rddp@ietf.org", "acronym": "rddp", "comments": "1st Meeting at the 54th IETF in Yokohama, Japan", "list_subscribe": "rddp-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rddp/", "type": "wg", "name": "Remote Direct Data Placement"}}, {"pk": 1574, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "tist@cisco.com", "acronym": "tist", "comments": "1st Meeting at the 54th IETF in Yokohama, Japan", "list_subscribe": "mailer@cisco.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.mail-archive.com/tist%40external.cisco.com/", "type": "wg", "name": "Topology-Insensitive Service Traversal"}}, -{"pk": 1575, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 105682, "parent": 1193, "list_email": "netconf@ietf.org", "acronym": "netconf", "comments": "1st meeting at the 54th IETF in Yokohama, Japan", "list_subscribe": "https://www.ietf.org/mailman/listinfo/netconf", "state": "active", "time": "2012-09-20 09:57:02", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/netconf/", "type": "wg", "name": "Network Configuration"}}, -{"pk": 1576, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "nemo@ietf.org", "acronym": "nemo", "comments": "1st meeting at the 54 IETF in Yokohama, Japan", "list_subscribe": "nemo-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/nemo/", "type": "wg", "name": "Network Mobility"}}, -{"pk": 1578, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 101568, "parent": 1193, "list_email": "v6ops@ietf.org", "acronym": "v6ops", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/v6ops", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/v6ops/", "type": "wg", "name": "IPv6 Operations"}}, +{"pk": 1575, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "netconf@ietf.org", "acronym": "netconf", "comments": "1st meeting at the 54th IETF in Yokohama, Japan", "list_subscribe": "https://www.ietf.org/mailman/listinfo/netconf", "state": "active", "time": "2012-09-20 09:57:02", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/netconf/", "type": "wg", "name": "Network Configuration"}}, +{"pk": 1576, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "nemo@ietf.org", "acronym": "nemo", "comments": "1st meeting at the 54 IETF in Yokohama, Japan", "list_subscribe": "nemo-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/nemo/", "type": "wg", "name": "Network Mobility"}}, +{"pk": 1578, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "v6ops@ietf.org", "acronym": "v6ops", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/v6ops", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/v6ops/", "type": "wg", "name": "IPv6 Operations"}}, {"pk": 1579, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "discuss@jxta.org mailing", "acronym": "jxta", "comments": "1st meeting at 55th IETF in Atlanta, GA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "JXTA"}}, {"pk": 1580, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "ipseckey@ietf.org", "acronym": "ipseckey", "comments": "1st meeting at the 55th IETF in Atlanta, GA", "list_subscribe": "ipseckey-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipseckey/", "type": "wg", "name": "IPSEC KEYing information resource record"}}, {"pk": 1581, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "lemonade@ietf.org", "acronym": "lemonade", "comments": "1st meeting at the 54th IETF in Yokohama, Japan", "list_subscribe": "lemonade-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/lemonade/", "type": "wg", "name": "Enhancements to Internet email to Support Diverse Service Environments"}}, {"pk": 1582, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "zerouter@internet.motlabs.com", "acronym": "zerouter", "comments": "1st Meeting at 55th IETF in Atlanta, GA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://internet.motlabs.com/mailman/listinfo/zerouter", "type": "wg", "name": "Zeroconf Router"}}, {"pk": 1583, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "trigtran@ietf.org", "acronym": "trigtran", "comments": "1st meeting at 55th IETF in Atlanta, GA", "list_subscribe": "trigtran-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/trigtran/", "type": "wg", "name": "Triggers for Transport"}}, -{"pk": 1584, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 101568, "parent": 1193, "list_email": "grow@ietf.org", "acronym": "grow", "comments": "1st meeting at the 56th IETF in San Francisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/grow", "state": "active", "time": "2012-02-01 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/grow", "type": "wg", "name": "Global Routing Operations"}}, -{"pk": 1585, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "problem-statement@alvestrand.no", "acronym": "problem", "comments": "1st meeting at the 56th IETF in San Francisco, CA", "list_subscribe": "problem-statement-request@alvestrand.no", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.alvestrand.no/pipermail/problem-statement/", "type": "wg", "name": "Problem Statement"}}, +{"pk": 1584, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "grow@ietf.org", "acronym": "grow", "comments": "1st meeting at the 56th IETF in San Francisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/grow", "state": "active", "time": "2012-02-01 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/grow", "type": "wg", "name": "Global Routing Operations"}}, +{"pk": 1585, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1008, "list_email": "problem-statement@alvestrand.no", "acronym": "problem", "comments": "1st meeting at the 56th IETF in San Francisco, CA", "list_subscribe": "problem-statement-request@alvestrand.no", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.alvestrand.no/pipermail/problem-statement/", "type": "wg", "name": "Problem Statement"}}, {"pk": 1586, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "pads", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Path-Decoupled Signaling"}}, {"pk": 1587, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "intersec", "comments": "1st meeting at 56th IETF in San Francisco, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Transport Service at Intermediary"}}, {"pk": 1588, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "plpmtud", "comments": "1st meeting at 56th IETF in San Francisco, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Packetization Layer Path MTU Discovery"}}, {"pk": 1589, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "nsiim", "comments": "1st meeting at th 56th IETF in San Francisco, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Next Steps in IP Mobility"}}, {"pk": 1590, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "ietf-enroll@mit.edu", "acronym": "enroll", "comments": "1st meeting at 57th IETF in Vienna, Austria; 2nd meeting at 58th IETF, Minneapolis, MN", "list_subscribe": "ietf-enroll-request@mit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://mailman.mit.edu/pipermail/ietf-enroll/", "type": "wg", "name": "Credential and Provisioning"}}, -{"pk": 1591, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "wgchairs-training@ops.ietf.org", "acronym": "edu", "comments": "1st meeting at 57th IETF-Vienna, Austria; 2nd meeting at 64th IETF-Vancouver, BC", "list_subscribe": "majordomo@ops.ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://ops.ietf.org/lists/wgchairs-training/", "type": "team", "name": "Education"}}, +{"pk": 1591, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1008, "list_email": "wgchairs-training@ops.ietf.org", "acronym": "edu", "comments": "1st meeting at 57th IETF-Vienna, Austria; 2nd meeting at 64th IETF-Vancouver, BC", "list_subscribe": "majordomo@ops.ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://ops.ietf.org/lists/wgchairs-training/", "type": "team", "name": "Education"}}, {"pk": 1592, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "mtu@psc.edu", "acronym": "pmutd", "comments": "", "list_subscribe": "majordomo@psc.edu with", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.psc.edu/~mathis/MTU/mbox.txt", "type": "wg", "name": "Path Maximum Transmission Unit Discovery"}}, -{"pk": 1593, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2329, "parent": 1249, "list_email": "l2vpn@ietf.org", "acronym": "l2vpn", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/l2vpn", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/l2vpn/", "type": "wg", "name": "Layer 2 Virtual Private Networks"}}, -{"pk": 1594, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2329, "parent": 1249, "list_email": "l3vpn@ietf.org", "acronym": "l3vpn", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/l3vpn", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/l3vpn/", "type": "wg", "name": "Layer 3 Virtual Private Networks"}}, -{"pk": 1595, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "ietf-quality@bogus.com", "acronym": "coach", "comments": "1st meeting at the 57th IETF in Vienna, Austria", "list_subscribe": "majordomo@psg.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://psg.com/lists/ietf-quality", "type": "wg", "name": "Comprehensive apprOACH to quality"}}, -{"pk": 1596, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 100664, "parent": 1052, "list_email": "mip4@ietf.org", "acronym": "mip4", "comments": "1st meeting at the 57th IETF in Vienna, Austria", "list_subscribe": "mip4-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mip4/", "type": "wg", "name": "Mobility for IPv4"}}, -{"pk": 1597, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "mip6@ietf.org", "acronym": "mip6", "comments": "1st meeting at the 57th IETF in Vienna, Austria", "list_subscribe": "https://www.ietf.org/mailman/listinfo/mip6", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mip6/", "type": "wg", "name": "Mobility for IPv6"}}, -{"pk": 1598, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "mipshop@ietf.org", "acronym": "mipshop", "comments": "1st meeting at the 57th IETF in Vienna, Austria", "list_subscribe": "mipshop-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mipshop/", "type": "wg", "name": "Mobility for IP: Performance, Signaling and Handoff Optimization"}}, -{"pk": 1599, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 101568, "parent": 1193, "list_email": "opsec@ietf.org", "acronym": "opsec", "comments": "email archives 2007 and prior: http://ops.ietf.org/lists/opsec/\r\n\r\n1st meeting at the 57th IETF in Vienna, Austria; 2nd meeting at 59th IETF-Seoul, Korea; 3rd meeting at 60th IETF - San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/opsec", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/opsec/", "type": "wg", "name": "Operational Security Capabilities for IP Network Infrastructure"}}, -{"pk": 1600, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 6699, "parent": 1193, "list_email": "capwap@frascone.com", "acronym": "capwap", "comments": "1st meeting at the 57th IETF in Vienna, Austria", "list_subscribe": "http://lists.frascone.com/mailman/listinfo/capwap", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.frascone.com/pipermail/capwap", "type": "wg", "name": "Control And Provisioning of Wireless Access Points"}}, -{"pk": 1601, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "xcon@ietf.org", "acronym": "xcon", "comments": "1st meeting at the 57th IETF in Vienna, Austria", "list_subscribe": "https://www.ietf.org/mailman/listinfo/xcon", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/xcon/", "type": "wg", "name": "Centralized Conferencing"}}, +{"pk": 1593, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "l2vpn@ietf.org", "acronym": "l2vpn", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/l2vpn", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/l2vpn/", "type": "wg", "name": "Layer 2 Virtual Private Networks"}}, +{"pk": 1594, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "l3vpn@ietf.org", "acronym": "l3vpn", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/l3vpn", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/l3vpn/", "type": "wg", "name": "Layer 3 Virtual Private Networks"}}, +{"pk": 1595, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1008, "list_email": "ietf-quality@bogus.com", "acronym": "coach", "comments": "1st meeting at the 57th IETF in Vienna, Austria", "list_subscribe": "majordomo@psg.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://psg.com/lists/ietf-quality", "type": "wg", "name": "Comprehensive apprOACH to quality"}}, +{"pk": 1596, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "mip4@ietf.org", "acronym": "mip4", "comments": "1st meeting at the 57th IETF in Vienna, Austria", "list_subscribe": "mip4-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mip4/", "type": "wg", "name": "Mobility for IPv4"}}, +{"pk": 1597, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "mip6@ietf.org", "acronym": "mip6", "comments": "1st meeting at the 57th IETF in Vienna, Austria", "list_subscribe": "https://www.ietf.org/mailman/listinfo/mip6", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mip6/", "type": "wg", "name": "Mobility for IPv6"}}, +{"pk": 1598, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "mipshop@ietf.org", "acronym": "mipshop", "comments": "1st meeting at the 57th IETF in Vienna, Austria", "list_subscribe": "mipshop-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mipshop/", "type": "wg", "name": "Mobility for IP: Performance, Signaling and Handoff Optimization"}}, +{"pk": 1599, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "opsec@ietf.org", "acronym": "opsec", "comments": "email archives 2007 and prior: http://ops.ietf.org/lists/opsec/\r\n\r\n1st meeting at the 57th IETF in Vienna, Austria; 2nd meeting at 59th IETF-Seoul, Korea; 3rd meeting at 60th IETF - San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/opsec", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/opsec/", "type": "wg", "name": "Operational Security Capabilities for IP Network Infrastructure"}}, +{"pk": 1600, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "capwap@frascone.com", "acronym": "capwap", "comments": "1st meeting at the 57th IETF in Vienna, Austria", "list_subscribe": "http://lists.frascone.com/mailman/listinfo/capwap", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.frascone.com/pipermail/capwap", "type": "wg", "name": "Control And Provisioning of Wireless Access Points"}}, +{"pk": 1601, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "xcon@ietf.org", "acronym": "xcon", "comments": "1st meeting at the 57th IETF in Vienna, Austria", "list_subscribe": "https://www.ietf.org/mailman/listinfo/xcon", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/xcon/", "type": "wg", "name": "Centralized Conferencing"}}, {"pk": 1602, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "ispmon", "comments": "1st meeting at 57th IETF in Vienna, Austria", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Monitoring Infrastructure Deployment"}}, {"pk": 1603, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "ddbof", "comments": "1st meeting at the 57th IETF in Vienna, Austria", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Device Discovery"}}, -{"pk": 1604, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21072, "parent": 934, "list_email": "ipdvb@erg.abdn.ac.uk", "acronym": "ipdvb", "comments": "1st meeting at 57th IETF in Vienna, Austria", "list_subscribe": "majordomo@erg.abdn.ac.uk", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.erg.abdn.ac.uk/ipdvb/archive/", "type": "wg", "name": "IP over DVB"}}, +{"pk": 1604, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ipdvb@erg.abdn.ac.uk", "acronym": "ipdvb", "comments": "1st meeting at 57th IETF in Vienna, Austria", "list_subscribe": "majordomo@erg.abdn.ac.uk", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.erg.abdn.ac.uk/ipdvb/archive/", "type": "wg", "name": "IP over DVB"}}, {"pk": 1605, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "mtp@shepfarm.com", "acronym": "mlm", "comments": "1st meeting at 57th IETF in Vienna, Austria", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.shepfarm.com/mailman/listinfo/mtp", "type": "wg", "name": "Multicast Last Mile"}}, {"pk": 1606, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "alias", "comments": "1st meeting at 57th IETF in Vienna, Austria", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Access Link Intermediaries Assisting Services"}}, -{"pk": 1607, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "dna@eng.monash.edu.au", "acronym": "dna", "comments": "1st meeting at th 57th IETF in Vienna, Austria", "list_subscribe": "majordomo@ecselists.eng.monash.edu.au", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://ecselists.eng.monash.edu.au/~warchive/dna/", "type": "wg", "name": "Detecting Network Attachment"}}, +{"pk": 1607, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "dna@eng.monash.edu.au", "acronym": "dna", "comments": "1st meeting at th 57th IETF in Vienna, Austria", "list_subscribe": "majordomo@ecselists.eng.monash.edu.au", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://ecselists.eng.monash.edu.au/~warchive/dna/", "type": "wg", "name": "Detecting Network Attachment"}}, {"pk": 1608, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "pmtud@ietf.org", "acronym": "pmtud", "comments": "", "list_subscribe": "pmtud-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pmtud/", "type": "wg", "name": "Path MTU Discovery"}}, -{"pk": 1609, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 6699, "parent": 1193, "list_email": "imss@ietf.org", "acronym": "imss", "comments": "", "list_subscribe": "https://www1.ietf.org/mailman/listinfo/imss", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/imss/", "type": "wg", "name": "Internet and Management Support for Storage"}}, -{"pk": 1610, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "saad@ietf.org", "acronym": "saad", "comments": "", "list_subscribe": "http://www.ietf.org/mail-archive/web/saad/index.html", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.ietf.org/ietf-mail-archive/saad", "type": "wg", "name": "Scope Addressing Architecture Discussion"}}, -{"pk": 1611, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 19483, "parent": 934, "list_email": "ltans@ietf.org", "acronym": "ltans", "comments": "", "list_subscribe": "http://www.ietf.org/mailman/listinfo/ltans", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ltans/", "type": "wg", "name": "Long-Term Archive and Notary Services"}}, -{"pk": 1612, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 105682, "parent": 1193, "list_email": "radext@ietf.org", "acronym": "radext", "comments": "1st meeting at the 58th IETF in Minneapolis, MN; 2nd meeting at 60th IETF - San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/radext", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/radext/", "type": "wg", "name": "RADIUS EXTensions"}}, +{"pk": 1609, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "imss@ietf.org", "acronym": "imss", "comments": "", "list_subscribe": "https://www1.ietf.org/mailman/listinfo/imss", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/imss/", "type": "wg", "name": "Internet and Management Support for Storage"}}, +{"pk": 1610, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1008, "list_email": "saad@ietf.org", "acronym": "saad", "comments": "", "list_subscribe": "http://www.ietf.org/mail-archive/web/saad/index.html", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.ietf.org/ietf-mail-archive/saad", "type": "wg", "name": "Scope Addressing Architecture Discussion"}}, +{"pk": 1611, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ltans@ietf.org", "acronym": "ltans", "comments": "", "list_subscribe": "http://www.ietf.org/mailman/listinfo/ltans", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ltans/", "type": "wg", "name": "Long-Term Archive and Notary Services"}}, +{"pk": 1612, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "radext@ietf.org", "acronym": "radext", "comments": "1st meeting at the 58th IETF in Minneapolis, MN; 2nd meeting at 60th IETF - San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/radext", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/radext/", "type": "wg", "name": "RADIUS EXTensions"}}, {"pk": 1613, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "pki4ipsec@icsalabs.com", "acronym": "pki4ipsec", "comments": "1st meeting at 58th IETF-Minneapolis, MN", "list_subscribe": "http://honor.icsalabs.com/mailman/listinfo/pki4ipsec", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://honor.icsalabs.com/mailman/listinfo/pki4ipsec", "type": "wg", "name": "Profiling Use of PKI in IPSEC"}}, -{"pk": 1614, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "newtrk@lists.uoregon.edu", "acronym": "newtrk", "comments": "1st meeting at 58th IETF-Minneapolis, MN; 2nd meeting at 59th IETF-Seoul, Korea", "list_subscribe": "newtrk-request@lists.uoregon.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/newtrk", "type": "wg", "name": "New IETF Standards Track Discussion"}}, +{"pk": 1614, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1008, "list_email": "newtrk@lists.uoregon.edu", "acronym": "newtrk", "comments": "1st meeting at 58th IETF-Minneapolis, MN; 2nd meeting at 59th IETF-Seoul, Korea", "list_subscribe": "newtrk-request@lists.uoregon.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/newtrk", "type": "wg", "name": "New IETF Standards Track Discussion"}}, {"pk": 1615, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "iea", "comments": "1st meeting at 58th IETF-Minneapolis, MN; 2nd meeting at 59th IETF-Seoul, Korea", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internationalizing Email Address"}}, {"pk": 1616, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "hipbof", "comments": "1st meeting at 58th IETF-Minneapolis, MN; 2nd meeting at 59th IETF-Seoul, Korea", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Host Identity Protocol BOF"}}, {"pk": 1617, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "mobike@machshav.com", "acronym": "mobike", "comments": "1st meeting at 58th IETF-Minneapolis, MN;2nd meeting at 59th IETF-Seoul, Korea", "list_subscribe": "https://www.machshav.com/mailman/listinfo.cgi/mobike", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "https://www.machshav.com/pipermail/mobike/", "type": "wg", "name": "IKEv2 Mobility and Multihoming"}}, {"pk": 1618, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "sbsm", "comments": "1st meeting 58th IETF-Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Session Based Security Model for SNMPv3"}}, -{"pk": 1619, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2329, "parent": 1249, "list_email": "rtgwg@ietf.org", "acronym": "rtgwg", "comments": "", "list_subscribe": "rtgwg-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rtgwg/", "type": "wg", "name": "Routing Area Working Group"}}, -{"pk": 1620, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 110856, "parent": 1324, "list_email": "tcpm@ietf.org", "acronym": "tcpm", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/tcpm", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/tcpm/", "type": "wg", "name": "TCP Maintenance and Minor Extensions"}}, -{"pk": 1621, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "icar@ietf.org", "acronym": "icar", "comments": "1st meeting at 59th IETF-Seoul, Korea", "list_subscribe": "icar-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/icar/", "type": "wg", "name": "Improved Cross-Area Review"}}, +{"pk": 1619, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "rtgwg@ietf.org", "acronym": "rtgwg", "comments": "", "list_subscribe": "rtgwg-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rtgwg/", "type": "wg", "name": "Routing Area Working Group"}}, +{"pk": 1620, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "tcpm@ietf.org", "acronym": "tcpm", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/tcpm", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/tcpm/", "type": "wg", "name": "TCP Maintenance and Minor Extensions"}}, +{"pk": 1621, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1008, "list_email": "icar@ietf.org", "acronym": "icar", "comments": "1st meeting at 59th IETF-Seoul, Korea", "list_subscribe": "icar-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/icar/", "type": "wg", "name": "Improved Cross-Area Review"}}, {"pk": 1622, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "letic", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Link-Enhancing Transport Intermediary Communication"}}, {"pk": 1623, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-mxcomp@imc.org", "acronym": "marid", "comments": "1st meeting at the 59th IETF-Seoul, Korea", "list_subscribe": "ietf-mxcomp-request@imc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.imc.org/ietf-mxcomp/index.html", "type": "wg", "name": "MTA Authorization Records in DNS"}}, {"pk": 1624, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "iiri", "comments": "1st meeting at 59th IETF-Seoul, Korea", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet Information Retrieval Infrastructure"}}, -{"pk": 1625, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "genarea", "comments": "", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ag", "name": "General Area Open Meeting"}}, -{"pk": 1626, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "hipsec@ietf.org", "acronym": "hip", "comments": "hipsec-request@ietf.org (old subscription method)", "list_subscribe": "http://www.ietf.org/mailman/listinfo/hipsec", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/hipsec/", "type": "wg", "name": "Host Identity Protocol"}}, +{"pk": 1625, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "genarea", "comments": "", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ag", "name": "General Area Open Meeting"}}, +{"pk": 1626, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "hipsec@ietf.org", "acronym": "hip", "comments": "hipsec-request@ietf.org (old subscription method)", "list_subscribe": "http://www.ietf.org/mailman/listinfo/hipsec", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/hipsec/", "type": "wg", "name": "Host Identity Protocol"}}, {"pk": 1627, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "atom-syntax@imc.org", "acronym": "atompub", "comments": "", "list_subscribe": "atom-syntax-request@imc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.imc.org/atom-syntax/mail-archive/", "type": "wg", "name": "Atom Publishing Format and Protocol"}}, -{"pk": 1628, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 104198, "parent": 1249, "list_email": "rtg-bfd@ietf.org", "acronym": "bfd", "comments": "", "list_subscribe": "rtg-bfd-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rtg-bfd/", "type": "wg", "name": "Bidirectional Forwarding Detection"}}, +{"pk": 1628, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "rtg-bfd@ietf.org", "acronym": "bfd", "comments": "", "list_subscribe": "rtg-bfd-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rtg-bfd/", "type": "wg", "name": "Bidirectional Forwarding Detection"}}, {"pk": 1629, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "perm", "comments": "1st meeting at 60th IETF - San Diego, CA; 2nd meeting at 61st IEFT - Washington, DC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Protected Entertainment Rights Management"}}, -{"pk": 1630, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 104198, "parent": 1249, "list_email": "pce@ietf.org", "acronym": "pce", "comments": "1st meeting at 60th IETF - San Diego, CA; 2nd meeting at 61st IETF - Washington, DC", "list_subscribe": "http://www.ietf.org/mailman/listinfo/pce", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pce/", "type": "wg", "name": "Path Computation Element"}}, +{"pk": 1630, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "pce@ietf.org", "acronym": "pce", "comments": "1st meeting at 60th IETF - San Diego, CA; 2nd meeting at 61st IETF - Washington, DC", "list_subscribe": "http://www.ietf.org/mailman/listinfo/pce", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pce/", "type": "wg", "name": "Path Computation Element"}}, {"pk": 1631, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "rbridge", "comments": "1st meeting at 60th IETF - San Diego, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IP Subnets in Topologies which are Flexible, Universal and Nice"}}, -{"pk": 1632, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 110856, "parent": 1324, "list_email": "behave@ietf.org", "acronym": "behave", "comments": "1st meeting at 60th IETF Meeting - San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/behave", "state": "active", "time": "2012-02-17 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/behave", "type": "wg", "name": "Behavior Engineering for Hindrance Avoidance"}}, -{"pk": 1633, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 19483, "parent": 934, "list_email": "isms@ietf.org", "acronym": "isms", "comments": "First met as SBSM, 2nd meeting at 60th IETF Meeting - San Diego, CA", "list_subscribe": "isms-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/isms/", "type": "wg", "name": "Integrated Security Model for SNMP"}}, -{"pk": 1634, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 19177, "parent": 1260, "list_email": "kitten@ietf.org", "acronym": "kitten", "comments": "1st meeting at 60th IETF - San Diego, CA; 2nd meeting at 61st IETF - Washington, DC", "list_subscribe": "https://www.ietf.org/mailman/listinfo/kitten", "state": "active", "time": "2012-10-01 09:22:55", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/kitten/", "type": "wg", "name": "Common Authentication Technology Next Generation"}}, +{"pk": 1632, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "behave@ietf.org", "acronym": "behave", "comments": "1st meeting at 60th IETF Meeting - San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/behave", "state": "active", "time": "2012-02-17 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/behave", "type": "wg", "name": "Behavior Engineering for Hindrance Avoidance"}}, +{"pk": 1633, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "isms@ietf.org", "acronym": "isms", "comments": "First met as SBSM, 2nd meeting at 60th IETF Meeting - San Diego, CA", "list_subscribe": "isms-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/isms/", "type": "wg", "name": "Integrated Security Model for SNMP"}}, +{"pk": 1634, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "kitten@ietf.org", "acronym": "kitten", "comments": "1st meeting at 60th IETF - San Diego, CA; 2nd meeting at 61st IETF - Washington, DC", "list_subscribe": "https://www.ietf.org/mailman/listinfo/kitten", "state": "active", "time": "2012-10-01 09:22:55", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/kitten/", "type": "wg", "name": "Common Authentication Technology Next Generation"}}, {"pk": 1635, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "urirev04", "comments": "1st meeting at 60th IETF Meeting - San Diego, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Uniform Resource Identifier Revisions"}}, {"pk": 1636, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "ipvlx", "comments": "1st meeting at 60th IETF Meeting - San Diego, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IP Virtual Link Extension"}}, {"pk": 1637, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "mass", "comments": "1st meeting 60th IETF Meeting - San Diego, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Message Authentication Signature Standards"}}, -{"pk": 1638, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 105682, "parent": 1193, "list_email": "netmod@ietf.org", "acronym": "netmod", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/netmod", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/netmod/", "type": "wg", "name": "NETCONF Data Modeling Language"}}, -{"pk": 1639, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "6lowpan@lists.ietf.org", "acronym": "6lowpan", "comments": "1st meeting at the 61st IETF - Washington, DC", "list_subscribe": "6lowpan-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/6lowpan/", "type": "wg", "name": "IPv6 over Low power WPAN"}}, -{"pk": 1640, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "ietf-tv", "comments": "1st meeting at 61st IETF Meeting - Washington, DC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "The Future of IETF Multicast/Unicast Service"}}, +{"pk": 1638, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "netmod@ietf.org", "acronym": "netmod", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/netmod", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/netmod/", "type": "wg", "name": "NETCONF Data Modeling Language"}}, +{"pk": 1639, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "6lowpan@lists.ietf.org", "acronym": "6lowpan", "comments": "1st meeting at the 61st IETF - Washington, DC", "list_subscribe": "6lowpan-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/6lowpan/", "type": "wg", "name": "IPv6 over Low power WPAN"}}, +{"pk": 1640, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "ietf-tv", "comments": "1st meeting at 61st IETF Meeting - Washington, DC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "The Future of IETF Multicast/Unicast Service"}}, {"pk": 1641, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "btns@ietf.org", "acronym": "btns", "comments": "1st meeting at 61st IETF-Washington, DC; 2nd meeting at 62nd IETF-Minneapolis, MN", "list_subscribe": "https://www.ietf.org/mailman/listinfo/btns", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/btns/", "type": "wg", "name": "Better-Than-Nothing Security"}}, -{"pk": 1642, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 100664, "parent": 1052, "list_email": "ntpwg@lists.ntp.org", "acronym": "ntp", "comments": "1st meeting at 61st IETF-Washington, DC; 2nd meeting at 62nd IETF-Minneapolis, MN", "list_subscribe": "https://lists.ntp.org/listinfo/ntpwg", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.ntp.org/pipermail/ntpwg/", "type": "wg", "name": "Network Time Protocol"}}, -{"pk": 1643, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "ecrit@ietf.org", "acronym": "ecrit", "comments": "1st meeting at 61st IETF - Washington, DC", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ecrit", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ecrit/", "type": "wg", "name": "Emergency Context Resolution with Internet Technologies"}}, +{"pk": 1642, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "ntpwg@lists.ntp.org", "acronym": "ntp", "comments": "1st meeting at 61st IETF-Washington, DC; 2nd meeting at 62nd IETF-Minneapolis, MN", "list_subscribe": "https://lists.ntp.org/listinfo/ntpwg", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.ntp.org/pipermail/ntpwg/", "type": "wg", "name": "Network Time Protocol"}}, +{"pk": 1643, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "ecrit@ietf.org", "acronym": "ecrit", "comments": "1st meeting at 61st IETF - Washington, DC", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ecrit", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ecrit/", "type": "wg", "name": "Emergency Context Resolution with Internet Technologies"}}, {"pk": 1644, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "easycert", "comments": "1st meeting at 61st IETF - Washington, DC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Easy-to-Use Certificates"}}, {"pk": 1645, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "idnprov", "comments": "1st meeting at 61st IETF - Washington, DC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IDN over EPP"}}, -{"pk": 1646, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "shim6@ietf.org", "acronym": "shim6", "comments": "1st meeting at 62nd IETF - Minneapolis, MN", "list_subscribe": "https://www.ietf.org/mailman/listinfo/shim6", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/shim6/", "type": "wg", "name": "Site Multihoming by IPv6 Intermediation"}}, -{"pk": 1647, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "", "acronym": "lowpan", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPv6 over IEEE 802.15.4"}}, -{"pk": 1648, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 105907, "parent": 934, "list_email": "ietf-calsify@osafoundation.org", "acronym": "calsify", "comments": "1st meeting at 62nd IETF-Minneapolis, MN; 2nd meeting at 63rd IETF-Paris, France", "list_subscribe": "http://lists.osafoundation.org/mailman/listinfo/ietf-calsify", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.osafoundation.org/pipermail/ietf-calsify/", "type": "wg", "name": "Calendaring and Scheduling Standards Simplification"}}, +{"pk": 1646, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "shim6@ietf.org", "acronym": "shim6", "comments": "1st meeting at 62nd IETF - Minneapolis, MN", "list_subscribe": "https://www.ietf.org/mailman/listinfo/shim6", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/shim6/", "type": "wg", "name": "Site Multihoming by IPv6 Intermediation"}}, +{"pk": 1647, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "lowpan", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPv6 over IEEE 802.15.4"}}, +{"pk": 1648, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-calsify@osafoundation.org", "acronym": "calsify", "comments": "1st meeting at 62nd IETF-Minneapolis, MN; 2nd meeting at 63rd IETF-Paris, France", "list_subscribe": "http://lists.osafoundation.org/mailman/listinfo/ietf-calsify", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.osafoundation.org/pipermail/ietf-calsify/", "type": "wg", "name": "Calendaring and Scheduling Standards Simplification"}}, {"pk": 1649, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "slrrp", "comments": "1st meeting at the 62nd IETF-Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Simple Lightweight RFID Reader Protocol"}}, -{"pk": 1650, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "trill@ietf.org", "acronym": "trill", "comments": "1st meeting at 62nd IETF-Minneapolis, MN", "list_subscribe": "https://www.ietf.org/mailman/listinfo/trill", "state": "active", "time": "2012-12-07 11:28:12", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/trill/current/maillist.html", "type": "wg", "name": "Transparent Interconnection of Lots of Links"}}, +{"pk": 1650, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "trill@ietf.org", "acronym": "trill", "comments": "1st meeting at 62nd IETF-Minneapolis, MN", "list_subscribe": "https://www.ietf.org/mailman/listinfo/trill", "state": "active", "time": "2012-12-07 11:28:12", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/trill/current/maillist.html", "type": "wg", "name": "Transparent Interconnection of Lots of Links"}}, {"pk": 1651, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "icos", "comments": "1st meeting at 62nd IETF-Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IP Configuration Security"}}, {"pk": 1652, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "tc", "comments": "1st meeting at 62nd IETF-Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Tunneling Configuration"}}, -{"pk": 1653, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "autoconf@ietf.org", "acronym": "autoconf", "comments": "1st meeting at 62nd IETF-Minneapolis, MN; 2nd meeting at 64th IETF-Vancouver, BC", "list_subscribe": "https://www.ietf.org/mailman/listinfo/autoconf", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/autoconf/", "type": "wg", "name": "Ad-Hoc Network Autoconfiguration"}}, -{"pk": 1654, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "liaison", "comments": "1st meeting at 62nd IETF-Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Liaison Relationships"}}, +{"pk": 1653, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "autoconf@ietf.org", "acronym": "autoconf", "comments": "1st meeting at 62nd IETF-Minneapolis, MN; 2nd meeting at 64th IETF-Vancouver, BC", "list_subscribe": "https://www.ietf.org/mailman/listinfo/autoconf", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/autoconf/", "type": "wg", "name": "Ad-Hoc Network Autoconfiguration"}}, +{"pk": 1654, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "liaison", "comments": "1st meeting at 62nd IETF-Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Liaison Relationships"}}, {"pk": 1655, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ltru@ietf.org", "acronym": "ltru", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ltru", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ltru/", "type": "wg", "name": "Language Tag Registry Update"}}, {"pk": 1656, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "l1vpn@ietf.org", "acronym": "l1vpn", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/l1vpn", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/l1vpn/", "type": "wg", "name": "Layer 1 Virtual Private Networks"}}, {"pk": 1657, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "secmech", "comments": "1st meeting at the 63rd IETF - Paris, France", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Security Mechanisms"}}, {"pk": 1658, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "hash", "comments": "1st meeting at 63rd IETF-Paris, France", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "One-way Hash Function"}}, {"pk": 1659, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "imad", "comments": "1st meeting at 63rd IETF-Paris, France", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPv4 Multicast Address Architecture"}}, -{"pk": 1660, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "techspec", "comments": "1st meeting at 64th IETF-Vancouver, BC; 2nd meeting 65th IETF-Dallas, TX", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Requirements for IETF Technical Specificaiton Publication"}}, +{"pk": 1660, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "techspec", "comments": "1st meeting at 64th IETF-Vancouver, BC; 2nd meeting 65th IETF-Dallas, TX", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Requirements for IETF Technical Specificaiton Publication"}}, {"pk": 1661, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "alien", "comments": "1st meeting at 63rd IETF-Paris, France", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Anonymous Identifiers"}}, {"pk": 1662, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "rui", "comments": "1st meeting at 63rd IETF-Paris, France; 2nd meeting at 64th IETF-Vancouver, BC; this BOF was changed to the WIDEX WG just before the Vancouver meeting.", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Remote UI"}}, {"pk": 1663, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "voipeer", "comments": "1st meeting at 63rd IETF-Paris, France; 2nd meeting at 64th IETF-Vancouver, BC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "VoIP Peering and Interconnect"}}, -{"pk": 1664, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "netlmm@ietf.org", "acronym": "netlmm", "comments": "1st meeting at 63rd IETF-Paris, France; 2nd meeting at 64th IETF-Vancouver, BC", "list_subscribe": "http://www.ietf.org/mailman/listinfo/netlmm", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/netlmm", "type": "wg", "name": "Network-based Localized Mobility Management"}}, -{"pk": 1665, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "int-area@ietf.org", "acronym": "intarea", "comments": "1st meeting at 63rd IETF-Paris, France", "list_subscribe": "https://www.ietf.org/mailman/listinfo/int-area", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/int-area/", "type": "wg", "name": "Internet Area Working Group"}}, -{"pk": 1666, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "", "acronym": "lrw", "comments": "1st meeting at 63rd IETF-Paris, France", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Lightweight Reachability softWires"}}, -{"pk": 1667, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "monami6@ietf.org", "acronym": "monami6", "comments": "1st meeting at 63rd IETF-Paris, France; 2nd meeting at 64th IETF-Vancouver, BC", "list_subscribe": "https://www1.ietf.org/mailman/listinfo/monami6", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/monami6/", "type": "wg", "name": "Mobile Nodes and Multiple Interfaces in IPv6"}}, +{"pk": 1664, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "netlmm@ietf.org", "acronym": "netlmm", "comments": "1st meeting at 63rd IETF-Paris, France; 2nd meeting at 64th IETF-Vancouver, BC", "list_subscribe": "http://www.ietf.org/mailman/listinfo/netlmm", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/netlmm", "type": "wg", "name": "Network-based Localized Mobility Management"}}, +{"pk": 1665, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "int-area@ietf.org", "acronym": "intarea", "comments": "1st meeting at 63rd IETF-Paris, France", "list_subscribe": "https://www.ietf.org/mailman/listinfo/int-area", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/int-area/", "type": "wg", "name": "Internet Area Working Group"}}, +{"pk": 1666, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "lrw", "comments": "1st meeting at 63rd IETF-Paris, France", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Lightweight Reachability softWires"}}, +{"pk": 1667, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "monami6@ietf.org", "acronym": "monami6", "comments": "1st meeting at 63rd IETF-Paris, France; 2nd meeting at 64th IETF-Vancouver, BC", "list_subscribe": "https://www1.ietf.org/mailman/listinfo/monami6", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/monami6/", "type": "wg", "name": "Mobile Nodes and Multiple Interfaces in IPv6"}}, {"pk": 1669, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "widex@ietf.org", "acronym": "widex", "comments": "Suplemental Website: http://www.softarmor.com/rui\r\n1st meeting as WIDEX at 64th IETF-Vancouver, BC; was previously known as RUI", "list_subscribe": "https://www1.ietf.org/mailman/listinfo/widex", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/widex/", "type": "wg", "name": "Widget Description Exchange Service"}}, {"pk": 1670, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "", "acronym": "gels", "comments": "1st meeting at 64th IETF-Vancouver, BC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "GMPLS Controlled Ethernet Label Switching"}}, -{"pk": 1671, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "ietf-dkim@mipassoc.org", "acronym": "dkim", "comments": "1st meeting at 64th IETF-Vancouver, BC", "list_subscribe": "http://mipassoc.org/mailman/listinfo/ietf-dkim", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://mipassoc.org/pipermail/ietf-dkim/", "type": "wg", "name": "Domain Keys Identified Mail"}}, -{"pk": 1672, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "pesci", "comments": "1st meeting at 64th IETF-Vancouver, BC; Bert Wijnen and Sam Hartman will host this BOF, Brian will be chair.", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Process Evolution Consideration for the IETF"}}, -{"pk": 1673, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 105519, "parent": 1324, "list_email": "fecframe@ietf.org", "acronym": "fecframe", "comments": "1st meeting at 64th IETF-Vancouver, BC", "list_subscribe": "https://www.ietf.org/mailman/listinfo/fecframe", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/fecframe", "type": "wg", "name": "FEC Framework"}}, -{"pk": 1674, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "emu@ietf.org", "acronym": "emu", "comments": "1st meeting at 64th IETF-Vancouver, BC", "list_subscribe": "https://www.ietf.org/mailman/listinfo/emu", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/emu/", "type": "wg", "name": "EAP Method Update"}}, -{"pk": 1675, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "16ng@ietf.org", "acronym": "16ng", "comments": "1st meeting at 64th IETF-Vancouver, BC. 2nd meeting 65th IETF-Dallas, TX; 34rd meeting at 66th IETF-Montreal, Canada", "list_subscribe": "https://www.ietf.org/mailman/listinfo/16ng", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/16ng", "type": "wg", "name": "IP over IEEE 802.16 Networks"}}, +{"pk": 1671, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "ietf-dkim@mipassoc.org", "acronym": "dkim", "comments": "1st meeting at 64th IETF-Vancouver, BC", "list_subscribe": "http://mipassoc.org/mailman/listinfo/ietf-dkim", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://mipassoc.org/pipermail/ietf-dkim/", "type": "wg", "name": "Domain Keys Identified Mail"}}, +{"pk": 1672, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "pesci", "comments": "1st meeting at 64th IETF-Vancouver, BC; Bert Wijnen and Sam Hartman will host this BOF, Brian will be chair.", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Process Evolution Consideration for the IETF"}}, +{"pk": 1673, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "fecframe@ietf.org", "acronym": "fecframe", "comments": "1st meeting at 64th IETF-Vancouver, BC", "list_subscribe": "https://www.ietf.org/mailman/listinfo/fecframe", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/fecframe", "type": "wg", "name": "FEC Framework"}}, +{"pk": 1674, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "emu@ietf.org", "acronym": "emu", "comments": "1st meeting at 64th IETF-Vancouver, BC", "list_subscribe": "https://www.ietf.org/mailman/listinfo/emu", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/emu/", "type": "wg", "name": "EAP Method Update"}}, +{"pk": 1675, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "16ng@ietf.org", "acronym": "16ng", "comments": "1st meeting at 64th IETF-Vancouver, BC. 2nd meeting 65th IETF-Dallas, TX; 34rd meeting at 66th IETF-Montreal, Canada", "list_subscribe": "https://www.ietf.org/mailman/listinfo/16ng", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/16ng", "type": "wg", "name": "IP over IEEE 802.16 Networks"}}, {"pk": 1676, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "xmlpatch", "comments": "1st meeting at 64th IETF-Vancouver, BC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "XML-Patch-Ops"}}, {"pk": 1677, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "iee", "comments": "1st meeting at 64th IETF-Vancouver, BC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internationalized Email and Extensions"}}, -{"pk": 1678, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "softwires@ietf.org", "acronym": "softwire", "comments": "1st meeting at 64th IETF-Vancouver, BC", "list_subscribe": "softwires-request@ietf.org", "state": "active", "time": "2012-06-20 08:03:29", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/softwires/", "type": "wg", "name": "Softwires"}}, +{"pk": 1678, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "softwires@ietf.org", "acronym": "softwire", "comments": "1st meeting at 64th IETF-Vancouver, BC", "list_subscribe": "softwires-request@ietf.org", "state": "active", "time": "2012-06-20 08:03:29", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/softwires/", "type": "wg", "name": "Softwires"}}, {"pk": 1679, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "tsvarea", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-02-23 12:00:00", "unused_tags": [], "list_archive": "", "type": "ag", "name": "Transport Area Open Meeting"}}, -{"pk": 1680, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2329, "parent": 1249, "list_email": "sidr@ietf.org", "acronym": "sidr", "comments": "1st meeting at 64th IETF-Vancouver, BC", "list_subscribe": "sidr-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sidr/", "type": "wg", "name": "Secure Inter-Domain Routing"}}, +{"pk": 1680, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "sidr@ietf.org", "acronym": "sidr", "comments": "1st meeting at 64th IETF-Vancouver, BC", "list_subscribe": "sidr-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sidr/", "type": "wg", "name": "Secure Inter-Domain Routing"}}, {"pk": 1681, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "callhome", "comments": "1st meeting at 64th IETF-Vancouver, BC, CANADA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Reversing Traditional Client/Server Connection Model"}}, -{"pk": 1682, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 105682, "parent": 1193, "list_email": "dime@ietf.org", "acronym": "dime", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/dime", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dime/", "type": "wg", "name": "Diameter Maintenance and Extensions"}}, +{"pk": 1682, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "dime@ietf.org", "acronym": "dime", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/dime", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dime/", "type": "wg", "name": "Diameter Maintenance and Extensions"}}, {"pk": 1683, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 2, "list_email": "", "acronym": "rai", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-02-26 00:21:37", "unused_tags": [], "list_archive": "", "type": "area", "name": "Real-time Applications and Infrastructure Area"}}, {"pk": 1684, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "", "acronym": "raiarea", "comments": "", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ag", "name": "Real-time Applications and Infrastructure Area Open Meeting"}}, -{"pk": 1685, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "speermint@ietf.org", "acronym": "speermint", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/speermint", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/speermint/", "type": "wg", "name": "Session PEERing for Multimedia INTerconnect"}}, -{"pk": 1686, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 18321, "parent": 934, "list_email": "ima@ietf.org", "acronym": "eai", "comments": "1st meeting at 65th IETF-Dallas, TX", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ima", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ima", "type": "wg", "name": "Email Address Internationalization"}}, -{"pk": 1688, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 19177, "parent": 1260, "list_email": "nea@ietf.org", "acronym": "nea", "comments": "1st meeting at 65th IETF-Dallas, TX; 2nd meeting at 66th IETF-Montreal, Canada; 3rd meeting at 67th IETF-San Diego, CA", "list_subscribe": "http://www.ietf.org/mailman/listinfo/nea", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/nea", "type": "wg", "name": "Network Endpoint Assessment"}}, +{"pk": 1685, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "speermint@ietf.org", "acronym": "speermint", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/speermint", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/speermint/", "type": "wg", "name": "Session PEERing for Multimedia INTerconnect"}}, +{"pk": 1686, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ima@ietf.org", "acronym": "eai", "comments": "1st meeting at 65th IETF-Dallas, TX", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ima", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ima", "type": "wg", "name": "Email Address Internationalization"}}, +{"pk": 1688, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "nea@ietf.org", "acronym": "nea", "comments": "1st meeting at 65th IETF-Dallas, TX; 2nd meeting at 66th IETF-Montreal, Canada; 3rd meeting at 67th IETF-San Diego, CA", "list_subscribe": "http://www.ietf.org/mailman/listinfo/nea", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/nea", "type": "wg", "name": "Network Endpoint Assessment"}}, {"pk": 1689, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "dix", "comments": "1st meeting at 65th IETF-Dallas, TX", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Digital Identity Exchange Protocol"}}, {"pk": 1690, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "p2psip@ietf.org", "acronym": "p2p-sip", "comments": "1st meeting at 65th IETF-Dallas, TX; 2nd meeting at 67th IETF-San Diego", "list_subscribe": "https://www.ietf.org/mailman/listinfo/p2psip", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/p2psip", "type": "wg", "name": "Peer to Peer Support for Session Initiation Protocol"}}, {"pk": 1691, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "l2cp", "comments": "1st meeting at 65th IETF-Dallas, TX", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Layer 2 Control Protocol"}}, {"pk": 1692, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "hoakey", "comments": "1st meeting at 65th IETF-Dallas, TX; 2nd meeting at 66th IETF-Montreal, Canada; 3rd meeting at 67th IETF-San Diego, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Handover and Application Keying and Pre-authentication"}}, -{"pk": 1693, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "ancp@ietf.org", "acronym": "ancp", "comments": "", "list_subscribe": "ancp-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ancp/", "type": "wg", "name": "Access Node Control Protocol"}}, +{"pk": 1693, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "ancp@ietf.org", "acronym": "ancp", "comments": "", "list_subscribe": "ancp-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ancp/", "type": "wg", "name": "Access Node Control Protocol"}}, {"pk": 1694, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "dmsp", "comments": "1st meeting at 66th IETF-Montreal, Canada", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Distributed Multimodal Synchronization Protocol"}}, {"pk": 1695, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "offpath", "comments": "1st meeting at 66th IETF-Monteral, Canada", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Path-decoupled Signaling for Data"}}, {"pk": 1696, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "ternli", "comments": "1st meeting at 66th IETF-Montreal, Canada", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Transport-Enhancing Refinements to the Network Layer"}}, {"pk": 1697, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "", "acronym": "rtpsec", "comments": "1st meeting at 66th IETF-Montreal, Canada", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "RTP Secure Keying"}}, {"pk": 1698, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "wae", "comments": "1st meeting at 66yth EITF-Montreal, Canada", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Web Authentication Enhancement"}}, -{"pk": 1699, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "", "acronym": "sava", "comments": "1st meeting 68th IETF - Prague, Czech Republic", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Source Address Validation Architecture"}}, -{"pk": 1700, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 19177, "parent": 1260, "list_email": "hokey@ietf.org", "acronym": "hokey", "comments": "Was call HOAKEY as a BOF. 1st meeting at 65th IETF-Dallas, TX; 2nd meeting at 66th IETF-Montreal, Canada; 3rd meeting at 67th IETF-San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/hokey", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/hokey/", "type": "wg", "name": "Handover Keying"}}, -{"pk": 1701, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 105519, "parent": 1324, "list_email": "pcn@ietf.org", "acronym": "pcn", "comments": "1st meeting at 67th IETF-San Diego, CA", "list_subscribe": "pcn-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pcn/", "type": "wg", "name": "Congestion and Pre-Congestion Notification"}}, -{"pk": 1702, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "mediactrl@ietf.org", "acronym": "mediactrl", "comments": "1st meeting at 67th IETF-San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/mediactrl", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mediactrl", "type": "wg", "name": "Media Server Control"}}, +{"pk": 1699, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "sava", "comments": "1st meeting 68th IETF - Prague, Czech Republic", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Source Address Validation Architecture"}}, +{"pk": 1700, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "hokey@ietf.org", "acronym": "hokey", "comments": "Was call HOAKEY as a BOF. 1st meeting at 65th IETF-Dallas, TX; 2nd meeting at 66th IETF-Montreal, Canada; 3rd meeting at 67th IETF-San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/hokey", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/hokey/", "type": "wg", "name": "Handover Keying"}}, +{"pk": 1701, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "pcn@ietf.org", "acronym": "pcn", "comments": "1st meeting at 67th IETF-San Diego, CA", "list_subscribe": "pcn-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pcn/", "type": "wg", "name": "Congestion and Pre-Congestion Notification"}}, +{"pk": 1702, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "mediactrl@ietf.org", "acronym": "mediactrl", "comments": "1st meeting at 67th IETF-San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/mediactrl", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mediactrl", "type": "wg", "name": "Media Server Control"}}, {"pk": 1703, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "spkm", "comments": "1st meeting 67th IETF-San Diego, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "NFSv4 and Low Infrastructure Public Key Based GSS Security Mechanisms"}}, {"pk": 1704, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "keyprov@ietf.org", "acronym": "keyprov", "comments": "1st meeting at 67th IETF-San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/keyprov", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/keyprov", "type": "wg", "name": "Provisioning of Symmetric Keys"}}, -{"pk": 1705, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "p2psip@ietf.org", "acronym": "p2psip", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/p2psip", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/p2psip", "type": "wg", "name": "Peer-to-Peer Session Initiation Protocol"}}, +{"pk": 1705, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "p2psip@ietf.org", "acronym": "p2psip", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/p2psip", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/p2psip", "type": "wg", "name": "Peer-to-Peer Session Initiation Protocol"}}, {"pk": 1706, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "ifare", "comments": "1st meeting in Prague, IETF-68;", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPsec FAilover and REdundancy"}}, {"pk": 1707, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "", "acronym": "peppermint", "comments": "1st meeting at IETF-70 in Vancouver, Canada; 2nd meeting at 71st IETF - Philadelphia, PA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Provisioning Extensions in Peering Registries for Multimedia INTerconnection"}}, -{"pk": 1708, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "bliss@ietf.org", "acronym": "bliss", "comments": "1st meeting at ietf-68, prague", "list_subscribe": "https://www.ietf.org/mailman/listinfo/bliss", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/bliss", "type": "wg", "name": "Basic Level of Interoperability for SIP Services"}}, -{"pk": 1709, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 100664, "parent": 1052, "list_email": "tictoc@ietf.org", "acronym": "tictoc", "comments": "1st meeting 68th IETF - Prague, Czech Republic", "list_subscribe": "TICTOC-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/tictoc", "type": "wg", "name": "Timing over IP Connection and Transfer of Clock"}}, -{"pk": 1710, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "", "acronym": "hiccup", "comments": "1st meeting at IETF-68", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Harnessing IP for Critical Communications Using Precedence"}}, +{"pk": 1708, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "bliss@ietf.org", "acronym": "bliss", "comments": "1st meeting at ietf-68, prague", "list_subscribe": "https://www.ietf.org/mailman/listinfo/bliss", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/bliss", "type": "wg", "name": "Basic Level of Interoperability for SIP Services"}}, +{"pk": 1709, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "tictoc@ietf.org", "acronym": "tictoc", "comments": "1st meeting 68th IETF - Prague, Czech Republic", "list_subscribe": "TICTOC-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/tictoc", "type": "wg", "name": "Timing over IP Connection and Transfer of Clock"}}, +{"pk": 1710, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "", "acronym": "hiccup", "comments": "1st meeting at IETF-68", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Harnessing IP for Critical Communications Using Precedence"}}, {"pk": 1711, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "fsm", "comments": "1st meetings at IETF-68", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Formal State Machines"}}, {"pk": 1712, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "tools", "comments": "", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "team", "name": "The Tools Team"}}, {"pk": 1713, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "proto", "comments": "", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "team", "name": "The Process and Tools Team"}}, -{"pk": 1714, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 101568, "parent": 1193, "list_email": "opsawg@ietf.org", "acronym": "opsawg", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/opsawg", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/opsawg", "type": "wg", "name": "Operations and Management Area Working Group"}}, -{"pk": 1715, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 6699, "parent": 1193, "list_email": "", "acronym": "apm", "comments": "1st meeting at IETF-69, Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Application Performance Metrics"}}, -{"pk": 1716, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 6699, "parent": 1193, "list_email": "", "acronym": "nee", "comments": "1st meeting at IETF-69, Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Netconf Extensions and Evolution"}}, -{"pk": 1717, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 6699, "parent": 1193, "list_email": "", "acronym": "xsdmi", "comments": "1st meeting at IETF-69, Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "XSD for accessing SMIv2 data models"}}, -{"pk": 1718, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21684, "parent": 934, "list_email": "ietf-http-wg@w3.org", "acronym": "httpbis", "comments": "1st meeting at IETF-69, Chicago, IL", "list_subscribe": "ietf-http-wg-request@w3.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.w3.org/Archives/Public/ietf-http-wg/", "type": "wg", "name": "Hypertext Transfer Protocol Bis"}}, +{"pk": 1714, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "opsawg@ietf.org", "acronym": "opsawg", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/opsawg", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/opsawg", "type": "wg", "name": "Operations and Management Area Working Group"}}, +{"pk": 1715, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "apm", "comments": "1st meeting at IETF-69, Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Application Performance Metrics"}}, +{"pk": 1716, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "nee", "comments": "1st meeting at IETF-69, Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Netconf Extensions and Evolution"}}, +{"pk": 1717, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "xsdmi", "comments": "1st meeting at IETF-69, Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "XSD for accessing SMIv2 data models"}}, +{"pk": 1718, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-http-wg@w3.org", "acronym": "httpbis", "comments": "1st meeting at IETF-69, Chicago, IL", "list_subscribe": "ietf-http-wg-request@w3.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.w3.org/Archives/Public/ietf-http-wg/", "type": "wg", "name": "Hypertext Transfer Protocol Bis"}}, {"pk": 1719, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "tam", "comments": "1st meeting at IETF-69, Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Trust Anchor Management"}}, {"pk": 1720, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "mext@ietf.org", "acronym": "mext", "comments": "Renamed to Distributed Mobility Management (dmm) in January 2012\r\n", "list_subscribe": "https://www.ietf.org/mailman/listinfo/mext", "state": "conclude", "time": "2012-01-10 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mext", "type": "wg", "name": "Mobility EXTensions for IPv6"}}, -{"pk": 1721, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 18321, "parent": 934, "list_email": "vcarddav@ietf.org", "acronym": "vcarddav", "comments": "1st Meeting at IETF-69, Chicago, IL", "list_subscribe": "https://www.ietf.org/mailman/listinfo/vcarddav", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/vcarddav", "type": "wg", "name": "vCard and CardDAV"}}, +{"pk": 1721, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "vcarddav@ietf.org", "acronym": "vcarddav", "comments": "1st Meeting at IETF-69, Chicago, IL", "list_subscribe": "https://www.ietf.org/mailman/listinfo/vcarddav", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/vcarddav", "type": "wg", "name": "vCard and CardDAV"}}, {"pk": 1722, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "biff", "comments": "1st meeting at IETF-69, Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Notifications from Mail Stores"}}, -{"pk": 1723, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 100664, "parent": 1052, "list_email": "ipv6@ietf.org", "acronym": "6man", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ipv6", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipv6", "type": "wg", "name": "IPv6 Maintenance"}}, -{"pk": 1725, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 6699, "parent": 1193, "list_email": "pmol@ietf.org", "acronym": "pmol", "comments": "", "list_subscribe": "https://www1.ietf.org/mailman/listinfo/pmol", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pmol/", "type": "wg", "name": "Performance Metrics for Other Layers"}}, -{"pk": 1726, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "cga-ext@ietf.org", "acronym": "csi", "comments": "1st meeting at IETF-70 in Vancouver, Canada", "list_subscribe": "http://www.ietf.org/mailman/listinfo/cga-ext", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/cga-ext/", "type": "wg", "name": "Cga & Send maIntenance"}}, -{"pk": 1727, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 17253, "parent": 1324, "list_email": "", "acronym": "safe", "comments": "1st meeting at IETF-70, Vancouver, Canada", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Self-Address Fixing Evolution"}}, -{"pk": 1728, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "savi@ietf.org", "acronym": "savi", "comments": "1st meeting at IETF-60, Vancouver, Canada; 2nd meeting at 71st IETF, Philadelphia, PA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/savi", "state": "active", "time": "2012-08-29 08:42:05", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/savi/", "type": "wg", "name": "Source Address Validation Improvements"}}, +{"pk": 1723, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "ipv6@ietf.org", "acronym": "6man", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ipv6", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipv6", "type": "wg", "name": "IPv6 Maintenance"}}, +{"pk": 1725, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "pmol@ietf.org", "acronym": "pmol", "comments": "", "list_subscribe": "https://www1.ietf.org/mailman/listinfo/pmol", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pmol/", "type": "wg", "name": "Performance Metrics for Other Layers"}}, +{"pk": 1726, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "cga-ext@ietf.org", "acronym": "csi", "comments": "1st meeting at IETF-70 in Vancouver, Canada", "list_subscribe": "http://www.ietf.org/mailman/listinfo/cga-ext", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/cga-ext/", "type": "wg", "name": "Cga & Send maIntenance"}}, +{"pk": 1727, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "safe", "comments": "1st meeting at IETF-70, Vancouver, Canada", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Self-Address Fixing Evolution"}}, +{"pk": 1728, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "savi@ietf.org", "acronym": "savi", "comments": "1st meeting at IETF-60, Vancouver, Canada; 2nd meeting at 71st IETF, Philadelphia, PA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/savi", "state": "active", "time": "2012-08-29 08:42:05", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/savi/", "type": "wg", "name": "Source Address Validation Improvements"}}, {"pk": 1729, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "", "acronym": "rl2n", "comments": "1st meeting at IETF-70, Vancouver, Canada", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Routing For Low Power and Lossy Networks"}}, -{"pk": 1730, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 104198, "parent": 1249, "list_email": "roll@ietf.org", "acronym": "roll", "comments": "", "list_subscribe": "http://www.ietf.org/mailman/listinfo/roll", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/roll/", "type": "wg", "name": "Routing Over Low power and Lossy networks"}}, +{"pk": 1730, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "roll@ietf.org", "acronym": "roll", "comments": "", "list_subscribe": "http://www.ietf.org/mailman/listinfo/roll", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/roll/", "type": "wg", "name": "Routing Over Low power and Lossy networks"}}, {"pk": 1731, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "fun@ietf.org", "acronym": "fun", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/fun", "state": "bof-conc", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/fun/", "type": "wg", "name": "FUture home Networks"}}, {"pk": 1732, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "", "acronym": "rucus", "comments": "1st meeting at 71st IETF - Philadelphia, PA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Ruducing Unwanted Communications using SIP"}}, {"pk": 1733, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "esds", "comments": "1st Meeting 71st IETF Meeting - Philadelphia, PA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Extensible Supply-chain Discovery Service"}}, -{"pk": 1734, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "testlist@mail.ietf.org", "acronym": "tf", "comments": "", "list_subscribe": "testlist-request@mail.ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/tf", "type": "wg", "name": "Testing Fun"}}, -{"pk": 1735, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "pufi", "comments": "1st meeting at 71st IETF - Philadelphia, PA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Procedures Update for IETF"}}, -{"pk": 1736, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 6699, "parent": 1193, "list_email": "", "acronym": "canmod", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Comparing Approaches to NETCONF Modeling"}}, -{"pk": 1737, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2329, "parent": 1249, "list_email": "karp@ietf.org", "acronym": "karp", "comments": "1st meeting at 71st IETF - Philadelphia, PA; 2nd meeting at 76th IETF-Hiroshima, Japan - Changed from Security area to Routing area, changed name and acronym from KMART, Key Management for use with Routing Protocols", "list_subscribe": "https://www.ietf.org/mailman/listinfo/karp", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/karp/", "type": "wg", "name": "Keying and Authentication for Routing Protocols"}}, +{"pk": 1734, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1008, "list_email": "testlist@mail.ietf.org", "acronym": "tf", "comments": "", "list_subscribe": "testlist-request@mail.ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/tf", "type": "wg", "name": "Testing Fun"}}, +{"pk": 1735, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "pufi", "comments": "1st meeting at 71st IETF - Philadelphia, PA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Procedures Update for IETF"}}, +{"pk": 1736, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "canmod", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Comparing Approaches to NETCONF Modeling"}}, +{"pk": 1737, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "karp@ietf.org", "acronym": "karp", "comments": "1st meeting at 71st IETF - Philadelphia, PA; 2nd meeting at 76th IETF-Hiroshima, Japan - Changed from Security area to Routing area, changed name and acronym from KMART, Key Management for use with Routing Protocols", "list_subscribe": "https://www.ietf.org/mailman/listinfo/karp", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/karp/", "type": "wg", "name": "Keying and Authentication for Routing Protocols"}}, {"pk": 1738, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "idna-update@alvestrand.no", "acronym": "idnabis", "comments": "Chairperson(s): Vinton Cerf", "list_subscribe": "http://www.alvestrand.no/mailman/listinfo/idna-update", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.alvestrand.no/pipermail/idna-update/", "type": "wg", "name": "Internationalized Domain Names in Applications, Revised"}}, -{"pk": 1739, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "drinks@ietf.org", "acronym": "drinks", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/drinks", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/drinks/", "type": "wg", "name": "Data for Reachability of Inter/tra-NetworK SIP"}}, -{"pk": 1740, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "ipsec@ietf.org", "acronym": "ipsecme", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ipsec", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipsec/", "type": "wg", "name": "IP Security Maintenance and Extensions"}}, +{"pk": 1739, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "drinks@ietf.org", "acronym": "drinks", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/drinks", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/drinks/", "type": "wg", "name": "Data for Reachability of Inter/tra-NetworK SIP"}}, +{"pk": 1740, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "ipsec@ietf.org", "acronym": "ipsecme", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ipsec", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipsec/", "type": "wg", "name": "IP Security Maintenance and Extensions"}}, {"pk": 1741, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "morg@ietf.org", "acronym": "morg", "comments": "1st meeting at 72nd IETF - Dublin, Ireland", "list_subscribe": "https://www.ietf.org/mailman/listinfo/morg", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/morg/", "type": "wg", "name": "Message Organization"}}, -{"pk": 1742, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "", "acronym": "explisp", "comments": "1st meeting at 72nd IETF - Dublin, Ireland", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Experimentation in LISP"}}, +{"pk": 1742, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "explisp", "comments": "1st meeting at 72nd IETF - Dublin, Ireland", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Experimentation in LISP"}}, {"pk": 1743, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "tana", "comments": "1st meeting at 72nd IETF - Dublin, Ireland; 2nd meeting at 73rd IETF - Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Techniques for Advanced Networking Applications"}}, -{"pk": 1744, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 105519, "parent": 1324, "list_email": "alto@ietf.org", "acronym": "alto", "comments": "1st meeting at 72nd IETF-Dublin, Ireland; 2nd meeting at 73rd IETF-Minneapolis, MN", "list_subscribe": "https://www.ietf.org/mailman/listinfo/alto", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/alto/", "type": "wg", "name": "Application-Layer Traffic Optimization"}}, +{"pk": 1744, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "alto@ietf.org", "acronym": "alto", "comments": "1st meeting at 72nd IETF-Dublin, Ireland; 2nd meeting at 73rd IETF-Minneapolis, MN", "list_subscribe": "https://www.ietf.org/mailman/listinfo/alto", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/alto/", "type": "wg", "name": "Application-Layer Traffic Optimization"}}, {"pk": 1745, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "ippmxx", "comments": "1st meeting at 72nd IETF-Dublin, Ireland\r\n\r\nWas called ippm++, changed to ippm to avoid undesirable characters, this record changed to ippmxx to\r\navoid further undesirable effects on the website.", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IP Performance Metrics, Next Steps"}}, -{"pk": 1747, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 100664, "parent": 1052, "list_email": "multimob@ietf.org", "acronym": "multimob", "comments": "1st meeting at 73rd IETF - Minneapolis, MN, 2nd meeting at 75th IETF-Stockholm, Sweden", "list_subscribe": "https://www.ietf.org/mailman/listinfo/multimob", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/multimob/", "type": "wg", "name": "Multicast Mobility"}}, -{"pk": 1748, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 19177, "parent": 1260, "list_email": "oauth@ietf.org", "acronym": "oauth", "comments": "1st meeting at 73rd IETF-Minneapolis, MN; 2nd meeting at 74th IETF-San Francisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/oauth", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/oauth/", "type": "wg", "name": "Web Authorization Protocol"}}, -{"pk": 1749, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 110856, "parent": 1324, "list_email": "ledbat@ietf.org", "acronym": "ledbat", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ledbat", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ledbat", "type": "wg", "name": "Low Extra Delay Background Transport"}}, -{"pk": 1751, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 100664, "parent": 1052, "list_email": "lisp@ietf.org", "acronym": "lisp", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/lisp", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/lisp/", "type": "wg", "name": "Locator/ID Separation Protocol"}}, -{"pk": 1752, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "", "acronym": "6ai", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPv6 Address Independence"}}, -{"pk": 1753, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 17253, "parent": 1324, "list_email": "", "acronym": "shara", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Sharing of an IPv4 Address"}}, -{"pk": 1754, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "pre8prob", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Pre-5378 Problem"}}, -{"pk": 1755, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "mif@ietf.org", "acronym": "mif", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/mif", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mif", "type": "wg", "name": "Multiple Interfaces"}}, -{"pk": 1756, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 100664, "parent": 1052, "list_email": "netext@ietf.org", "acronym": "netext", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/netext", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/netext/", "type": "wg", "name": "Network-Based Mobility Extensions"}}, -{"pk": 1757, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 105519, "parent": 1324, "list_email": "storm@ietf.org", "acronym": "storm", "comments": "1st meeting 74th IETF-San Francisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/storm", "state": "active", "time": "2012-02-03 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/storm/", "type": "wg", "name": "STORage Maintenance"}}, +{"pk": 1747, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "multimob@ietf.org", "acronym": "multimob", "comments": "1st meeting at 73rd IETF - Minneapolis, MN, 2nd meeting at 75th IETF-Stockholm, Sweden", "list_subscribe": "https://www.ietf.org/mailman/listinfo/multimob", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/multimob/", "type": "wg", "name": "Multicast Mobility"}}, +{"pk": 1748, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "oauth@ietf.org", "acronym": "oauth", "comments": "1st meeting at 73rd IETF-Minneapolis, MN; 2nd meeting at 74th IETF-San Francisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/oauth", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/oauth/", "type": "wg", "name": "Web Authorization Protocol"}}, +{"pk": 1749, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "ledbat@ietf.org", "acronym": "ledbat", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ledbat", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ledbat", "type": "wg", "name": "Low Extra Delay Background Transport"}}, +{"pk": 1751, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "lisp@ietf.org", "acronym": "lisp", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/lisp", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/lisp/", "type": "wg", "name": "Locator/ID Separation Protocol"}}, +{"pk": 1752, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "6ai", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPv6 Address Independence"}}, +{"pk": 1753, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "shara", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Sharing of an IPv4 Address"}}, +{"pk": 1754, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "pre8prob", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Pre-5378 Problem"}}, +{"pk": 1755, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "mif@ietf.org", "acronym": "mif", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/mif", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mif", "type": "wg", "name": "Multiple Interfaces"}}, +{"pk": 1756, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "netext@ietf.org", "acronym": "netext", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/netext", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/netext/", "type": "wg", "name": "Network-Based Mobility Extensions"}}, +{"pk": 1757, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "storm@ietf.org", "acronym": "storm", "comments": "1st meeting 74th IETF-San Francisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/storm", "state": "active", "time": "2012-02-03 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/storm/", "type": "wg", "name": "STORage Maintenance"}}, {"pk": 1758, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "mmox", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Massively Multi-Player Games and Applications"}}, -{"pk": 1759, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 18321, "parent": 934, "list_email": "yam@ietf.org", "acronym": "yam", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "yam-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/yam/", "type": "wg", "name": "Yet Another Mail"}}, -{"pk": 1760, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "atoca@ietf.org", "acronym": "atoca", "comments": "1st meeting at 74th IETF-San Fancisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/atoca", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/atoca", "type": "wg", "name": "Authority-to-Citizen Alert"}}, -{"pk": 1761, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "xmpp@ietf.org", "acronym": "xmpp", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/xmpp", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/xmpp/", "type": "wg", "name": "Extensible Messaging and Presence Protocol"}}, -{"pk": 1762, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "sipcore@ietf.org", "acronym": "sipcore", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/sipcore", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sipcore/", "type": "wg", "name": "Session Initiation Protocol Core"}}, -{"pk": 1763, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "dispatch@ietf.org", "acronym": "dispatch", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/dispatch", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dispatch/", "type": "wg", "name": "Dispatch"}}, -{"pk": 1764, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 110856, "parent": 1324, "list_email": "multipathtcp@ietf.org", "acronym": "mptcp", "comments": "1st meeting at 75th IETF-Stockholm, Sweden; 2nd meeting at 76th IETF-Hiroshima, Japan", "list_subscribe": "https://www.ietf.org/mailman/listinfo/multipathtcp", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/multipathtcp/", "type": "wg", "name": "Multipath TCP"}}, -{"pk": 1765, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "codec@ietf.org", "acronym": "codec", "comments": "1st meeting at 75th IETF-Stockholm, Sweden; 2nd meeting at 76th IETF-Hiroshima, Japan", "list_subscribe": "https://www.ietf.org/mailman/listinfo/codec", "state": "active", "time": "2013-01-11 14:07:31", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/codec/", "type": "wg", "name": "Internet Wideband Audio Codec"}}, -{"pk": 1766, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "", "acronym": "netext2", "comments": "1st meeting at 75th IETF-Stockholm, Sweden", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network-Based Mobilty Extension, 2nd Stage"}}, +{"pk": 1759, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "yam@ietf.org", "acronym": "yam", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "yam-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/yam/", "type": "wg", "name": "Yet Another Mail"}}, +{"pk": 1760, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "atoca@ietf.org", "acronym": "atoca", "comments": "1st meeting at 74th IETF-San Fancisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/atoca", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/atoca", "type": "wg", "name": "Authority-to-Citizen Alert"}}, +{"pk": 1761, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "xmpp@ietf.org", "acronym": "xmpp", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/xmpp", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/xmpp/", "type": "wg", "name": "Extensible Messaging and Presence Protocol"}}, +{"pk": 1762, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "sipcore@ietf.org", "acronym": "sipcore", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/sipcore", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sipcore/", "type": "wg", "name": "Session Initiation Protocol Core"}}, +{"pk": 1763, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "dispatch@ietf.org", "acronym": "dispatch", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/dispatch", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dispatch/", "type": "wg", "name": "Dispatch"}}, +{"pk": 1764, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "multipathtcp@ietf.org", "acronym": "mptcp", "comments": "1st meeting at 75th IETF-Stockholm, Sweden; 2nd meeting at 76th IETF-Hiroshima, Japan", "list_subscribe": "https://www.ietf.org/mailman/listinfo/multipathtcp", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/multipathtcp/", "type": "wg", "name": "Multipath TCP"}}, +{"pk": 1765, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "codec@ietf.org", "acronym": "codec", "comments": "1st meeting at 75th IETF-Stockholm, Sweden; 2nd meeting at 76th IETF-Hiroshima, Japan", "list_subscribe": "https://www.ietf.org/mailman/listinfo/codec", "state": "active", "time": "2013-01-11 14:07:31", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/codec/", "type": "wg", "name": "Internet Wideband Audio Codec"}}, +{"pk": 1766, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "netext2", "comments": "1st meeting at 75th IETF-Stockholm, Sweden", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network-Based Mobilty Extension, 2nd Stage"}}, {"pk": 1767, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "ogpx", "comments": "1st meeting at 75th IETF-Stockholm, Sweden", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Open Grid Protocol"}}, -{"pk": 1768, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "sip-clf@ietf.org", "acronym": "sipclf", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/sip-clf", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sip-clf/", "type": "wg", "name": "SIP Common Log Format"}}, -{"pk": 1769, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 105907, "parent": 934, "list_email": "vwrap@ietf.org", "acronym": "vwrap", "comments": "", "list_subscribe": "vwrap-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/vwrap/", "type": "wg", "name": "Virtual World Region Agent Protocol"}}, +{"pk": 1768, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "sip-clf@ietf.org", "acronym": "sipclf", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/sip-clf", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sip-clf/", "type": "wg", "name": "SIP Common Log Format"}}, +{"pk": 1769, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "vwrap@ietf.org", "acronym": "vwrap", "comments": "", "list_subscribe": "vwrap-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/vwrap/", "type": "wg", "name": "Virtual World Region Agent Protocol"}}, {"pk": 1770, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "grobj", "comments": "1st meeting at 76th IETF-Hiroshima, Japan", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Generic Referral Object"}}, -{"pk": 1771, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 105519, "parent": 1324, "list_email": "ppsp@ietf.org", "acronym": "ppsp", "comments": "1st meeting 76th IETF-Hiroshima, Japan", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ppsp", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ppsp/", "type": "wg", "name": "Peer to Peer Streaming Protocol"}}, +{"pk": 1771, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "ppsp@ietf.org", "acronym": "ppsp", "comments": "1st meeting 76th IETF-Hiroshima, Japan", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ppsp", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ppsp/", "type": "wg", "name": "Peer to Peer Streaming Protocol"}}, {"pk": 1772, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "homegate", "comments": "1st meeting at 76th IETF-Hiroshima, Japan; 2nd meeting at 78th IETF-Maastricht, Netherlands", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Broadband Home Gateway"}}, -{"pk": 1773, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "", "acronym": "aplusp", "comments": "1st meeting - 76th IETF-Hiroshima, Japan", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Address Plus Port"}}, +{"pk": 1773, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "aplusp", "comments": "1st meeting - 76th IETF-Hiroshima, Japan", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Address Plus Port"}}, {"pk": 1774, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "6lowapp", "comments": "1st meeting at 76th IETF-Hiroshima, Japan; 2nd meeting at 77th IETF-Anaheim, CA, USA; Become a WG on 3-9-10 and name changed to Constrained RESTful Environments (core)", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Application Protocols for Low-power V6 Networks"}}, -{"pk": 1775, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 110856, "parent": 1324, "list_email": "conex@ietf.org", "acronym": "conex", "comments": "1st meeting at 76th IETF-Hiroshima, Japan", "list_subscribe": "https://www.ietf.org/mailman/listinfo/conex", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/conex/", "type": "wg", "name": "Congestion Exposure"}}, -{"pk": 1776, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "", "acronym": "nat66", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPv6-to-IPv6 Network Address Translation"}}, -{"pk": 1777, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21684, "parent": 934, "list_email": "hybi@ietf.org", "acronym": "hybi", "comments": "1st meeting at 76th IETF-Hiroshima, Japan", "list_subscribe": "https://www.ietf.org/mailman/listinfo/hybi", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/hybi/", "type": "wg", "name": "BiDirectional or Server-Initiated HTTP"}}, -{"pk": 1778, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 18321, "parent": 934, "list_email": "public-iri@w3.org", "acronym": "iri", "comments": "1st meeting at 76th IETF-Hiroshima, Japan", "list_subscribe": "public-iri-request@w3.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.w3.org/Archives/Public/public-iri/", "type": "wg", "name": "Internationalized Resource Identifiers"}}, -{"pk": 1779, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "int-area@ietf.org", "acronym": "intareawg", "comments": "See", "list_subscribe": "https://www.ietf.org/mailman/listinfo/int-area", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/int-area/", "type": "wg", "name": "Internet Area Proposed Working Group"}}, -{"pk": 1780, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 105519, "parent": 1324, "list_email": "decade@ietf.org", "acronym": "decade", "comments": "1st meeting at 76th IETF-Hiroshima, Japan; 2nd meeting at 77th IETF-Anaheim, CA, USA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/decade", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/decade/", "type": "wg", "name": "Decoupled Application Data Enroute"}}, -{"pk": 1781, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 105907, "parent": 934, "list_email": "http-state@ietf.org", "acronym": "httpstate", "comments": "Alternative Archive: http://groups.google.com/group/http-state", "list_subscribe": "https://www.ietf.org/mailman/listinfo/http-state", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/http-state/", "type": "wg", "name": "HTTP State Management Mechanism"}}, -{"pk": 1782, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "martini@ietf.org", "acronym": "martini", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/martini", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/martini/", "type": "wg", "name": "Multiple AoR reachabiliTy InformatioN Indication"}}, -{"pk": 1783, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21684, "parent": 934, "list_email": "marf@ietf.org", "acronym": "marf", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/marf", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/marf/", "type": "wg", "name": "Messaging Abuse Reporting Format"}}, -{"pk": 1784, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 105907, "parent": 934, "list_email": "", "acronym": "newprep", "comments": "1st meeting at 77th IETF-Anaheim, CA, USA;\r\nBecame PRECIS working group 2010-06-11", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Stringprep after IDNA2008"}}, +{"pk": 1775, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "conex@ietf.org", "acronym": "conex", "comments": "1st meeting at 76th IETF-Hiroshima, Japan", "list_subscribe": "https://www.ietf.org/mailman/listinfo/conex", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/conex/", "type": "wg", "name": "Congestion Exposure"}}, +{"pk": 1776, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "nat66", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPv6-to-IPv6 Network Address Translation"}}, +{"pk": 1777, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "hybi@ietf.org", "acronym": "hybi", "comments": "1st meeting at 76th IETF-Hiroshima, Japan", "list_subscribe": "https://www.ietf.org/mailman/listinfo/hybi", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/hybi/", "type": "wg", "name": "BiDirectional or Server-Initiated HTTP"}}, +{"pk": 1778, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "public-iri@w3.org", "acronym": "iri", "comments": "1st meeting at 76th IETF-Hiroshima, Japan", "list_subscribe": "public-iri-request@w3.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.w3.org/Archives/Public/public-iri/", "type": "wg", "name": "Internationalized Resource Identifiers"}}, +{"pk": 1779, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "int-area@ietf.org", "acronym": "intareawg", "comments": "See", "list_subscribe": "https://www.ietf.org/mailman/listinfo/int-area", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/int-area/", "type": "wg", "name": "Internet Area Proposed Working Group"}}, +{"pk": 1780, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "decade@ietf.org", "acronym": "decade", "comments": "1st meeting at 76th IETF-Hiroshima, Japan; 2nd meeting at 77th IETF-Anaheim, CA, USA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/decade", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/decade/", "type": "wg", "name": "Decoupled Application Data Enroute"}}, +{"pk": 1781, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "http-state@ietf.org", "acronym": "httpstate", "comments": "Alternative Archive: http://groups.google.com/group/http-state", "list_subscribe": "https://www.ietf.org/mailman/listinfo/http-state", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/http-state/", "type": "wg", "name": "HTTP State Management Mechanism"}}, +{"pk": 1782, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "martini@ietf.org", "acronym": "martini", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/martini", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/martini/", "type": "wg", "name": "Multiple AoR reachabiliTy InformatioN Indication"}}, +{"pk": 1783, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "marf@ietf.org", "acronym": "marf", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/marf", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/marf/", "type": "wg", "name": "Messaging Abuse Reporting Format"}}, +{"pk": 1784, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "newprep", "comments": "1st meeting at 77th IETF-Anaheim, CA, USA;\r\nBecame PRECIS working group 2010-06-11", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Stringprep after IDNA2008"}}, {"pk": 1785, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "rydeirde", "comments": "1st meeting at 77th IETF-Anaheim, CA, USA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Registry Data Escrow/Internet Registration Escrow"}}, -{"pk": 1786, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "wgdtspec", "comments": "1st meeting at 77th IETF-Anaheim, CA, USA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Review of Datatracker Specifications to Support"}}, +{"pk": 1786, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "wgdtspec", "comments": "1st meeting at 77th IETF-Anaheim, CA, USA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Review of Datatracker Specifications to Support"}}, {"pk": 1787, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "", "acronym": "e2md", "comments": "1st meeting at 77th IETF-Anaheim, CA, USA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "E. 164 to Metadata"}}, -{"pk": 1788, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "siprec@ietf.org", "acronym": "siprec", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/siprec", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/siprec/", "type": "wg", "name": "SIP Recording"}}, -{"pk": 1789, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21684, "parent": 934, "list_email": "core@ietf.org", "acronym": "core", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/core", "state": "active", "time": "2012-09-10 16:56:30", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/core/", "type": "wg", "name": "Constrained RESTful Environments"}}, -{"pk": 1791, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "sip-overload@ietf.org", "acronym": "soc", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/sip-overload", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sip-overload/", "type": "wg", "name": "SIP Overload Control"}}, -{"pk": 1792, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21684, "parent": 934, "list_email": "urn@ietf.org", "acronym": "urnbis", "comments": "1st meeting at 78th IETF-Maastricht, Netherlands", "list_subscribe": "https://www.ietf.org/mailman/listinfo/urn", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/urn/", "type": "wg", "name": "Uniform Resource Names, Revised"}}, -{"pk": 1793, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "", "acronym": "fedauth", "comments": "1st meeting at IETF 78-Maastricht, Netherlands", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Federated Authentication Beyond the Web"}}, -{"pk": 1794, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 105907, "parent": 934, "list_email": "", "acronym": "hasmat", "comments": "1st meeting at IETF 78-Maastricht, Netherlands", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "HTTP Application Security Minus Authentication and Transport"}}, -{"pk": 1795, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "salud@ietf.org", "acronym": "salud", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/salud", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/salud/", "type": "wg", "name": "Sip ALerting for User Devices"}}, -{"pk": 1796, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "cuss@ietf.org", "acronym": "cuss", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/cuss", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/cuss/", "type": "wg", "name": "Call Control UUI Service for SIP"}}, -{"pk": 1797, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "splices@ietf.org", "acronym": "splices", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/splices", "state": "conclude", "time": "2012-01-25 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/splices/", "type": "wg", "name": "looSely-couPLed sIp deviCES"}}, -{"pk": 1798, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 18321, "parent": 934, "list_email": "precis@ietf.org", "acronym": "precis", "comments": "was NEWPREP BOF", "list_subscribe": "https://www.ietf.org/mailman/listinfo/precis", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/precis/", "type": "wg", "name": "Preparation and Comparison of Internationalized Strings"}}, -{"pk": 1799, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 18321, "parent": 934, "list_email": "ftpext@ietf.org", "acronym": "ftpext2", "comments": "1st meeting at IETF 78 - Maastricht, Netherlands", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ftpext", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ftpext/", "type": "wg", "name": "FTP Extensions, 2nd edition"}}, -{"pk": 1800, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "pcp@ietf.org", "acronym": "pcp", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/pcp", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pcp/", "type": "wg", "name": "Port Control Protocol"}}, -{"pk": 1801, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 105682, "parent": 1193, "list_email": "eman@ietf.org", "acronym": "eman", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/eman", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/eman", "type": "wg", "name": "Energy Management"}}, -{"pk": 1802, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21684, "parent": 934, "list_email": "websec@ietf.org", "acronym": "websec", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/websec", "state": "active", "time": "2012-07-30 13:20:27", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/websec/", "type": "wg", "name": "Web Security"}}, -{"pk": 1803, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "homenet@ietf.org", "acronym": "homenet", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/homenet", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/homenet/", "type": "wg", "name": "Home Networking"}}, -{"pk": 1804, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 19177, "parent": 1260, "list_email": "abfab@ietf.org", "acronym": "abfab", "comments": "Note that this proposed WG emerged from the FEDAUTH BoF held\r\nat IETF 78.", "list_subscribe": "https://www.ietf.org/mailman/listinfo/abfab", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/abfab/", "type": "wg", "name": "Application Bridging for Federated Access Beyond web"}}, -{"pk": 1805, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21684, "parent": 934, "list_email": "apps-discuss@ietf.org", "acronym": "appsawg", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/apps-discuss", "state": "active", "time": "2012-07-03 07:35:06", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/apps-discuss/", "type": "wg", "name": "Applications Area Working Group"}}, -{"pk": 1806, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "iddtspec", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Review of Datatracker Specifications to Follow Internet-Draft Activities"}}, -{"pk": 1807, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 101568, "parent": 1193, "list_email": "armd@ietf.org", "acronym": "armd", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/armd", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/armd/", "type": "wg", "name": "Address Resolution for Massive numbers of hosts in the Data center"}}, -{"pk": 1808, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 17253, "parent": 1324, "list_email": "", "acronym": "nbs", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Name-Based Sockets"}}, -{"pk": 1809, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "", "acronym": "lwip", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Light-Weight IP Protocol Design"}}, -{"pk": 1810, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 19177, "parent": 1260, "list_email": "dane@ietf.org", "acronym": "dane", "comments": "Previously was 'kidns' BOF.", "list_subscribe": "https://www.ietf.org/mailman/listinfo/dane", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dane/", "type": "wg", "name": "DNS-based Authentication of Named Entities"}}, -{"pk": 1811, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "", "acronym": "scap", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Synergy of SCAP Program and IETF Activities"}}, -{"pk": 1812, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "avt@ietf.org", "acronym": "avtcore", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/avt", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/avt/", "type": "wg", "name": "Audio/Video Transport Core Maintenance"}}, -{"pk": 1813, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "avtext@ietf.org", "acronym": "avtext", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/avtext", "state": "active", "time": "2013-01-11 09:03:50", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/avtext/", "type": "wg", "name": "Audio/Video Transport Extensions"}}, -{"pk": 1814, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "payload@ietf.org", "acronym": "payload", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/payload", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/payload/", "type": "wg", "name": "Audio/Video Transport Payloads"}}, -{"pk": 1815, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "xrblock@ietf.org", "acronym": "xrblock", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/xrblock", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/xrblock/", "type": "wg", "name": "Metric Blocks for use with RTCP's Extended Report Framework"}}, -{"pk": 1816, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "clue@ietf.org", "acronym": "clue", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/clue", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/clue/", "type": "wg", "name": "ControLling mUltiple streams for tElepresence"}}, -{"pk": 1817, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 100664, "parent": 1052, "list_email": "lwip@ietf.org", "acronym": "lwig", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/lwip", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/lwip", "type": "wg", "name": "Light-Weight Implementation Guidance"}}, -{"pk": 1818, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 101568, "parent": 1193, "list_email": "", "acronym": "renum", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Site Renumbering"}}, -{"pk": 1819, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 18321, "parent": 934, "list_email": "paws@ietf.org", "acronym": "paws", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/paws", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/paws/", "type": "wg", "name": "Protocol to Access WS database"}}, -{"pk": 1820, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "rtcweb@ietf.org", "acronym": "rtcweb", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/rtcweb", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rtcweb/", "type": "wg", "name": "Real-Time Communication in WEB-browsers"}}, -{"pk": 1821, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 19177, "parent": 1260, "list_email": "", "acronym": "plasma", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Policy Augmented S/Mime"}}, -{"pk": 1822, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 105519, "parent": 1324, "list_email": "cdni@ietf.org", "acronym": "cdni", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/cdni", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/cdni/", "type": "wg", "name": "Content Delivery Networks Interconnection"}}, -{"pk": 1823, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "vipr@ietf.org", "acronym": "vipr", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/vipr", "state": "active", "time": "2012-02-10 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/vipr/", "type": "wg", "name": "Verification Involving PSTN Reachability"}}, -{"pk": 1824, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 101568, "parent": 1193, "list_email": "renum@ietf.org", "acronym": "6renum", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/renum", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/renum/", "type": "wg", "name": "IPv6 Site Renumbering"}}, -{"pk": 1825, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 101568, "parent": 1193, "list_email": "multrans@ietf.org", "acronym": "multrans", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/multrans", "state": "bof-conc", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Multicast Transition "}}, -{"pk": 1826, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "http-auth@ietf.org", "acronym": "httpauth", "comments": "BOF at IETF 85", "list_subscribe": "https://www.ietf.org/mailman/listinfo/http-auth", "state": "bof", "time": "2013-01-31 11:23:01", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/http-auth/", "type": "wg", "name": "Hypertext Transmission Protocol Authentication"}}, -{"pk": 1827, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 18321, "parent": 934, "list_email": "domainrep@ietf.org", "acronym": "repute", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/domainrep/", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/domainrep/", "type": "wg", "name": "Reputation Services"}}, -{"pk": 1828, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "cicm@ietf.org", "acronym": "cicm", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/cicm", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/cicm/", "type": "wg", "name": "Common Interface to Cryptographic Modules"}}, -{"pk": 1829, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "woes@ietf.org", "acronym": "woes", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/woes", "state": "bof-conc", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/woes/", "type": "wg", "name": "Web Object Encryption and Signing"}}, -{"pk": 1830, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "jose@ietf.org", "acronym": "jose", "comments": "Originally WOES BOF at IETF 81", "list_subscribe": "https://www.ietf.org/mailman/listinfo/jose", "state": "active", "time": "2012-08-01 14:21:17", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/jose/", "type": "wg", "name": "Javascript Object Signing and Encryption"}}, -{"pk": 1831, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "mile@ietf.org", "acronym": "mile", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/mile", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mile/", "type": "wg", "name": "Managed Incident Lightweight Exchange"}}, -{"pk": 1832, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "bfcpbis@ietf.org", "acronym": "bfcpbis", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/bfcpbis", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/bfcpbis/", "type": "wg", "name": "Binary Floor Control Protocol Bis "}}, -{"pk": 1833, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "", "acronym": "dcon", "comments": "", "list_subscribe": "", "state": "bof-conc", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Distributed Conferencing"}}, -{"pk": 1834, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 18321, "parent": 934, "list_email": "weirds@ietf.org", "acronym": "weirds", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/weirds", "state": "active", "time": "2012-02-23 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/weirds/", "type": "wg", "name": "Web Extensible Internet Registration Data Service"}}, -{"pk": 1835, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 104198, "parent": 1249, "list_email": "", "acronym": "sdn", "comments": "", "list_subscribe": "", "state": "bof-conc", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Software Driven Networks "}}, -{"pk": 1836, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 18321, "parent": 934, "list_email": "spfbis@ietf.org", "acronym": "spfbis", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/spfbis", "state": "active", "time": "2012-02-07 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/spfbis/", "type": "wg", "name": "SPF Update"}}, -{"pk": 1837, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "", "acronym": "dmm-proposed", "comments": "Proposed re-naming of MEXT WG", "list_subscribe": "", "state": "conclude", "time": "2012-01-10 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Distributed Mobility Management (formerly MEXT)"}}, -{"pk": 1838, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 110856, "parent": 1324, "list_email": "rmcat@ietf.org", "acronym": "rmcat", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/rmcat", "state": "active", "time": "2012-09-21 09:53:53", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rmcat/", "type": "wg", "name": "RTP Media Congestion Avoidance Techniques"}}, -{"pk": 1839, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "insipid@ietf.org", "acronym": "insipid", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/insipid", "state": "active", "time": "2012-02-23 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/insipid/", "type": "wg", "name": "INtermediary-safe SIP session ID"}}, -{"pk": 1840, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2329, "parent": 1249, "list_email": "nvo3@ietf.org", "acronym": "nvo3", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/nvo3", "state": "active", "time": "2012-02-23 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/nvo3/", "type": "wg", "name": "Network Virtualization Overlays"}}, +{"pk": 1788, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "siprec@ietf.org", "acronym": "siprec", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/siprec", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/siprec/", "type": "wg", "name": "SIP Recording"}}, +{"pk": 1789, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "core@ietf.org", "acronym": "core", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/core", "state": "active", "time": "2012-09-10 16:56:30", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/core/", "type": "wg", "name": "Constrained RESTful Environments"}}, +{"pk": 1791, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "sip-overload@ietf.org", "acronym": "soc", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/sip-overload", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sip-overload/", "type": "wg", "name": "SIP Overload Control"}}, +{"pk": 1792, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "urn@ietf.org", "acronym": "urnbis", "comments": "1st meeting at 78th IETF-Maastricht, Netherlands", "list_subscribe": "https://www.ietf.org/mailman/listinfo/urn", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/urn/", "type": "wg", "name": "Uniform Resource Names, Revised"}}, +{"pk": 1793, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "fedauth", "comments": "1st meeting at IETF 78-Maastricht, Netherlands", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Federated Authentication Beyond the Web"}}, +{"pk": 1794, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "hasmat", "comments": "1st meeting at IETF 78-Maastricht, Netherlands", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "HTTP Application Security Minus Authentication and Transport"}}, +{"pk": 1795, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "salud@ietf.org", "acronym": "salud", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/salud", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/salud/", "type": "wg", "name": "Sip ALerting for User Devices"}}, +{"pk": 1796, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "cuss@ietf.org", "acronym": "cuss", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/cuss", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/cuss/", "type": "wg", "name": "Call Control UUI Service for SIP"}}, +{"pk": 1797, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "splices@ietf.org", "acronym": "splices", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/splices", "state": "conclude", "time": "2012-01-25 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/splices/", "type": "wg", "name": "looSely-couPLed sIp deviCES"}}, +{"pk": 1798, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "precis@ietf.org", "acronym": "precis", "comments": "was NEWPREP BOF", "list_subscribe": "https://www.ietf.org/mailman/listinfo/precis", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/precis/", "type": "wg", "name": "Preparation and Comparison of Internationalized Strings"}}, +{"pk": 1799, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "ftpext@ietf.org", "acronym": "ftpext2", "comments": "1st meeting at IETF 78 - Maastricht, Netherlands", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ftpext", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ftpext/", "type": "wg", "name": "FTP Extensions, 2nd edition"}}, +{"pk": 1800, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "pcp@ietf.org", "acronym": "pcp", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/pcp", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pcp/", "type": "wg", "name": "Port Control Protocol"}}, +{"pk": 1801, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "eman@ietf.org", "acronym": "eman", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/eman", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/eman", "type": "wg", "name": "Energy Management"}}, +{"pk": 1802, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "websec@ietf.org", "acronym": "websec", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/websec", "state": "active", "time": "2012-07-30 13:20:27", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/websec/", "type": "wg", "name": "Web Security"}}, +{"pk": 1803, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "homenet@ietf.org", "acronym": "homenet", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/homenet", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/homenet/", "type": "wg", "name": "Home Networking"}}, +{"pk": 1804, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "abfab@ietf.org", "acronym": "abfab", "comments": "Note that this proposed WG emerged from the FEDAUTH BoF held\r\nat IETF 78.", "list_subscribe": "https://www.ietf.org/mailman/listinfo/abfab", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/abfab/", "type": "wg", "name": "Application Bridging for Federated Access Beyond web"}}, +{"pk": 1805, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "apps-discuss@ietf.org", "acronym": "appsawg", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/apps-discuss", "state": "active", "time": "2012-07-03 07:35:06", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/apps-discuss/", "type": "wg", "name": "Applications Area Working Group"}}, +{"pk": 1806, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "iddtspec", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Review of Datatracker Specifications to Follow Internet-Draft Activities"}}, +{"pk": 1807, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "armd@ietf.org", "acronym": "armd", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/armd", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/armd/", "type": "wg", "name": "Address Resolution for Massive numbers of hosts in the Data center"}}, +{"pk": 1808, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "nbs", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Name-Based Sockets"}}, +{"pk": 1809, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "lwip", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Light-Weight IP Protocol Design"}}, +{"pk": 1810, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "dane@ietf.org", "acronym": "dane", "comments": "Previously was 'kidns' BOF.", "list_subscribe": "https://www.ietf.org/mailman/listinfo/dane", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dane/", "type": "wg", "name": "DNS-based Authentication of Named Entities"}}, +{"pk": 1811, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "scap", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Synergy of SCAP Program and IETF Activities"}}, +{"pk": 1812, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "avt@ietf.org", "acronym": "avtcore", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/avt", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/avt/", "type": "wg", "name": "Audio/Video Transport Core Maintenance"}}, +{"pk": 1813, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "avtext@ietf.org", "acronym": "avtext", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/avtext", "state": "active", "time": "2013-01-11 09:03:50", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/avtext/", "type": "wg", "name": "Audio/Video Transport Extensions"}}, +{"pk": 1814, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "payload@ietf.org", "acronym": "payload", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/payload", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/payload/", "type": "wg", "name": "Audio/Video Transport Payloads"}}, +{"pk": 1815, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "xrblock@ietf.org", "acronym": "xrblock", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/xrblock", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/xrblock/", "type": "wg", "name": "Metric Blocks for use with RTCP's Extended Report Framework"}}, +{"pk": 1816, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "clue@ietf.org", "acronym": "clue", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/clue", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/clue/", "type": "wg", "name": "ControLling mUltiple streams for tElepresence"}}, +{"pk": 1817, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "lwip@ietf.org", "acronym": "lwig", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/lwip", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/lwip", "type": "wg", "name": "Light-Weight Implementation Guidance"}}, +{"pk": 1818, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "renum", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Site Renumbering"}}, +{"pk": 1819, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "paws@ietf.org", "acronym": "paws", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/paws", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/paws/", "type": "wg", "name": "Protocol to Access WS database"}}, +{"pk": 1820, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "rtcweb@ietf.org", "acronym": "rtcweb", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/rtcweb", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rtcweb/", "type": "wg", "name": "Real-Time Communication in WEB-browsers"}}, +{"pk": 1821, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "plasma", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Policy Augmented S/Mime"}}, +{"pk": 1822, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "cdni@ietf.org", "acronym": "cdni", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/cdni", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/cdni/", "type": "wg", "name": "Content Delivery Networks Interconnection"}}, +{"pk": 1823, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "vipr@ietf.org", "acronym": "vipr", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/vipr", "state": "active", "time": "2012-02-10 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/vipr/", "type": "wg", "name": "Verification Involving PSTN Reachability"}}, +{"pk": 1824, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "renum@ietf.org", "acronym": "6renum", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/renum", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/renum/", "type": "wg", "name": "IPv6 Site Renumbering"}}, +{"pk": 1825, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "multrans@ietf.org", "acronym": "multrans", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/multrans", "state": "bof-conc", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Multicast Transition "}}, +{"pk": 1826, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "http-auth@ietf.org", "acronym": "httpauth", "comments": "BOF at IETF 85", "list_subscribe": "https://www.ietf.org/mailman/listinfo/http-auth", "state": "bof", "time": "2013-01-31 11:23:01", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/http-auth/", "type": "wg", "name": "Hypertext Transmission Protocol Authentication"}}, +{"pk": 1827, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "domainrep@ietf.org", "acronym": "repute", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/domainrep/", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/domainrep/", "type": "wg", "name": "Reputation Services"}}, +{"pk": 1828, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "cicm@ietf.org", "acronym": "cicm", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/cicm", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/cicm/", "type": "wg", "name": "Common Interface to Cryptographic Modules"}}, +{"pk": 1829, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "woes@ietf.org", "acronym": "woes", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/woes", "state": "bof-conc", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/woes/", "type": "wg", "name": "Web Object Encryption and Signing"}}, +{"pk": 1830, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "jose@ietf.org", "acronym": "jose", "comments": "Originally WOES BOF at IETF 81", "list_subscribe": "https://www.ietf.org/mailman/listinfo/jose", "state": "active", "time": "2012-08-01 14:21:17", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/jose/", "type": "wg", "name": "Javascript Object Signing and Encryption"}}, +{"pk": 1831, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "mile@ietf.org", "acronym": "mile", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/mile", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mile/", "type": "wg", "name": "Managed Incident Lightweight Exchange"}}, +{"pk": 1832, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "bfcpbis@ietf.org", "acronym": "bfcpbis", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/bfcpbis", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/bfcpbis/", "type": "wg", "name": "Binary Floor Control Protocol Bis "}}, +{"pk": 1833, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "", "acronym": "dcon", "comments": "", "list_subscribe": "", "state": "bof-conc", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Distributed Conferencing"}}, +{"pk": 1834, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "weirds@ietf.org", "acronym": "weirds", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/weirds", "state": "active", "time": "2012-02-23 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/weirds/", "type": "wg", "name": "Web Extensible Internet Registration Data Service"}}, +{"pk": 1835, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "", "acronym": "sdn", "comments": "", "list_subscribe": "", "state": "bof-conc", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Software Driven Networks "}}, +{"pk": 1836, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "spfbis@ietf.org", "acronym": "spfbis", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/spfbis", "state": "active", "time": "2012-02-07 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/spfbis/", "type": "wg", "name": "SPF Update"}}, +{"pk": 1837, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "dmm-proposed", "comments": "Proposed re-naming of MEXT WG", "list_subscribe": "", "state": "conclude", "time": "2012-01-10 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Distributed Mobility Management (formerly MEXT)"}}, +{"pk": 1838, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "rmcat@ietf.org", "acronym": "rmcat", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/rmcat", "state": "active", "time": "2012-09-21 09:53:53", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rmcat/", "type": "wg", "name": "RTP Media Congestion Avoidance Techniques"}}, +{"pk": 1839, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "insipid@ietf.org", "acronym": "insipid", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/insipid", "state": "active", "time": "2012-02-23 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/insipid/", "type": "wg", "name": "INtermediary-safe SIP session ID"}}, +{"pk": 1840, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "nvo3@ietf.org", "acronym": "nvo3", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/nvo3", "state": "active", "time": "2012-02-23 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/nvo3/", "type": "wg", "name": "Network Virtualization Overlays"}}, {"pk": 1841, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "i2aex", "comments": "Originally ALTOEXT; was changed before the 1st BOF.", "list_subscribe": "", "state": "bof-conc", "time": "2012-02-23 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Infrastructure-to-Application Information Exposure"}}, -{"pk": 1842, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21684, "parent": 934, "list_email": "scim@ietf.org", "acronym": "scim", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/scim", "state": "active", "time": "2012-02-23 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/scim/", "type": "wg", "name": "System for Cross-domain Identity Management"}}, -{"pk": 1843, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "rpsreqs", "comments": "", "list_subscribe": "", "state": "bof-conc", "time": "2012-02-23 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Remote Participation System Requirements"}}, -{"pk": 1844, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "antitrust", "comments": "", "list_subscribe": "", "state": "bof-conc", "time": "2012-02-23 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Does the IETF Need an Anti-Trust Policy"}}, -{"pk": 1845, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "rfcform", "comments": "", "list_subscribe": "", "state": "bof-conc", "time": "2012-02-27 13:37:14", "unused_tags": [], "list_archive": "", "type": "wg", "name": "RFC Format"}}, +{"pk": 1842, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "scim@ietf.org", "acronym": "scim", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/scim", "state": "active", "time": "2012-02-23 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/scim/", "type": "wg", "name": "System for Cross-domain Identity Management"}}, +{"pk": 1843, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "rpsreqs", "comments": "", "list_subscribe": "", "state": "bof-conc", "time": "2012-02-23 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Remote Participation System Requirements"}}, +{"pk": 1844, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "antitrust", "comments": "", "list_subscribe": "", "state": "bof-conc", "time": "2012-02-23 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Does the IETF Need an Anti-Trust Policy"}}, +{"pk": 1845, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "rfcform", "comments": "", "list_subscribe": "", "state": "bof-conc", "time": "2012-02-27 13:37:14", "unused_tags": [], "list_archive": "", "type": "wg", "name": "RFC Format"}}, {"pk": 1846, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 51, "list_email": "", "acronym": "itu-t-wp-5-13", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-02-28 13:45:20", "unused_tags": [], "list_archive": "", "type": "sdo", "name": "ITU-T Working Party 5/13"}}, -{"pk": 1847, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 100664, "parent": 1052, "list_email": "dmm@ietf.org", "acronym": "dmm", "comments": "Renamed from Mobility EXTensions for IPv6 (mext) in January 2012", "list_subscribe": "https://www.ietf.org/mailman/listinfo/dmm", "state": "active", "time": "2012-03-05 09:38:10", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dmm", "type": "wg", "name": "Distributed Mobility Management"}}, -{"pk": 1848, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "sunset4@ietf.org", "acronym": "sunset4", "comments": "Originally v4exit, changed before external review.", "list_subscribe": "https://www.ietf.org/mailman/listinfo/sunset4", "state": "active", "time": "2012-04-05 09:20:44", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sunset4/", "type": "wg", "name": "Sunsetting IPv4"}}, +{"pk": 1847, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "dmm@ietf.org", "acronym": "dmm", "comments": "Renamed from Mobility EXTensions for IPv6 (mext) in January 2012", "list_subscribe": "https://www.ietf.org/mailman/listinfo/dmm", "state": "active", "time": "2012-03-05 09:38:10", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dmm", "type": "wg", "name": "Distributed Mobility Management"}}, +{"pk": 1848, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "sunset4@ietf.org", "acronym": "sunset4", "comments": "Originally v4exit, changed before external review.", "list_subscribe": "https://www.ietf.org/mailman/listinfo/sunset4", "state": "active", "time": "2012-04-05 09:20:44", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sunset4/", "type": "wg", "name": "Sunsetting IPv4"}}, {"pk": 1849, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 3, "list_email": "icnrg@irtf.org", "acronym": "icnrg", "comments": "", "list_subscribe": "http://irtf.org/mailman/listinfo/icnrg", "state": "active", "time": "2012-04-24 09:47:41", "unused_tags": [], "list_archive": "http://www.irtf.org/mail-archive/web/icnrg/", "type": "rg", "name": "Information-Centric Networking"}}, {"pk": 1850, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "nomcom2012", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-05-03 11:20:20", "unused_tags": [], "list_archive": "", "type": "ietf", "name": "IAB/IESG Nominating Committee 2012/2013"}}, -{"pk": 1851, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21684, "parent": 934, "list_email": "imapext@ietf.org", "acronym": "imapmove", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/imapext", "state": "conclude", "time": "2012-06-26 09:17:05", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/imapext/", "type": "wg", "name": "IMAP MOVE extension"}}, -{"pk": 1852, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "straw@ietf.org", "acronym": "straw", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/straw", "state": "active", "time": "2012-07-10 09:40:03", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/straw/", "type": "wg", "name": "Sip Traversal Required for Applications to Work"}}, +{"pk": 1851, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "imapext@ietf.org", "acronym": "imapmove", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/imapext", "state": "conclude", "time": "2012-06-26 09:17:05", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/imapext/", "type": "wg", "name": "IMAP MOVE extension"}}, +{"pk": 1852, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "straw@ietf.org", "acronym": "straw", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/straw", "state": "active", "time": "2012-07-10 09:40:03", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/straw/", "type": "wg", "name": "Sip Traversal Required for Applications to Work"}}, {"pk": 1853, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 3, "list_email": "", "acronym": "irtfopen", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-06-06 09:42:20", "unused_tags": [], "list_archive": "", "type": "ag", "name": "IRTF Open Meeting"}}, -{"pk": 1854, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 18321, "parent": 934, "list_email": "", "acronym": "dsii", "comments": "", "list_subscribe": "", "state": "bof-conc", "time": "2012-06-20 09:30:10", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Data Set Identifier Interoperability"}}, +{"pk": 1854, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "dsii", "comments": "", "list_subscribe": "", "state": "bof-conc", "time": "2012-06-20 09:30:10", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Data Set Identifier Interoperability"}}, {"pk": 1855, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "stephaniemccammon@gmail.com, smccammon@amsl.com", "acronym": "smcamo", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-06-27 08:44:05", "unused_tags": [], "list_archive": "", "type": "sdo", "name": "smcamo"}}, {"pk": 1857, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 3, "list_email": "", "acronym": "sdnrg", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-06-28 09:39:45", "unused_tags": [], "list_archive": "", "type": "rg", "name": "Software Defined Networking Research Group"}}, {"pk": 1858, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ONF", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-07-03 10:22:12", "unused_tags": [], "list_archive": "", "type": "sdo", "name": "ONF"}}, @@ -1003,25 +1003,25 @@ {"pk": 1861, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 3, "list_email": "irsg@irtf.org", "acronym": "irsg", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-08-02 10:11:25", "unused_tags": [], "list_archive": "", "type": "irtf", "name": "Internet Research Steering Group"}}, {"pk": 1862, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ieee-80211", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-08-28 13:26:59", "unused_tags": [], "list_archive": "", "type": "sdo", "name": "IEEE 802.11"}}, {"pk": 1863, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "rse", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-09-13 08:45:42", "unused_tags": [], "list_archive": "", "type": "ietf", "name": "RFC Series Editor"}}, -{"pk": 1864, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "video-codec@ietf.org", "acronym": "videocodec", "comments": "BOF at IETF 85", "list_subscribe": "https://www.ietf.org/mailman/listinfo/video-codec", "state": "bof-conc", "time": "2012-09-26 10:43:01", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/video-codec/", "type": "wg", "name": "Internet Video Codec"}}, -{"pk": 1865, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 104198, "parent": 1249, "list_email": "irs-discuss@ietf.org", "acronym": "irs", "comments": "BOF at IETF 85", "list_subscribe": "http://www.ietf.org/mailman/listinfo/irs-discuss ", "state": "bof-conc", "time": "2012-09-26 10:46:57", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/irs-discuss/", "type": "wg", "name": "Interface to the Routing System"}}, -{"pk": 1866, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "", "acronym": "fmc", "comments": "BOF at IETF 85", "list_subscribe": "", "state": "bof-conc", "time": "2012-09-26 10:51:42", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Fixed Mobile Convergence"}}, -{"pk": 1867, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "", "acronym": "mdnsext", "comments": "BOF at IETF 85", "list_subscribe": "", "state": "bof-conc", "time": "2012-09-26 10:54:19", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Extensions to the Bonjour protocol suite"}}, -{"pk": 1868, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 19177, "parent": 1260, "list_email": "", "acronym": "certrans", "comments": "BOF at IETF 85", "list_subscribe": "", "state": "bof-conc", "time": "2012-09-26 10:56:57", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Certificate Transparency"}}, -{"pk": 1869, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "", "acronym": "sacm", "comments": "BOF at IETF 85", "list_subscribe": "", "state": "bof", "time": "2012-09-26 11:00:55", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Security Automation and Continuous Monitoring"}}, -{"pk": 1870, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 101568, "parent": 1193, "list_email": "wpkops@ietf.org", "acronym": "wpkops", "comments": "BOF at IETF 85", "list_subscribe": "https://www.ietf.org/mailman/listinfo/wpkops", "state": "proposed", "time": "2013-01-07 07:19:03", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/wpkops/", "type": "wg", "name": "Web PKI OPS"}}, +{"pk": 1864, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "video-codec@ietf.org", "acronym": "videocodec", "comments": "BOF at IETF 85", "list_subscribe": "https://www.ietf.org/mailman/listinfo/video-codec", "state": "bof-conc", "time": "2012-09-26 10:43:01", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/video-codec/", "type": "wg", "name": "Internet Video Codec"}}, +{"pk": 1865, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "irs-discuss@ietf.org", "acronym": "irs", "comments": "BOF at IETF 85", "list_subscribe": "http://www.ietf.org/mailman/listinfo/irs-discuss ", "state": "bof-conc", "time": "2012-09-26 10:46:57", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/irs-discuss/", "type": "wg", "name": "Interface to the Routing System"}}, +{"pk": 1866, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "fmc", "comments": "BOF at IETF 85", "list_subscribe": "", "state": "bof-conc", "time": "2012-09-26 10:51:42", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Fixed Mobile Convergence"}}, +{"pk": 1867, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "mdnsext", "comments": "BOF at IETF 85", "list_subscribe": "", "state": "bof-conc", "time": "2012-09-26 10:54:19", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Extensions to the Bonjour protocol suite"}}, +{"pk": 1868, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "certrans", "comments": "BOF at IETF 85", "list_subscribe": "", "state": "bof-conc", "time": "2012-09-26 10:56:57", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Certificate Transparency"}}, +{"pk": 1869, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "sacm", "comments": "BOF at IETF 85", "list_subscribe": "", "state": "bof", "time": "2012-09-26 11:00:55", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Security Automation and Continuous Monitoring"}}, +{"pk": 1870, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "wpkops@ietf.org", "acronym": "wpkops", "comments": "BOF at IETF 85", "list_subscribe": "https://www.ietf.org/mailman/listinfo/wpkops", "state": "proposed", "time": "2013-01-07 07:19:03", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/wpkops/", "type": "wg", "name": "Web PKI OPS"}}, {"pk": 1871, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ieee-80216", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-09-28 10:08:59", "unused_tags": [], "list_archive": "", "type": "sdo", "name": "IEEE 802.16"}}, {"pk": 1872, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "itu-t-jca-cloud", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-09-28 13:35:37", "unused_tags": [], "list_archive": "", "type": "sdo", "name": "ITU-T JCA-Cloud"}}, {"pk": 1873, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "iaoc", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-10-18 10:57:54", "unused_tags": [], "list_archive": "", "type": "ietf", "name": "IETF Administrative Oversight Committee"}}, {"pk": 1874, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "itu-t-jca-cop", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-10-23 13:37:57", "unused_tags": [], "list_archive": "", "type": "sdo", "name": "ITU-T JCA-COP"}}, -{"pk": 1875, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 104198, "parent": 1249, "list_email": "i2rs@ietf.org", "acronym": "i2rs", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/i2rs", "state": "active", "time": "2013-01-29 09:50:47", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/i2rs/current/maillist.html", "type": "wg", "name": "Interface to the Routing System"}}, +{"pk": 1875, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "i2rs@ietf.org", "acronym": "i2rs", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/i2rs", "state": "active", "time": "2013-01-29 09:50:47", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/i2rs/current/maillist.html", "type": "wg", "name": "Interface to the Routing System"}}, {"pk": 1876, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "rfceditor", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-11-25 11:44:11", "unused_tags": [], "list_archive": "", "type": "rfcedtyp", "name": "RFC Editor"}}, -{"pk": 1877, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 105682, "parent": 1193, "list_email": "", "acronym": "lmap", "comments": "", "list_subscribe": "", "state": "bof", "time": "2013-01-31 11:16:39", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Large-Scale Measurement of Broadband Performance"}}, -{"pk": 1878, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "history", "comments": "", "list_subscribe": "", "state": "bof", "time": "2013-01-31 11:13:55", "unused_tags": [], "list_archive": "", "type": "wg", "name": "History of the Internet"}}, -{"pk": 1879, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "iprbis", "comments": "", "list_subscribe": "", "state": "bof", "time": "2013-01-31 11:15:10", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Proposed Update IPR Policy"}}, -{"pk": 1880, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "iab-wcit", "comments": "", "list_subscribe": "", "state": "bof", "time": "2013-01-31 11:20:41", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IAB-sponsored Discussion of WCIT"}}, -{"pk": 1881, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 18321, "parent": 934, "list_email": "", "acronym": "aggsrv", "comments": "", "list_subscribe": "", "state": "bof", "time": "2013-01-31 11:24:06", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Aggregated Service Discovery"}}, -{"pk": 1882, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 21684, "parent": 934, "list_email": "", "acronym": "json", "comments": "", "list_subscribe": "", "state": "bof", "time": "2013-01-31 11:24:58", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Javascript Object Notation"}}, +{"pk": 1877, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "lmap", "comments": "", "list_subscribe": "", "state": "bof", "time": "2013-01-31 11:16:39", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Large-Scale Measurement of Broadband Performance"}}, +{"pk": 1878, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "history", "comments": "", "list_subscribe": "", "state": "bof", "time": "2013-01-31 11:13:55", "unused_tags": [], "list_archive": "", "type": "wg", "name": "History of the Internet"}}, +{"pk": 1879, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "iprbis", "comments": "", "list_subscribe": "", "state": "bof", "time": "2013-01-31 11:15:10", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Proposed Update IPR Policy"}}, +{"pk": 1880, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "iab-wcit", "comments": "", "list_subscribe": "", "state": "bof", "time": "2013-01-31 11:20:41", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IAB-sponsored Discussion of WCIT"}}, +{"pk": 1881, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "aggsrv", "comments": "", "list_subscribe": "", "state": "bof", "time": "2013-01-31 11:24:06", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Aggregated Service Discovery"}}, +{"pk": 1882, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "json", "comments": "", "list_subscribe": "", "state": "bof", "time": "2013-01-31 11:24:58", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Javascript Object Notation"}}, {"pk": 1, "model": "group.groupstatetransitions", "fields": {"state": 44, "group": 1796, "next_states": [44]}}, {"pk": 1, "model": "group.role", "fields": {"person": 106014, "group": 8, "name": "auth", "email": "michelle.cotton@icann.org"}}, {"pk": 2, "model": "group.role", "fields": {"person": 108103, "group": 8, "name": "auth", "email": "amanda.baber@icann.org"}}, diff --git a/ietf/group/fixtures/workinggroups.json b/ietf/group/fixtures/workinggroups.json index 88e5561cb..31888f2a2 100644 --- a/ietf/group/fixtures/workinggroups.json +++ b/ietf/group/fixtures/workinggroups.json @@ -1,11 +1,11 @@ [ {"pk": 1, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ietf", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-02-26 00:21:36", "unused_tags": [], "list_archive": "", "type": "ietf", "name": "IETF"}}, -{"pk": 2, "model": "group.group", "fields": {"charter": "charter-ietf-iesg", "unused_states": [], "ad": 5376, "parent": 1, "list_email": "iesg@ietf.org", "acronym": "iesg", "comments": "", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ietf", "name": "Internet Engineering Steering Group"}}, +{"pk": 2, "model": "group.group", "fields": {"charter": "charter-ietf-iesg", "unused_states": [], "ad": null, "parent": 1, "list_email": "iesg@ietf.org", "acronym": "iesg", "comments": "", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ietf", "name": "Internet Engineering Steering Group"}}, {"pk": 3, "model": "group.group", "fields": {"charter": null, "unused_states": [81, 82, 83, 84, 85, 86, 87, 88, 1, 2, 3, 4, 5, 6, 16, 13, 21, 14, 15, 19, 20, 12, 18, 9, 10, 17, 7, 22, 23, 11, 8, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 79, 80, 77, 78], "ad": null, "parent": null, "list_email": "", "acronym": "irtf", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-02-26 00:21:36", "unused_tags": ["app-min", "errata", "iana-crd", "iesg-com", "missref", "need-sh", "ref", "rfc-rev", "via-rfc", "w-dep", "need-ed", "point", "w-expert", "ad-f-up", "w-extern", "w-part", "extpty", "w-merge", "w-review", "need-aut", "sh-f-up", "need-rev", "w-refdoc", "w-refing", "rev-wglc", "rev-ad", "rev-iesg", "sheph-u", "other"], "list_archive": "", "type": "irtf", "name": "IRTF"}}, {"pk": 4, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "secretariat", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-02-26 00:21:36", "unused_tags": [], "list_archive": "", "type": "ietf", "name": "IETF Secretariat"}}, {"pk": 5, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ise", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-02-26 00:21:36", "unused_tags": [], "list_archive": "", "type": "ietf", "name": "Independent Submission Editor"}}, {"pk": 6, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "rsoc", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-02-26 00:21:36", "unused_tags": [], "list_archive": "", "type": "ietf", "name": "RFC Series Oversight Committee"}}, -{"pk": 7, "model": "group.group", "fields": {"charter": "charter-ietf-iab", "unused_states": [], "ad": 5376, "parent": 1, "list_email": "iab@iab.org", "acronym": "iab", "comments": "1st meeting at 35th IETF - Los Angeles, CA - March 1996", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ietf", "name": "Internet Architecture Board"}}, +{"pk": 7, "model": "group.group", "fields": {"charter": "charter-ietf-iab", "unused_states": [], "ad": null, "parent": 1, "list_email": "iab@iab.org", "acronym": "iab", "comments": "1st meeting at 35th IETF - Los Angeles, CA - March 1996", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ietf", "name": "Internet Architecture Board"}}, {"pk": 8, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "iana", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-02-26 00:21:36", "unused_tags": [], "list_archive": "", "type": "ietf", "name": "IANA"}}, {"pk": 9, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "iepg", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-02-26 00:21:36", "unused_tags": [], "list_archive": "", "type": "ietf", "name": "IEPG"}}, {"pk": 10, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "nomcom1992", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2012-02-26 00:21:36", "unused_tags": [], "list_archive": "", "type": "ietf", "name": "IAB/IESG Nominating Committee 1992/1993"}}, @@ -101,33 +101,33 @@ {"pk": 1683, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 2, "list_email": "", "acronym": "rai", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-02-26 00:21:37", "unused_tags": [], "list_archive": "", "type": "area", "name": "Real-time Applications and Infrastructure Area"}}, {"pk": 925, "model": "group.group", "fields": {"charter": "charter-ietf-vgmib", "unused_states": [], "ad": null, "parent": 1052, "list_email": "vgmib@hprnd.rose.hp.com", "acronym": "vgmib", "comments": "1st meeting 32nd IETF Danvers, MA April 3-7, 1995 mw (BOF)\r\n\r\nAD was Burgan", "list_subscribe": "vgmib-request@hprnd.rose.hp.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://rosegarden.external.hp.com/pub/vgmib", "type": "wg", "name": "100VG-AnyLAN MIB"}}, {"pk": 926, "model": "group.group", "fields": {"charter": "charter-ietf-asid", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-asid@umich.edu", "acronym": "asid", "comments": "1st IETF Meeting: Seattle: 94-03: BOF Name change 5/95 from Access/Synchronization of the Internet Directories WG /mw", "list_subscribe": "ietf-asid-request@umich.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://terminator.rs.itd.umich.edu/ietf-asid/archive", "type": "wg", "name": "Access, Searching and Indexing of Directories"}}, -{"pk": 927, "model": "group.group", "fields": {"charter": "charter-ietf-addrconf", "unused_states": [], "ad": 2324, "parent": 1092, "list_email": "addrconf@cisco.com", "acronym": "addrconf", "comments": "", "list_subscribe": "addrconf-request@cisco.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://munnari.oz.au/addrconf/list-archive", "type": "wg", "name": "Address Autoconfiguration"}}, -{"pk": 928, "model": "group.group", "fields": {"charter": "charter-ietf-aeiou", "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "aeiou", "comments": "1st MEETING: Seattle 94-03: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Address Extension by IP Option Usage"}}, -{"pk": 929, "model": "group.group", "fields": {"charter": "charter-ietf-ale", "unused_states": [], "ad": 2324, "parent": 1092, "list_email": "ipv4-ale@ftp.com", "acronym": "ale", "comments": "Met as a BOF in Houston. 93-11; merged with cidr on 3/16/95.", "list_subscribe": "ipv4-ale-request@ftp.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "research.ftp.com:pub/ale/", "type": "wg", "name": "Address Lifetime Expectations"}}, -{"pk": 930, "model": "group.group", "fields": {"charter": "charter-ietf-alertman", "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "alert-man@merit.edu", "acronym": "alertman", "comments": "Still has two documents to get published as experimental.", "list_subscribe": "alert-man-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Alert Management"}}, +{"pk": 927, "model": "group.group", "fields": {"charter": "charter-ietf-addrconf", "unused_states": [], "ad": null, "parent": 1092, "list_email": "addrconf@cisco.com", "acronym": "addrconf", "comments": "", "list_subscribe": "addrconf-request@cisco.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://munnari.oz.au/addrconf/list-archive", "type": "wg", "name": "Address Autoconfiguration"}}, +{"pk": 928, "model": "group.group", "fields": {"charter": "charter-ietf-aeiou", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "aeiou", "comments": "1st MEETING: Seattle 94-03: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Address Extension by IP Option Usage"}}, +{"pk": 929, "model": "group.group", "fields": {"charter": "charter-ietf-ale", "unused_states": [], "ad": null, "parent": 1092, "list_email": "ipv4-ale@ftp.com", "acronym": "ale", "comments": "Met as a BOF in Houston. 93-11; merged with cidr on 3/16/95.", "list_subscribe": "ipv4-ale-request@ftp.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "research.ftp.com:pub/ale/", "type": "wg", "name": "Address Lifetime Expectations"}}, +{"pk": 930, "model": "group.group", "fields": {"charter": "charter-ietf-alertman", "unused_states": [], "ad": null, "parent": 1157, "list_email": "alert-man@merit.edu", "acronym": "alertman", "comments": "Still has two documents to get published as experimental.", "list_subscribe": "alert-man-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Alert Management"}}, {"pk": 931, "model": "group.group", "fields": {"charter": "charter-ietf-aaarg", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-aaarg@imc.org", "acronym": "aaarg", "comments": "1st meeting held at 39th IETF - Munich, Germany", "list_subscribe": "ietf-aaarg-request@imc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www/imc.org/ietf-aaarg", "type": "wg", "name": "Application Authentication/Authorization Review Gr"}}, {"pk": 932, "model": "group.group", "fields": {"charter": "charter-ietf-acap", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-acap+@andrew.cmu.edu", "acronym": "acap", "comments": "1st meeting at 36th IETF - Montreal, Canada", "list_subscribe": "majordomo@lists.andrew.cmu.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "anonymous IMAP: cyrus.andrew.cmu.edu:archive.ietf-acap", "type": "wg", "name": "Application Configuration Access Protocol"}}, {"pk": 933, "model": "group.group", "fields": {"charter": "charter-ietf-applmib", "unused_states": [], "ad": null, "parent": 934, "list_email": "applmib@ietf.verio.net", "acronym": "applmib", "comments": "1st meeting, 34th IETF Dallas, TX December 4-8, 1995 mw", "list_subscribe": "applmib-request@ietf.verio.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ietf.verio.net/pub/applmib/archive", "type": "wg", "name": "Application MIB"}}, -{"pk": 936, "model": "group.group", "fields": {"charter": "charter-ietf-apparea", "unused_states": [], "ad": 18321, "parent": 934, "list_email": "", "acronym": "apparea", "comments": "First meeting at 35th IETF in Los Angeles, CA - March 1996", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ag", "name": "Applications Area Open Meeting"}}, +{"pk": 936, "model": "group.group", "fields": {"charter": "charter-ietf-apparea", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "apparea", "comments": "First meeting at 35th IETF in Los Angeles, CA - March 1996", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ag", "name": "Applications Area Open Meeting"}}, {"pk": 937, "model": "group.group", "fields": {"charter": "charter-ietf-apptsv", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "apptsv", "comments": "1st meeting at 35th IETF - Los Angeles - March 1996", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ag", "name": "Applications/Transport Joint Session"}}, -{"pk": 938, "model": "group.group", "fields": {"charter": "charter-ietf-osinsap", "unused_states": [], "ad": 2372, "parent": 1199, "list_email": "ietf-osi-nsap@osi3.ncsl.nist.gov", "acronym": "osinsap", "comments": "", "list_subscribe": "ietf-osi-nsap-request@osi3.ncsl.nist.gov", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Assignment of OSI NSAP Addresses"}}, -{"pk": 939, "model": "group.group", "fields": {"charter": "charter-ietf-afic", "unused_states": [], "ad": 188, "parent": null, "list_email": "", "acronym": "afic", "comments": "1st met as BOF 33rd IETF: Stockholm: 17-21 1995 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "ATM Forum/IETF Cooperation BOF"}}, +{"pk": 938, "model": "group.group", "fields": {"charter": "charter-ietf-osinsap", "unused_states": [], "ad": null, "parent": 1199, "list_email": "ietf-osi-nsap@osi3.ncsl.nist.gov", "acronym": "osinsap", "comments": "", "list_subscribe": "ietf-osi-nsap-request@osi3.ncsl.nist.gov", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Assignment of OSI NSAP Addresses"}}, +{"pk": 939, "model": "group.group", "fields": {"charter": "charter-ietf-afic", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "afic", "comments": "1st met as BOF 33rd IETF: Stockholm: 17-21 1995 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "ATM Forum/IETF Cooperation BOF"}}, {"pk": 940, "model": "group.group", "fields": {"charter": "charter-ietf-atommib", "unused_states": [], "ad": null, "parent": 1193, "list_email": "atommib@research.telcordia.com", "acronym": "atommib", "comments": "Met as atmmib BOF in Ohio. O-start 4/15/93, concluded 8/25/94", "list_subscribe": "atommib-request@research.telcordia.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.research.telcordia.com/pub/Group.archive/atommib", "type": "wg", "name": "AToM MIB"}}, -{"pk": 941, "model": "group.group", "fields": {"charter": "charter-ietf-avt", "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "avt@ietf.org", "acronym": "avt", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/avt", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/avt/", "type": "wg", "name": "Audio/Video Transport"}}, +{"pk": 941, "model": "group.group", "fields": {"charter": "charter-ietf-avt", "unused_states": [], "ad": null, "parent": 1683, "list_email": "avt@ietf.org", "acronym": "avt", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/avt", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/avt/", "type": "wg", "name": "Audio/Video Transport"}}, {"pk": 942, "model": "group.group", "fields": {"charter": "charter-ietf-aft", "unused_states": [], "ad": null, "parent": 1260, "list_email": "aft@socks.nec.com", "acronym": "aft", "comments": "1st meeting December 1994 IETF, San Jose /mw", "list_subscribe": "aft-request@socks.nec.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.socks.nec.com/aftmail/", "type": "wg", "name": "Authenticated Firewall Traversal"}}, {"pk": 943, "model": "group.group", "fields": {"charter": "charter-ietf-aac", "unused_states": [], "ad": null, "parent": 1260, "list_email": "ietf-aac@isi.edu", "acronym": "aac", "comments": "Work of the WG to be subsumed by CAT WG.", "list_subscribe": "ietf-aac-request@isi.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "prospero.isi.edu:~/pub/aac/*", "type": "wg", "name": "Authorization and Access Control"}}, {"pk": 944, "model": "group.group", "fields": {"charter": "charter-ietf-list", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-list-wg@utdallas.edu", "acronym": "list", "comments": "", "list_subscribe": "ietf-list-wg-request@utdallas.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "pub/ietf-list-wg@ftp.utdallas.edu", "type": "wg", "name": "Automated Internet Mailing List Services"}}, -{"pk": 945, "model": "group.group", "fields": {"charter": "charter-ietf-bmwg", "unused_states": [], "ad": 101568, "parent": 1193, "list_email": "bmwg@ietf.org", "acronym": "bmwg", "comments": "", "list_subscribe": "bmwg-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/bmwg/", "type": "wg", "name": "Benchmarking Methodology"}}, -{"pk": 946, "model": "group.group", "fields": {"charter": "charter-ietf-bgpdepl", "unused_states": [], "ad": 2324, "parent": 1193, "list_email": "bgpd@merit.edu", "acronym": "bgpdepl", "comments": "Not really concluded. Renamed to Cidr Deployment (cidrp)", "list_subscribe": "bgpd-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "merit.edu:~/pub/bgpd-archive", "type": "wg", "name": "BGP Deployment and Application"}}, +{"pk": 945, "model": "group.group", "fields": {"charter": "charter-ietf-bmwg", "unused_states": [], "ad": null, "parent": 1193, "list_email": "bmwg@ietf.org", "acronym": "bmwg", "comments": "", "list_subscribe": "bmwg-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/bmwg/", "type": "wg", "name": "Benchmarking Methodology"}}, +{"pk": 946, "model": "group.group", "fields": {"charter": "charter-ietf-bgpdepl", "unused_states": [], "ad": null, "parent": 1193, "list_email": "bgpd@merit.edu", "acronym": "bgpdepl", "comments": "Not really concluded. Renamed to Cidr Deployment (cidrp)", "list_subscribe": "bgpd-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "merit.edu:~/pub/bgpd-archive", "type": "wg", "name": "BGP Deployment and Application"}}, {"pk": 947, "model": "group.group", "fields": {"charter": "charter-ietf-bgp", "unused_states": [], "ad": null, "parent": 1249, "list_email": "bgp@ans.net", "acronym": "bgp", "comments": "BGP merged with IPIDRP to become IDR.", "list_subscribe": "bgp-request@ans.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp.ans.net:/pub/archive/iwg", "type": "wg", "name": "Border Gateway Protocol"}}, {"pk": 948, "model": "group.group", "fields": {"charter": "charter-ietf-bridge", "unused_states": [], "ad": null, "parent": 1193, "list_email": "bridge-mib@ietf.org", "acronym": "bridge", "comments": "mailing list was at nsl.dec.com. Ended 9/30/93. Reactivated 2/21/96", "list_subscribe": "bridge-mib-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/bridge-mib/", "type": "wg", "name": "Bridge MIB"}}, {"pk": 949, "model": "group.group", "fields": {"charter": "charter-ietf-calsch", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-calendar@imc.org", "acronym": "calsch", "comments": "", "list_subscribe": "ietf-calendar-request@imc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.imc.org/ietf-calendar/mail-archive/", "type": "wg", "name": "Calendaring and Scheduling"}}, -{"pk": 950, "model": "group.group", "fields": {"charter": "charter-ietf-charmib", "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "char-mib@decwrl.dec.com", "acronym": "charmib", "comments": "Started 8/1/90. Reactivated on 4/15/93", "list_subscribe": "char-mib-request@decwrl.dec.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Character MIB"}}, +{"pk": 950, "model": "group.group", "fields": {"charter": "charter-ietf-charmib", "unused_states": [], "ad": null, "parent": 1157, "list_email": "char-mib@decwrl.dec.com", "acronym": "charmib", "comments": "Started 8/1/90. Reactivated on 4/15/93", "list_subscribe": "char-mib-request@decwrl.dec.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Character MIB"}}, {"pk": 951, "model": "group.group", "fields": {"charter": "charter-ietf-charset", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-charsets@innosoft.com", "acronym": "charset", "comments": "", "list_subscribe": "ietf-charsets-request@innosoft.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Character Set Policy"}}, -{"pk": 953, "model": "group.group", "fields": {"charter": "charter-ietf-chassis", "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "chassismib@cs.utk.edu", "acronym": "chassis", "comments": "", "list_subscribe": "chassismib-request@cs.utk.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Chassis MIB"}}, -{"pk": 954, "model": "group.group", "fields": {"charter": "charter-ietf-cidrd", "unused_states": [], "ad": 2324, "parent": 1193, "list_email": "cidrd@iepg.org", "acronym": "cidrd", "comments": "Renamed from BGP Deployment (bgpdpl). Subsumed ale wg on 3/16/95.", "list_subscribe": "cidrd-request@iepg.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://aarnet.edu.au/pub/mailing-lists/cidrd*", "type": "wg", "name": "CIDR Deployment"}}, +{"pk": 953, "model": "group.group", "fields": {"charter": "charter-ietf-chassis", "unused_states": [], "ad": null, "parent": 1157, "list_email": "chassismib@cs.utk.edu", "acronym": "chassis", "comments": "", "list_subscribe": "chassismib-request@cs.utk.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Chassis MIB"}}, +{"pk": 954, "model": "group.group", "fields": {"charter": "charter-ietf-cidrd", "unused_states": [], "ad": null, "parent": 1193, "list_email": "cidrd@iepg.org", "acronym": "cidrd", "comments": "Renamed from BGP Deployment (bgpdpl). Subsumed ale wg on 3/16/95.", "list_subscribe": "cidrd-request@iepg.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://aarnet.edu.au/pub/mailing-lists/cidrd*", "type": "wg", "name": "CIDR Deployment"}}, {"pk": 955, "model": "group.group", "fields": {"charter": "charter-ietf-cidr", "unused_states": [], "ad": null, "parent": 1249, "list_email": "", "acronym": "cidr", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "CIDR Supernetting"}}, -{"pk": 956, "model": "group.group", "fields": {"charter": "charter-ietf-cmot", "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "netman@gateway.mitre.org", "acronym": "cmot", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "CMIP Over TCP"}}, +{"pk": 956, "model": "group.group", "fields": {"charter": "charter-ietf-cmot", "unused_states": [], "ad": null, "parent": 1157, "list_email": "netman@gateway.mitre.org", "acronym": "cmot", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "CMIP Over TCP"}}, {"pk": 957, "model": "group.group", "fields": {"charter": "charter-ietf-colip", "unused_states": [], "ad": null, "parent": null, "list_email": "colip-atm@necom830.cc.titech.ac.jp", "acronym": "colip", "comments": "1st meeting, 32nd IETF Danvers, MA April 3-7, 1995 mw", "list_subscribe": "colip-atm-request@necom830.cc.titech.ac.jp", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "CO and CL IP Transport over ATM"}}, {"pk": 958, "model": "group.group", "fields": {"charter": "charter-ietf-cipso", "unused_states": [], "ad": null, "parent": 1260, "list_email": "cipso@wdl1.wdl.loral.com", "acronym": "cipso", "comments": "This group is an external group working to join the IETF framework for some of their specific tasks. Associated w/TSIG", "list_subscribe": "cipso-request@wdl1.wdl.loral.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "archive-server@wdl1.wdl.loral.com", "type": "wg", "name": "Commercial Internet Protocol Security Option"}}, {"pk": 959, "model": "group.group", "fields": {"charter": "charter-ietf-catnip", "unused_states": [], "ad": null, "parent": 1092, "list_email": "catnip@world.std.com", "acronym": "catnip", "comments": "Originally named TPIX.", "list_subscribe": "catnip-request@world.std.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://world.std.com/pub/catnip/*", "type": "wg", "name": "Common Architecture for Next Generation IP"}}, @@ -139,115 +139,115 @@ {"pk": 965, "model": "group.group", "fields": {"charter": "charter-ietf-coredb", "unused_states": [], "ad": null, "parent": 1193, "list_email": "ietf-coredb@imc.org", "acronym": "coredb", "comments": "1st Meeting at 38th IETF - Memphis, TN Charter submitted 5/6/97. WG not established.", "list_subscribe": "ietf-coredb-request@imc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.imc.org/ietf-coredb/mail-archive/", "type": "wg", "name": "Council of Registrars Database"}}, {"pk": 966, "model": "group.group", "fields": {"charter": "charter-ietf-dlsw", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "dlsw", "comments": "1st IETF meeting: Seattle: 94-03: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Data Link Switching"}}, {"pk": 967, "model": "group.group", "fields": {"charter": "charter-ietf-dlswmib", "unused_states": [], "ad": null, "parent": 1249, "list_email": "aiw-dlsw-mib@networking.raleigh.ibm.com", "acronym": "dlswmib", "comments": "1st meeting in San Jose: December 5-9, 1994", "list_subscribe": "aiw-dlsw-mib-request@networking.raleigh.ibm.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://host name/pub/standards/aiw/maillogs/mib.mail", "type": "wg", "name": "Data Link Switching MIB"}}, -{"pk": 968, "model": "group.group", "fields": {"charter": "charter-ietf-ddniwg", "unused_states": [], "ad": 2324, "parent": 1193, "list_email": "", "acronym": "ddniwg", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "DDN Interconnectivity"}}, -{"pk": 969, "model": "group.group", "fields": {"charter": "charter-ietf-decnetiv", "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "phiv-mib@pa.dec.com", "acronym": "decnetiv", "comments": "Started 5/1/90. Went dormant 6/2/92, reactivated 4/15/93", "list_subscribe": "phiv-mib-request@pa.dec.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "DECnet Phase IV MIB"}}, +{"pk": 968, "model": "group.group", "fields": {"charter": "charter-ietf-ddniwg", "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "ddniwg", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "DDN Interconnectivity"}}, +{"pk": 969, "model": "group.group", "fields": {"charter": "charter-ietf-decnetiv", "unused_states": [], "ad": null, "parent": 1157, "list_email": "phiv-mib@pa.dec.com", "acronym": "decnetiv", "comments": "Started 5/1/90. Went dormant 6/2/92, reactivated 4/15/93", "list_subscribe": "phiv-mib-request@pa.dec.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "DECnet Phase IV MIB"}}, {"pk": 970, "model": "group.group", "fields": {"charter": "charter-ietf-drums", "unused_states": [], "ad": null, "parent": 934, "list_email": "drums@cs.utk.edu", "acronym": "drums", "comments": "", "list_subscribe": "drums-request@cs.utk.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://cs.utk.edu/pub/drums/mail-archive/", "type": "wg", "name": "Detailed Revision/Update of Message Standards"}}, -{"pk": 971, "model": "group.group", "fields": {"charter": "charter-ietf-opmeas", "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "opmeas", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Developing Operational Measurement Criteria"}}, -{"pk": 972, "model": "group.group", "fields": {"charter": "charter-ietf-roamreq", "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "roamreq", "comments": "1st meeting at 36th IETF - Montreal, Canada", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Dialup Roaming Requirements BOF"}}, -{"pk": 973, "model": "group.group", "fields": {"charter": "charter-ietf-disi", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "disi@merit.edu", "acronym": "disi", "comments": "", "list_subscribe": "disi-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "pub/disi-archive@merit.edu", "type": "wg", "name": "Directory Information Services Infrastructure"}}, +{"pk": 971, "model": "group.group", "fields": {"charter": "charter-ietf-opmeas", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "opmeas", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Developing Operational Measurement Criteria"}}, +{"pk": 972, "model": "group.group", "fields": {"charter": "charter-ietf-roamreq", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "roamreq", "comments": "1st meeting at 36th IETF - Montreal, Canada", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Dialup Roaming Requirements BOF"}}, +{"pk": 973, "model": "group.group", "fields": {"charter": "charter-ietf-disi", "unused_states": [], "ad": null, "parent": 1346, "list_email": "disi@merit.edu", "acronym": "disi", "comments": "", "list_subscribe": "disi-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "pub/disi-archive@merit.edu", "type": "wg", "name": "Directory Information Services Infrastructure"}}, {"pk": 974, "model": "group.group", "fields": {"charter": "charter-ietf-lamug", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-dis@bacon.gmu.edu", "acronym": "lamug", "comments": "1st meeting - Montreal, Canada June 1996", "list_subscribe": "ietf-dis-request@bacon.gmu.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "DIS Large-Scale Multicast Usage"}}, -{"pk": 975, "model": "group.group", "fields": {"charter": "charter-ietf-dfs", "unused_states": [], "ad": 2744, "parent": null, "list_email": "dfs-wg@citi.umich.edu", "acronym": "dfs", "comments": "", "list_subscribe": "dfs-wg-request@citi.umich.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Distributed File Systems"}}, +{"pk": 975, "model": "group.group", "fields": {"charter": "charter-ietf-dfs", "unused_states": [], "ad": null, "parent": null, "list_email": "dfs-wg@citi.umich.edu", "acronym": "dfs", "comments": "", "list_subscribe": "dfs-wg-request@citi.umich.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Distributed File Systems"}}, {"pk": 976, "model": "group.group", "fields": {"charter": "charter-ietf-dis", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "dis", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Distributed Interactive Simulation"}}, -{"pk": 977, "model": "group.group", "fields": {"charter": "charter-ietf-disman", "unused_states": [], "ad": 6699, "parent": 1193, "list_email": "disman@ietf.org", "acronym": "disman", "comments": "1st meeting 32nd IETF, Danvers April 3-7. 1995 mw\r\nOld Archvies at: ftp://ftp.ietf.org/ietf-mail-archive/disman/", "list_subscribe": "disman-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/disman/", "type": "wg", "name": "Distributed Management"}}, +{"pk": 977, "model": "group.group", "fields": {"charter": "charter-ietf-disman", "unused_states": [], "ad": null, "parent": 1193, "list_email": "disman@ietf.org", "acronym": "disman", "comments": "1st meeting 32nd IETF, Danvers April 3-7. 1995 mw\r\nOld Archvies at: ftp://ftp.ietf.org/ietf-mail-archive/disman/", "list_subscribe": "disman-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/disman/", "type": "wg", "name": "Distributed Management"}}, {"pk": 978, "model": "group.group", "fields": {"charter": "charter-ietf-chronos", "unused_states": [], "ad": null, "parent": 934, "list_email": "chronos@boombox.micro.umn.edu", "acronym": "chronos", "comments": "", "list_subscribe": "chronos-request@boombox.micro.umn.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "/pub/chronos @boombox.micro.umn.edu", "type": "wg", "name": "Distributed Scheduling Protocol"}}, -{"pk": 979, "model": "group.group", "fields": {"charter": "charter-ietf-dawg", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "", "acronym": "dawg", "comments": "1st IETF Meeting: Seattle: 94-03: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Distribution and Announcement"}}, -{"pk": 980, "model": "group.group", "fields": {"charter": "charter-ietf-dnsfutur", "unused_states": [], "ad": 2744, "parent": null, "list_email": "", "acronym": "dnsfutur", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "DNS Future Work"}}, +{"pk": 979, "model": "group.group", "fields": {"charter": "charter-ietf-dawg", "unused_states": [], "ad": null, "parent": 1346, "list_email": "", "acronym": "dawg", "comments": "1st IETF Meeting: Seattle: 94-03: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Distribution and Announcement"}}, +{"pk": 980, "model": "group.group", "fields": {"charter": "charter-ietf-dnsfutur", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "dnsfutur", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "DNS Future Work"}}, {"pk": 981, "model": "group.group", "fields": {"charter": "charter-ietf-dns2", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "dns2", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "DNS II"}}, {"pk": 982, "model": "group.group", "fields": {"charter": "charter-ietf-dnsind", "unused_states": [], "ad": null, "parent": 1052, "list_email": "namedroppers@internic.net", "acronym": "dnsind", "comments": "BOF in Seattle, then turned into WG.", "list_subscribe": "namedroppers-request@internic.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://rs.internic.net/archives/namedroppers", "type": "wg", "name": "DNS IXFR, Notification, and Dynamic Update"}}, {"pk": 983, "model": "group.group", "fields": {"charter": "charter-ietf-dnsbof", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "dnsbof", "comments": "1st meeting at Los Angeles - 35th IETF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Domain Name Server BOF"}}, -{"pk": 984, "model": "group.group", "fields": {"charter": "charter-ietf-dns", "unused_states": [], "ad": 2744, "parent": 934, "list_email": "namedroppers@nic.ddn.mil", "acronym": "dns", "comments": "Archive disappeared.", "list_subscribe": "namedroppers-request@nic.ddn.mil", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "nicfs.nic.ddn.mil:~/namedroppers/*.Z", "type": "wg", "name": "Domain Name System"}}, +{"pk": 984, "model": "group.group", "fields": {"charter": "charter-ietf-dns", "unused_states": [], "ad": null, "parent": 934, "list_email": "namedroppers@nic.ddn.mil", "acronym": "dns", "comments": "Archive disappeared.", "list_subscribe": "namedroppers-request@nic.ddn.mil", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "nicfs.nic.ddn.mil:~/namedroppers/*.Z", "type": "wg", "name": "Domain Name System"}}, {"pk": 985, "model": "group.group", "fields": {"charter": "charter-ietf-dnssec", "unused_states": [], "ad": null, "parent": 1260, "list_email": "dns-security@lists.tislabs.com", "acronym": "dnssec", "comments": "Moved from SAP to SEC on 10 May 1994 by JWS.", "list_subscribe": "dns-security-request@lists.tislabs.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.tis.com/pub/lists/dns-security", "type": "wg", "name": "Domain Name System Security"}}, {"pk": 986, "model": "group.group", "fields": {"charter": "charter-ietf-trunkmib", "unused_states": [], "ad": null, "parent": 1052, "list_email": "trunk-mib@external.cisco.com", "acronym": "trunkmib", "comments": "Orig. Start: 1/23/92; End: 2/18/93. Restarted in Stockholm. Tracy Cox Brown was co-chair for the first group. mw\r\n\r\nAD was Burgan", "list_subscribe": "trunk-mib-request@cisco.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "DS1/DS3 MIB"}}, {"pk": 987, "model": "group.group", "fields": {"charter": "charter-ietf-dcnl", "unused_states": [], "ad": null, "parent": null, "list_email": "dcnl-ietf@cray.com", "acronym": "dcnl", "comments": "Likely to become a Working Group", "list_subscribe": "dcnl-ietf-request@cray.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Dynamic Creation of Network Links (T3 Circuits)"}}, -{"pk": 988, "model": "group.group", "fields": {"charter": "charter-ietf-dhc", "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "dhcwg@ietf.org", "acronym": "dhc", "comments": "", "list_subscribe": "http://www.ietf.org/mailman/listinfo/dhcwg", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dhcwg/", "type": "wg", "name": "Dynamic Host Configuration"}}, +{"pk": 988, "model": "group.group", "fields": {"charter": "charter-ietf-dhc", "unused_states": [], "ad": null, "parent": 1052, "list_email": "dhcwg@ietf.org", "acronym": "dhc", "comments": "", "list_subscribe": "http://www.ietf.org/mailman/listinfo/dhcwg", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dhcwg/", "type": "wg", "name": "Dynamic Host Configuration"}}, {"pk": 989, "model": "group.group", "fields": {"charter": "charter-ietf-edi", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-edi@byu.edu", "acronym": "edi", "comments": "1st IETF Meeting: Seattle: 94-03: BOF", "list_subscribe": "listserv@byu.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.sterling.com/edi/lists/ietf-edi", "type": "wg", "name": "Electronic Data Interchange"}}, {"pk": 990, "model": "group.group", "fields": {"charter": "charter-ietf-ediint", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-ediint@imc.org", "acronym": "ediint", "comments": "1st meeting at 36th IETF - Montreal, Canada", "list_subscribe": "ietf-ediint-request@imc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.imc.org/ietf-ediint/", "type": "wg", "name": "Electronic Data Interchange-Internet Integration"}}, {"pk": 991, "model": "group.group", "fields": {"charter": "charter-ietf-mailreq", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "mailreq", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Email Requirements"}}, -{"pk": 992, "model": "group.group", "fields": {"charter": "charter-ietf-eii", "unused_states": [], "ad": 2324, "parent": 1193, "list_email": "", "acronym": "eii", "comments": "1st meeting San Jose, December 5-9, 1994 mw CANCELLED", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Emergency Information Infrastructure"}}, -{"pk": 993, "model": "group.group", "fields": {"charter": "charter-ietf-eid", "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "eid", "comments": "1st meeting Toronto IETF. mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Endpoint Identifier"}}, +{"pk": 992, "model": "group.group", "fields": {"charter": "charter-ietf-eii", "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "eii", "comments": "1st meeting San Jose, December 5-9, 1994 mw CANCELLED", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Emergency Information Infrastructure"}}, +{"pk": 993, "model": "group.group", "fields": {"charter": "charter-ietf-eid", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "eid", "comments": "1st meeting Toronto IETF. mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Endpoint Identifier"}}, {"pk": 994, "model": "group.group", "fields": {"charter": "charter-ietf-entmib", "unused_states": [], "ad": null, "parent": 1193, "list_email": "entmib@ietf.org", "acronym": "entmib", "comments": "1st session 33rd IETF, Stockholm 17-21 July mw", "list_subscribe": "http://www.ietf.org/mailman/listinfo/entmib", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/entmib/", "type": "wg", "name": "Entity MIB"}}, -{"pk": 995, "model": "group.group", "fields": {"charter": "charter-ietf-opera", "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "opera", "comments": "1st IETF Meeting: Seattle: 94-03: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Establishing a Forum for Operational Issues"}}, -{"pk": 996, "model": "group.group", "fields": {"charter": "charter-ietf-ethermib", "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "enet_mib@ftp.com", "acronym": "ethermib", "comments": "to resolve the ethernet controversy....", "list_subscribe": "enet_mib-request@ftp.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Ethernet MIB"}}, -{"pk": 997, "model": "group.group", "fields": {"charter": "charter-ietf-earthen", "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "earthen", "comments": "1st meeting at 35th IETF - Los Angeles, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Explorations of Alternate Routing & Topology to He"}}, +{"pk": 995, "model": "group.group", "fields": {"charter": "charter-ietf-opera", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "opera", "comments": "1st IETF Meeting: Seattle: 94-03: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Establishing a Forum for Operational Issues"}}, +{"pk": 996, "model": "group.group", "fields": {"charter": "charter-ietf-ethermib", "unused_states": [], "ad": null, "parent": 1157, "list_email": "enet_mib@ftp.com", "acronym": "ethermib", "comments": "to resolve the ethernet controversy....", "list_subscribe": "enet_mib-request@ftp.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Ethernet MIB"}}, +{"pk": 997, "model": "group.group", "fields": {"charter": "charter-ietf-earthen", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "earthen", "comments": "1st meeting at 35th IETF - Los Angeles, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Explorations of Alternate Routing & Topology to He"}}, {"pk": 998, "model": "group.group", "fields": {"charter": "charter-ietf-ftpext", "unused_states": [], "ad": null, "parent": 934, "list_email": "ftpext@ietf.org", "acronym": "ftpext", "comments": "Was a San Diego BOF", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ftpext", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ftpext/", "type": "wg", "name": "Extensions to FTP"}}, {"pk": 999, "model": "group.group", "fields": {"charter": "charter-ietf-osiextnd", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "osiextnd", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Extensions to OSI for use in the Internet"}}, -{"pk": 1000, "model": "group.group", "fields": {"charter": "charter-ietf-fddimib", "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "fddi-mib@CS.UTK.EDU", "acronym": "fddimib", "comments": "This working group is newly revived to work on the draft FDDI MIB. Concluded the first time on 8/1/91.", "list_subscribe": "fddi-mib-request@CS.UTK.EDU", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "FDDI MIB"}}, -{"pk": 1001, "model": "group.group", "fields": {"charter": "charter-ietf-wg2", "unused_states": [], "ad": 188, "parent": 1179, "list_email": "", "acronym": "wg2", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "File Transfer, Access and Management"}}, +{"pk": 1000, "model": "group.group", "fields": {"charter": "charter-ietf-fddimib", "unused_states": [], "ad": null, "parent": 1157, "list_email": "fddi-mib@CS.UTK.EDU", "acronym": "fddimib", "comments": "This working group is newly revived to work on the draft FDDI MIB. Concluded the first time on 8/1/91.", "list_subscribe": "fddi-mib-request@CS.UTK.EDU", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "FDDI MIB"}}, +{"pk": 1001, "model": "group.group", "fields": {"charter": "charter-ietf-wg2", "unused_states": [], "ad": null, "parent": 1179, "list_email": "", "acronym": "wg2", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "File Transfer, Access and Management"}}, {"pk": 1002, "model": "group.group", "fields": {"charter": "charter-ietf-frnetmib", "unused_states": [], "ad": null, "parent": 1052, "list_email": "frnetmib@sunroof.eng.sun.com", "acronym": "frnetmib", "comments": "Orig. conclude date: 3/18/94. reactivated 4/19/96", "list_subscribe": "majordomo@sunroof.eng.sun.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.ietf.org/ietf-mail-archive/frnetmib/", "type": "wg", "name": "Frame Relay Service MIB"}}, {"pk": 1003, "model": "group.group", "fields": {"charter": "charter-ietf-pages", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "pages", "comments": "1st IETF Meeting: Seattle: 94-03: BOF eventually became whip WG", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Framework for White Pages Service in the Internet"}}, {"pk": 1004, "model": "group.group", "fields": {"charter": "charter-ietf-ftpftam", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "ftpftam", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "FTP-FTAM Gateway"}}, -{"pk": 1005, "model": "group.group", "fields": {"charter": "charter-ietf-wg5", "unused_states": [], "ad": 188, "parent": 1179, "list_email": "", "acronym": "wg5", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Full Screen Services"}}, +{"pk": 1005, "model": "group.group", "fields": {"charter": "charter-ietf-wg5", "unused_states": [], "ad": null, "parent": 1179, "list_email": "", "acronym": "wg5", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Full Screen Services"}}, {"pk": 1006, "model": "group.group", "fields": {"charter": "charter-ietf-fddifs", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "fddifs", "comments": "1st meeting at 38th IETF - Memphis, TN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Future Directions for Differential Services"}}, {"pk": 1007, "model": "group.group", "fields": {"charter": "charter-ietf-grip", "unused_states": [], "ad": null, "parent": 1193, "list_email": "grip-wg@uu.net", "acronym": "grip", "comments": "1st meeting Toronto IETF 7/94. mw The 'G and R' stand for 'Guidelines and Recommendations'", "list_subscribe": "grip-wg-request@uu.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www-ext.eng.uu.net/grip-wg/grip-wg.txt", "type": "wg", "name": "G & R for Security Incident Processing"}}, -{"pk": 1009, "model": "group.group", "fields": {"charter": "charter-ietf-gisd", "unused_states": [], "ad": 2324, "parent": null, "list_email": "gisd-wg@ripe.net", "acronym": "gisd", "comments": "Bof in Amsterdam (Jul 93). Acronym WAS giss (Generic Internet Svs. Spec.) David replaced Daniel Karrenberg & Tony Bates 6/94 mw", "list_subscribe": "majordomo@ripe.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.ripe.net/ripe/archives/gisd-wg/current", "type": "wg", "name": "Generic Internet Service Description"}}, -{"pk": 1010, "model": "group.group", "fields": {"charter": "charter-ietf-gopher", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "", "acronym": "gopher", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "GOPHER"}}, -{"pk": 1011, "model": "group.group", "fields": {"charter": "charter-ietf-stdguide", "unused_states": [], "ad": 2853, "parent": 1179, "list_email": "stdguide@midnight.com", "acronym": "stdguide", "comments": "Developed from prottest bof which met in Danvers. mw", "list_subscribe": "majordomo@midnight.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.midnight.com/pub/stdguide-archive", "type": "wg", "name": "Guide for Internet Standards Writers"}}, +{"pk": 1009, "model": "group.group", "fields": {"charter": "charter-ietf-gisd", "unused_states": [], "ad": null, "parent": null, "list_email": "gisd-wg@ripe.net", "acronym": "gisd", "comments": "Bof in Amsterdam (Jul 93). Acronym WAS giss (Generic Internet Svs. Spec.) David replaced Daniel Karrenberg & Tony Bates 6/94 mw", "list_subscribe": "majordomo@ripe.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.ripe.net/ripe/archives/gisd-wg/current", "type": "wg", "name": "Generic Internet Service Description"}}, +{"pk": 1010, "model": "group.group", "fields": {"charter": "charter-ietf-gopher", "unused_states": [], "ad": null, "parent": 1346, "list_email": "", "acronym": "gopher", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "GOPHER"}}, +{"pk": 1011, "model": "group.group", "fields": {"charter": "charter-ietf-stdguide", "unused_states": [], "ad": null, "parent": 1179, "list_email": "stdguide@midnight.com", "acronym": "stdguide", "comments": "Developed from prottest bof which met in Danvers. mw", "list_subscribe": "majordomo@midnight.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.midnight.com/pub/stdguide-archive", "type": "wg", "name": "Guide for Internet Standards Writers"}}, {"pk": 1012, "model": "group.group", "fields": {"charter": "charter-ietf-guts", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "guts", "comments": "1st meeting at 35th IETF - Los Angeles, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Guidelines for UDP and TCP Based Systems"}}, -{"pk": 1013, "model": "group.group", "fields": {"charter": "charter-ietf-peering", "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "peering", "comments": "Scheduled on-site 31st IETF/San Jose (December 5-9, 1994) mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "High Speed 34 Megabit Atlantic Peering"}}, +{"pk": 1013, "model": "group.group", "fields": {"charter": "charter-ietf-peering", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "peering", "comments": "Scheduled on-site 31st IETF/San Jose (December 5-9, 1994) mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "High Speed 34 Megabit Atlantic Peering"}}, {"pk": 1014, "model": "group.group", "fields": {"charter": "charter-ietf-hops", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "hops", "comments": "1st meeting at 38th IETF - Memphis, TN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Host Proximity Service"}}, {"pk": 1015, "model": "group.group", "fields": {"charter": "charter-ietf-hostreq", "unused_states": [], "ad": null, "parent": null, "list_email": "ietf-hosts@NNSC.NSF.NET", "acronym": "hostreq", "comments": "", "list_subscribe": "ietf-hosts-request@NNSC.NSF.NET", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Host Requirements"}}, -{"pk": 1016, "model": "group.group", "fields": {"charter": "charter-ietf-hostmib", "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "hostmib@andrew.cmu.edu", "acronym": "hostmib", "comments": "", "list_subscribe": "hostmib-request@andrew.cmu.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Host Resources MIB"}}, +{"pk": 1016, "model": "group.group", "fields": {"charter": "charter-ietf-hostmib", "unused_states": [], "ad": null, "parent": 1157, "list_email": "hostmib@andrew.cmu.edu", "acronym": "hostmib", "comments": "", "list_subscribe": "hostmib-request@andrew.cmu.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Host Resources MIB"}}, {"pk": 1017, "model": "group.group", "fields": {"charter": "charter-ietf-httpsec", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "httpsec", "comments": "Scheduled on-site at 31st IETF/San Jose (December 5-9, 1994) mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "HTTP Secure"}}, -{"pk": 1018, "model": "group.group", "fields": {"charter": "charter-ietf-harts", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "harts@isi.edu", "acronym": "harts", "comments": "This group was formed from the arts bof mw. A fake conclude msg sent 8/1. When last ID published, will conclude record.", "list_subscribe": "harts-request@isi.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://nfs/ftp/harts/harts.mail", "type": "wg", "name": "Humanities and Arts"}}, +{"pk": 1018, "model": "group.group", "fields": {"charter": "charter-ietf-harts", "unused_states": [], "ad": null, "parent": 1346, "list_email": "harts@isi.edu", "acronym": "harts", "comments": "This group was formed from the arts bof mw. A fake conclude msg sent 8/1. When last ID published, will conclude record.", "list_subscribe": "harts-request@isi.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://nfs/ftp/harts/harts.mail", "type": "wg", "name": "Humanities and Arts"}}, {"pk": 1019, "model": "group.group", "fields": {"charter": "charter-ietf-html", "unused_states": [], "ad": null, "parent": 934, "list_email": "www-html@w3.org", "acronym": "html", "comments": "", "list_subscribe": "www-html-request@w3.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ics.uci.edu/pub/ietf/html/", "type": "wg", "name": "HyperText Markup Language"}}, {"pk": 1020, "model": "group.group", "fields": {"charter": "charter-ietf-http", "unused_states": [], "ad": null, "parent": 934, "list_email": "http-wg@hplb.hp.com", "acronym": "http", "comments": "", "list_subscribe": "http-wg-request@hplb.hp.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ics.uci.edu/pub/ietf/http/hypermail", "type": "wg", "name": "HyperText Transfer Protocol"}}, -{"pk": 1021, "model": "group.group", "fields": {"charter": "charter-ietf-httpmib", "unused_states": [], "ad": 4763, "parent": null, "list_email": "", "acronym": "httpmib", "comments": "First meeting held at 35th IETF in Los Angeles, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "HyperText Transfer Protocol MIB"}}, -{"pk": 1022, "model": "group.group", "fields": {"charter": "charter-ietf-hubmib", "unused_states": [], "ad": 6699, "parent": 1193, "list_email": "hubmib@ietf.org", "acronym": "hubmib", "comments": "Orig. Start: 7/1/91; End: 9/10/93. Restarted. mw", "list_subscribe": "hubmib-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/hubmib/", "type": "wg", "name": "Ethernet Interfaces and Hub MIB"}}, -{"pk": 1023, "model": "group.group", "fields": {"charter": "charter-ietf-ietfgrow", "unused_states": [], "ad": 188, "parent": 1179, "list_email": "", "acronym": "ietfgrow", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IETF Growth"}}, -{"pk": 1024, "model": "group.group", "fields": {"charter": "charter-ietf-dnsevolv", "unused_states": [], "ad": 188, "parent": null, "list_email": "", "acronym": "dnsevolv", "comments": "1st met as BOF at 34th IETF, Dallas 12/4-8 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IETF Role in DNS Evolution"}}, -{"pk": 1026, "model": "group.group", "fields": {"charter": "charter-ietf-emailmgt", "unused_states": [], "ad": 4763, "parent": null, "list_email": "", "acronym": "emailmgt", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IFIP Electronic Mail Management"}}, -{"pk": 1027, "model": "group.group", "fields": {"charter": "charter-ietf-none", "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "none", "comments": "This is here so that 'none' can be entered in, for example, idform.", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "individ", "name": "Individual Submissions"}}, -{"pk": 1028, "model": "group.group", "fields": {"charter": "charter-ietf-wg-isus", "unused_states": [], "ad": 188, "parent": 1179, "list_email": "", "acronym": "wg-isus", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Informational Services and User Support"}}, -{"pk": 1029, "model": "group.group", "fields": {"charter": "charter-ietf-check", "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "check", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Installation Checklist"}}, +{"pk": 1021, "model": "group.group", "fields": {"charter": "charter-ietf-httpmib", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "httpmib", "comments": "First meeting held at 35th IETF in Los Angeles, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "HyperText Transfer Protocol MIB"}}, +{"pk": 1022, "model": "group.group", "fields": {"charter": "charter-ietf-hubmib", "unused_states": [], "ad": null, "parent": 1193, "list_email": "hubmib@ietf.org", "acronym": "hubmib", "comments": "Orig. Start: 7/1/91; End: 9/10/93. Restarted. mw", "list_subscribe": "hubmib-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/hubmib/", "type": "wg", "name": "Ethernet Interfaces and Hub MIB"}}, +{"pk": 1023, "model": "group.group", "fields": {"charter": "charter-ietf-ietfgrow", "unused_states": [], "ad": null, "parent": 1179, "list_email": "", "acronym": "ietfgrow", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IETF Growth"}}, +{"pk": 1024, "model": "group.group", "fields": {"charter": "charter-ietf-dnsevolv", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "dnsevolv", "comments": "1st met as BOF at 34th IETF, Dallas 12/4-8 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IETF Role in DNS Evolution"}}, +{"pk": 1026, "model": "group.group", "fields": {"charter": "charter-ietf-emailmgt", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "emailmgt", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IFIP Electronic Mail Management"}}, +{"pk": 1027, "model": "group.group", "fields": {"charter": "charter-ietf-none", "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "none", "comments": "This is here so that 'none' can be entered in, for example, idform.", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "individ", "name": "Individual Submissions"}}, +{"pk": 1028, "model": "group.group", "fields": {"charter": "charter-ietf-wg-isus", "unused_states": [], "ad": null, "parent": 1179, "list_email": "", "acronym": "wg-isus", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Informational Services and User Support"}}, +{"pk": 1029, "model": "group.group", "fields": {"charter": "charter-ietf-check", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "check", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Installation Checklist"}}, {"pk": 1030, "model": "group.group", "fields": {"charter": "charter-ietf-ids", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-ids@umich.edu", "acronym": "ids", "comments": "Changed from USV to APPs on 4/12/95.", "list_subscribe": "ietf-ids-request@umich.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://terminator.rs.itd.umich.edu/ietf-ids/archive", "type": "wg", "name": "Integrated Directory Services"}}, {"pk": 1031, "model": "group.group", "fields": {"charter": "charter-ietf-iia", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "iia", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Integrated Information Architecture"}}, {"pk": 1032, "model": "group.group", "fields": {"charter": "charter-ietf-ipnni", "unused_states": [], "ad": null, "parent": 1249, "list_email": "", "acronym": "ipnni", "comments": "1st meeting at 35th IETF - Los Angeles, CA - March 1996", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Integrated PNNI"}}, {"pk": 1033, "model": "group.group", "fields": {"charter": "charter-ietf-intserv", "unused_states": [], "ad": null, "parent": 1324, "list_email": "int-serv@isi.edu", "acronym": "intserv", "comments": "1st IETF Meeting: Seattle: 94-03: BOF.", "list_subscribe": "int-serv-request@isi.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.isi.edu/int-serv/int-serv.mail", "type": "wg", "name": "Integrated Services"}}, {"pk": 1034, "model": "group.group", "fields": {"charter": "charter-ietf-isfoo", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "isfoo", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Integrated Services over Foo"}}, {"pk": 1035, "model": "group.group", "fields": {"charter": "charter-ietf-issll", "unused_states": [], "ad": null, "parent": 1324, "list_email": "issll@mercury.lcs.mit.edu", "acronym": "issll", "comments": "", "list_subscribe": "issll-request@mercury.lcs.mit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://mercury.lcs.mit.edu/pub/issll/mail/", "type": "wg", "name": "Integrated Services over Specific Link Layers"}}, -{"pk": 1037, "model": "group.group", "fields": {"charter": "charter-ietf-iiir", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "iiir@merit.edu", "acronym": "iiir", "comments": "Charter updated 1/29/93", "list_subscribe": "iiir-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://merit.edu/pub/iiir-archive", "type": "wg", "name": "Integration of Internet Information Resources"}}, -{"pk": 1038, "model": "group.group", "fields": {"charter": "charter-ietf-intprop", "unused_states": [], "ad": 188, "parent": 1179, "list_email": "intprop-wg@lm.com", "acronym": "intprop", "comments": "1st meeting San Jose, 31st IETF December 5-9, 1994 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Intellectual Property of the IETF"}}, +{"pk": 1037, "model": "group.group", "fields": {"charter": "charter-ietf-iiir", "unused_states": [], "ad": null, "parent": 1346, "list_email": "iiir@merit.edu", "acronym": "iiir", "comments": "Charter updated 1/29/93", "list_subscribe": "iiir-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://merit.edu/pub/iiir-archive", "type": "wg", "name": "Integration of Internet Information Resources"}}, +{"pk": 1038, "model": "group.group", "fields": {"charter": "charter-ietf-intprop", "unused_states": [], "ad": null, "parent": 1179, "list_email": "intprop-wg@lm.com", "acronym": "intprop", "comments": "1st meeting San Jose, 31st IETF December 5-9, 1994 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Intellectual Property of the IETF"}}, {"pk": 1039, "model": "group.group", "fields": {"charter": "charter-ietf-idmr", "unused_states": [], "ad": null, "parent": 1249, "list_email": "idmr@cs.ucl.ac.uk", "acronym": "idmr", "comments": "Paul resigned just prior to 31st IETF. 12/5/94 mw", "list_subscribe": "idmr-request@cs.ucl.ac.uk", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.ietf.org/ietf-mail-archive/idmr/", "type": "wg", "name": "Inter-Domain Multicast Routing"}}, {"pk": 1040, "model": "group.group", "fields": {"charter": "charter-ietf-idpr", "unused_states": [], "ad": null, "parent": 1249, "list_email": "idpr-wg@bbn.com", "acronym": "idpr", "comments": "", "list_subscribe": "idpr-wg-request@bbn.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Inter-Domain Policy Routing"}}, -{"pk": 1041, "model": "group.group", "fields": {"charter": "charter-ietf-idr", "unused_states": [], "ad": 2329, "parent": 1249, "list_email": "idr@ietf.org", "acronym": "idr", "comments": "This working group resulted from BGP and IPIDRP merging.", "list_subscribe": "idr-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/idr/", "type": "wg", "name": "Inter-Domain Routing"}}, -{"pk": 1042, "model": "group.group", "fields": {"charter": "charter-ietf-imm", "unused_states": [], "ad": 188, "parent": 1324, "list_email": "", "acronym": "imm", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Interactive Multimedia"}}, +{"pk": 1041, "model": "group.group", "fields": {"charter": "charter-ietf-idr", "unused_states": [], "ad": null, "parent": 1249, "list_email": "idr@ietf.org", "acronym": "idr", "comments": "This working group resulted from BGP and IPIDRP merging.", "list_subscribe": "idr-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/idr/", "type": "wg", "name": "Inter-Domain Routing"}}, +{"pk": 1042, "model": "group.group", "fields": {"charter": "charter-ietf-imm", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "imm", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Interactive Multimedia"}}, {"pk": 1043, "model": "group.group", "fields": {"charter": "charter-ietf-iwg", "unused_states": [], "ad": null, "parent": 1249, "list_email": "", "acronym": "iwg", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Interconnectivity Working Group"}}, {"pk": 1044, "model": "group.group", "fields": {"charter": "charter-ietf-ifmib", "unused_states": [], "ad": null, "parent": 1052, "list_email": "ifmib@ietf.org", "acronym": "ifmib", "comments": "Orig. Start: 5/13/93; End: 12/29/94. Restarted to elevate RFC to next status level.", "list_subscribe": "http://www.ietf.org/mailman/listinfo/ifmib", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://thumper.bellcore.com/pub/Group.archive/if-mib", "type": "wg", "name": "Interfaces MIB"}}, -{"pk": 1045, "model": "group.group", "fields": {"charter": "charter-ietf-iahc", "unused_states": [], "ad": 2853, "parent": 1179, "list_email": "", "acronym": "iahc", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "International Ad Hoc Committee"}}, -{"pk": 1046, "model": "group.group", "fields": {"charter": "charter-ietf-inaparch", "unused_states": [], "ad": 188, "parent": 1179, "list_email": "", "acronym": "inaparch", "comments": "1st meeting 31st IETF San Jose: December 1994 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "International Networking and the NAP Architecture"}}, -{"pk": 1047, "model": "group.group", "fields": {"charter": "charter-ietf-acct", "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "accounting-wg@wugate.wustl.edu", "acronym": "acct", "comments": "", "list_subscribe": "accounting-wg-request@wugate.wustl.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet Accounting"}}, -{"pk": 1048, "model": "group.group", "fields": {"charter": "charter-ietf-acct2", "unused_states": [], "ad": 2324, "parent": null, "list_email": "accounting-wg@wugate.wustl.edu", "acronym": "acct2", "comments": "1st met as BOF Seattle IETF, March 1994 mw", "list_subscribe": "accounting-wg-request@wugate.wustl.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet Accounting 2"}}, -{"pk": 1049, "model": "group.group", "fields": {"charter": "charter-ietf-ioh", "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "ioh", "comments": "1st met as BOF, 33rd IETF Stockholm 17-21 July 1995", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet and OSI Harmonisation"}}, -{"pk": 1050, "model": "group.group", "fields": {"charter": "charter-ietf-iafa", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "iafa@cc.mcgill.ca", "acronym": "iafa", "comments": "", "list_subscribe": "iafa-request@cc.mcgill.ca", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "archive.cc.mcgill.ca:~/pub/mailing-lists/iafa-archive", "type": "wg", "name": "Internet Anonymous FTP Archives"}}, +{"pk": 1045, "model": "group.group", "fields": {"charter": "charter-ietf-iahc", "unused_states": [], "ad": null, "parent": 1179, "list_email": "", "acronym": "iahc", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "International Ad Hoc Committee"}}, +{"pk": 1046, "model": "group.group", "fields": {"charter": "charter-ietf-inaparch", "unused_states": [], "ad": null, "parent": 1179, "list_email": "", "acronym": "inaparch", "comments": "1st meeting 31st IETF San Jose: December 1994 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "International Networking and the NAP Architecture"}}, +{"pk": 1047, "model": "group.group", "fields": {"charter": "charter-ietf-acct", "unused_states": [], "ad": null, "parent": 1157, "list_email": "accounting-wg@wugate.wustl.edu", "acronym": "acct", "comments": "", "list_subscribe": "accounting-wg-request@wugate.wustl.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet Accounting"}}, +{"pk": 1048, "model": "group.group", "fields": {"charter": "charter-ietf-acct2", "unused_states": [], "ad": null, "parent": null, "list_email": "accounting-wg@wugate.wustl.edu", "acronym": "acct2", "comments": "1st met as BOF Seattle IETF, March 1994 mw", "list_subscribe": "accounting-wg-request@wugate.wustl.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet Accounting 2"}}, +{"pk": 1049, "model": "group.group", "fields": {"charter": "charter-ietf-ioh", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ioh", "comments": "1st met as BOF, 33rd IETF Stockholm 17-21 July 1995", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet and OSI Harmonisation"}}, +{"pk": 1050, "model": "group.group", "fields": {"charter": "charter-ietf-iafa", "unused_states": [], "ad": null, "parent": 1346, "list_email": "iafa@cc.mcgill.ca", "acronym": "iafa", "comments": "", "list_subscribe": "iafa-request@cc.mcgill.ca", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "archive.cc.mcgill.ca:~/pub/mailing-lists/iafa-archive", "type": "wg", "name": "Internet Anonymous FTP Archives"}}, {"pk": 1053, "model": "group.group", "fields": {"charter": "charter-ietf-icp", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "icp", "comments": "1st meeting at 37th IETF - San Jose", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet Cache Protocol"}}, {"pk": 1054, "model": "group.group", "fields": {"charter": "charter-ietf-fax", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-fax@imc.org", "acronym": "fax", "comments": "1st meeting at 37th IETF - San Jose, CA", "list_subscribe": "ietf-fax-request@imc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.imc.org/ietf-fax/", "type": "wg", "name": "Internet Fax"}}, {"pk": 1055, "model": "group.group", "fields": {"charter": "charter-ietf-smtpext", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-smtp@list.cren.net", "acronym": "smtpext", "comments": "Chaired by G. Vaudreuil until 11/18/91", "list_subscribe": "listproc@list.cren.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://list.cren.net:/archives/ietf-smtp/*", "type": "wg", "name": "Internet Mail Extensions"}}, {"pk": 1056, "model": "group.group", "fields": {"charter": "charter-ietf-imp", "unused_states": [], "ad": null, "parent": 934, "list_email": "imp-interest@thumper.bellcore.com", "acronym": "imp", "comments": "", "list_subscribe": "imp-interest-request@thumper.bellcore.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "thumper.bellcore.com:pub/devetzis/imp/imp-archive", "type": "wg", "name": "Internet Mercantile Protocols"}}, {"pk": 1057, "model": "group.group", "fields": {"charter": "charter-ietf-imap", "unused_states": [], "ad": null, "parent": 934, "list_email": "imap@cac.washington.edu", "acronym": "imap", "comments": "Originally met as Interactive Mail Access Protocol BOF. 93-07. Name changed 11/5/93 with Area Director approval. mw", "list_subscribe": "imap-request@cac.washington.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp.cac.washington.edu:~/imap/imap_archive", "type": "wg", "name": "Internet Message Access Protocol"}}, {"pk": 1058, "model": "group.group", "fields": {"charter": "charter-ietf-822ext", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-822@dimacs.rutgers.edu", "acronym": "822ext", "comments": "", "list_subscribe": "ietf-822-request@dimacs.rutgers.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ietf.cnri.reston.va.us:~/ietf-mail-archive/822ext/*", "type": "wg", "name": "Internet Message Extensions"}}, -{"pk": 1059, "model": "group.group", "fields": {"charter": "charter-ietf-mib", "unused_states": [], "ad": 4763, "parent": 934, "list_email": "mib-wg@nnsc.nsf.net", "acronym": "mib", "comments": "", "list_subscribe": "mib-wg-request@nnsc.nsf.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet MIB"}}, -{"pk": 1060, "model": "group.group", "fields": {"charter": "charter-ietf-ima", "unused_states": [], "ad": 188, "parent": null, "list_email": "", "acronym": "ima", "comments": "1st meeting Toronto IETF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet Middleware"}}, +{"pk": 1059, "model": "group.group", "fields": {"charter": "charter-ietf-mib", "unused_states": [], "ad": null, "parent": 934, "list_email": "mib-wg@nnsc.nsf.net", "acronym": "mib", "comments": "", "list_subscribe": "mib-wg-request@nnsc.nsf.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet MIB"}}, +{"pk": 1060, "model": "group.group", "fields": {"charter": "charter-ietf-ima", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ima", "comments": "1st meeting Toronto IETF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet Middleware"}}, {"pk": 1061, "model": "group.group", "fields": {"charter": "charter-ietf-rap", "unused_states": [], "ad": null, "parent": 1193, "list_email": "rap@ops.ietf.org", "acronym": "rap", "comments": "1st Meeting at 37th IETF - San Jose, CA\r\nChanged from TSV to OPS on 11/23/99.", "list_subscribe": "rap-request@ops.ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "https://ops.ietf.org/lists/rap", "type": "wg", "name": "Resource Allocation Protocol"}}, {"pk": 1062, "model": "group.group", "fields": {"charter": "charter-ietf-ipp", "unused_states": [], "ad": null, "parent": 934, "list_email": "ipp@pwg.org", "acronym": "ipp", "comments": "", "list_subscribe": "ipp-request@pwg.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.pwg.org/pub/pwg/ipp/", "type": "wg", "name": "Internet Printing Protocol"}}, -{"pk": 1063, "model": "group.group", "fields": {"charter": "charter-ietf-ire", "unused_states": [], "ad": 2324, "parent": null, "list_email": "ire@apnic.net", "acronym": "ire", "comments": "1st meeting at 36th IETF - Montreal, Canada", "list_subscribe": "ire-request@apnic.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.apnic.net/mailing-lists/ire", "type": "wg", "name": "Internet Registry Evolution"}}, -{"pk": 1064, "model": "group.group", "fields": {"charter": "charter-ietf-isn", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "isn-wg@nasa.gov", "acronym": "isn", "comments": "", "list_subscribe": "listmanager@nasa.gov", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet School Networking"}}, -{"pk": 1065, "model": "group.group", "fields": {"charter": "charter-ietf-isn2", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "isn-wg@unmvma.unm.edu", "acronym": "isn2", "comments": "1st meeting 32nd IETF, Danvers, MA April 3-7, 1995, primarily for local teachers to attend. 3/17/95 mw", "list_subscribe": "listserv@unmvma.unm.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet School Networking 2"}}, +{"pk": 1063, "model": "group.group", "fields": {"charter": "charter-ietf-ire", "unused_states": [], "ad": null, "parent": null, "list_email": "ire@apnic.net", "acronym": "ire", "comments": "1st meeting at 36th IETF - Montreal, Canada", "list_subscribe": "ire-request@apnic.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.apnic.net/mailing-lists/ire", "type": "wg", "name": "Internet Registry Evolution"}}, +{"pk": 1064, "model": "group.group", "fields": {"charter": "charter-ietf-isn", "unused_states": [], "ad": null, "parent": 1346, "list_email": "isn-wg@nasa.gov", "acronym": "isn", "comments": "", "list_subscribe": "listmanager@nasa.gov", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet School Networking"}}, +{"pk": 1065, "model": "group.group", "fields": {"charter": "charter-ietf-isn2", "unused_states": [], "ad": null, "parent": 1346, "list_email": "isn-wg@unmvma.unm.edu", "acronym": "isn2", "comments": "1st meeting 32nd IETF, Danvers, MA April 3-7, 1995, primarily for local teachers to attend. 3/17/95 mw", "list_subscribe": "listserv@unmvma.unm.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet School Networking 2"}}, {"pk": 1066, "model": "group.group", "fields": {"charter": "charter-ietf-ispp", "unused_states": [], "ad": null, "parent": 1260, "list_email": "ietf-payments@cc.bellcore.com", "acronym": "ispp", "comments": "1st BOF meeting 33rd IETF/Stockholm 17-21 July 1995 mw", "list_subscribe": "majordomo@cc.bellcore.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.bellcore.com/pub/rubin/", "type": "wg", "name": "Internet Secure Payments Protocol"}}, {"pk": 1067, "model": "group.group", "fields": {"charter": "charter-ietf-spwg", "unused_states": [], "ad": null, "parent": 1260, "list_email": "spwg@nri.reston.va.us", "acronym": "spwg", "comments": "", "list_subscribe": "spwg-request@nri.reston.va.us", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet Security Policy"}}, -{"pk": 1068, "model": "group.group", "fields": {"charter": "charter-ietf-isoc", "unused_states": [], "ad": 188, "parent": null, "list_email": "", "acronym": "isoc", "comments": "Mike Roberts led an isoc bof at the 28th IETF in Houston, November 1-5, 1993 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet Society Advisory Council"}}, +{"pk": 1068, "model": "group.group", "fields": {"charter": "charter-ietf-isoc", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "isoc", "comments": "Mike Roberts led an isoc bof at the 28th IETF in Houston, November 1-5, 1993 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet Society Advisory Council"}}, {"pk": 1069, "model": "group.group", "fields": {"charter": "charter-ietf-st2", "unused_states": [], "ad": null, "parent": 1052, "list_email": "st@bbn.com", "acronym": "st2", "comments": "Lou Berger replaces Steve DeJarnett 6/28/94 mw", "list_subscribe": "st-request@bbn.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.bbn.com/pub/st/st-archive", "type": "wg", "name": "Internet Stream Protocol V2"}}, -{"pk": 1070, "model": "group.group", "fields": {"charter": "charter-ietf-userglos", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "usergloss@xylogics.com", "acronym": "userglos", "comments": "Orig. Start: 12/02/90; End: 1/12/93. Restarted to elevate RFC to next status level. Meet at 33rd IETF in Stockholm.", "list_subscribe": "usergloss-request@xylogics.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://xylogics.com/pub/users/gmalkin/usergloss/usergloss-arc", "type": "wg", "name": "Internet User Glossary"}}, -{"pk": 1071, "model": "group.group", "fields": {"charter": "charter-ietf-iup", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "ietf@venera.isi.edu", "acronym": "iup", "comments": "", "list_subscribe": "ietf-request@venera.isi.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet User Population"}}, +{"pk": 1070, "model": "group.group", "fields": {"charter": "charter-ietf-userglos", "unused_states": [], "ad": null, "parent": 1346, "list_email": "usergloss@xylogics.com", "acronym": "userglos", "comments": "Orig. Start: 12/02/90; End: 1/12/93. Restarted to elevate RFC to next status level. Meet at 33rd IETF in Stockholm.", "list_subscribe": "usergloss-request@xylogics.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://xylogics.com/pub/users/gmalkin/usergloss/usergloss-arc", "type": "wg", "name": "Internet User Glossary"}}, +{"pk": 1071, "model": "group.group", "fields": {"charter": "charter-ietf-iup", "unused_states": [], "ad": null, "parent": 1346, "list_email": "ietf@venera.isi.edu", "acronym": "iup", "comments": "", "list_subscribe": "ietf-request@venera.isi.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet User Population"}}, {"pk": 1072, "model": "group.group", "fields": {"charter": "charter-ietf-whip", "unused_states": [], "ad": null, "parent": 934, "list_email": "wps@SURFnet.nl", "acronym": "whip", "comments": "Working group formed as result of pages BOF from Seattle in March 1994.", "list_subscribe": "wps-request@SURFnet.nl", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.es.net/pub/ietf/wps", "type": "wg", "name": "Internet White Pages Requirements"}}, {"pk": 1073, "model": "group.group", "fields": {"charter": "charter-ietf-ion", "unused_states": [], "ad": null, "parent": 1052, "list_email": "ion@sunroof.eng.sun.com", "acronym": "ion", "comments": "", "list_subscribe": "majordomo@sunroof.eng.sun.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.ietf.org/ietf-mail-archive/ion", "type": "wg", "name": "Internetworking Over NBMA"}}, {"pk": 1074, "model": "group.group", "fields": {"charter": "charter-ietf-ipae", "unused_states": [], "ad": null, "parent": 1052, "list_email": "ip-encaps@sunroof.eng.sun.com", "acronym": "ipae", "comments": "", "list_subscribe": "ip-encaps-request@sunroof.eng.sun.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "parcftp.xerox.com:~/pub/ip-encaps/", "type": "wg", "name": "IP Address Encapsulation"}}, -{"pk": 1075, "model": "group.group", "fields": {"charter": "charter-ietf-ipaddr", "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "ipaddr", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IP Addressing Plan"}}, +{"pk": 1075, "model": "group.group", "fields": {"charter": "charter-ietf-ipaddr", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ipaddr", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IP Addressing Plan"}}, {"pk": 1076, "model": "group.group", "fields": {"charter": "charter-ietf-ipacad", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ipacad", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IP Applications Over Cable Data Network"}}, {"pk": 1077, "model": "group.group", "fields": {"charter": "charter-ietf-ipauth", "unused_states": [], "ad": null, "parent": 1260, "list_email": "awg@bitsy.mit.edu", "acronym": "ipauth", "comments": "This WG has died an unnatural death.", "list_subscribe": "awg-request@bitsy.mit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IP Authentication"}}, {"pk": 1078, "model": "group.group", "fields": {"charter": "charter-ietf-mtudisc", "unused_states": [], "ad": null, "parent": 1052, "list_email": "mtudwg@decwrl.dec.com", "acronym": "mtudisc", "comments": "", "list_subscribe": "mtudwg-request@decwrl.dec.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IP MTU Discovery"}}, {"pk": 1079, "model": "group.group", "fields": {"charter": "charter-ietf-appleip", "unused_states": [], "ad": null, "parent": 1052, "list_email": "apple-ip@apple.com", "acronym": "appleip", "comments": "", "list_subscribe": "apple-ip-request@apple.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IP Over AppleTalk"}}, {"pk": 1080, "model": "group.group", "fields": {"charter": "charter-ietf-ipatm", "unused_states": [], "ad": null, "parent": 1052, "list_email": "ip-atm@matmos.hpl.hp.com", "acronym": "ipatm", "comments": "Combined with rolc to become ION", "list_subscribe": "majordomo@matmos.hpl.hp.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.hep.net/ftp/lists-archive/atm", "type": "wg", "name": "IP Over Asynchronous Transfer Mode"}}, -{"pk": 1081, "model": "group.group", "fields": {"charter": "charter-ietf-ipcdn", "unused_states": [], "ad": 6699, "parent": 1193, "list_email": "ipcdn@ietf.org", "acronym": "ipcdn", "comments": "", "list_subscribe": "http://www.ietf.org/mailman/listinfo/ipcdn", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipcdn/", "type": "wg", "name": "IP over Cable Data Network"}}, +{"pk": 1081, "model": "group.group", "fields": {"charter": "charter-ietf-ipcdn", "unused_states": [], "ad": null, "parent": 1193, "list_email": "ipcdn@ietf.org", "acronym": "ipcdn", "comments": "", "list_subscribe": "http://www.ietf.org/mailman/listinfo/ipcdn", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipcdn/", "type": "wg", "name": "IP over Cable Data Network"}}, {"pk": 1082, "model": "group.group", "fields": {"charter": "charter-ietf-fddi", "unused_states": [], "ad": null, "parent": 1052, "list_email": "FDDI@merit.edu", "acronym": "fddi", "comments": "", "list_subscribe": "FDDI-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IP Over FDDI"}}, {"pk": 1083, "model": "group.group", "fields": {"charter": "charter-ietf-ipfc", "unused_states": [], "ad": null, "parent": 1052, "list_email": "ipfc@standards.gadzoox.com", "acronym": "ipfc", "comments": "BOF met first in November 1992; second meeting Toronto 1994. Name changed from\r\nfibreip for the 41st IETF-Los Angeles", "list_subscribe": "ipfc-request@standards.gadzoox.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "standards.gadzoox.com/pub/archives/ipfc/ipfc", "type": "wg", "name": "IP over Fibre Channel"}}, {"pk": 1084, "model": "group.group", "fields": {"charter": "charter-ietf-hippi", "unused_states": [], "ad": null, "parent": 1052, "list_email": "hippi-ietf@cray.com", "acronym": "hippi", "comments": "This is a placeholder for the IP over HIPPI internet draft", "list_subscribe": "hippi-ietf-request@cray.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IP Over HIPPI"}}, @@ -255,38 +255,38 @@ {"pk": 1086, "model": "group.group", "fields": {"charter": "charter-ietf-iplpdn", "unused_states": [], "ad": null, "parent": 1249, "list_email": "iplpdn@cnri.reston.va.us", "acronym": "iplpdn", "comments": "", "list_subscribe": "iplpdn-request@cnri.reston.va.us", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ietf.cnri.reston.va.us:~/ietf-mail-archive/iplpdn/*", "type": "wg", "name": "IP Over Large Public Data Networks"}}, {"pk": 1087, "model": "group.group", "fields": {"charter": "charter-ietf-smds", "unused_states": [], "ad": null, "parent": 1052, "list_email": "smds@cnri.reston.va.us", "acronym": "smds", "comments": "", "list_subscribe": "smds-request@cnri.reston.va.us", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ietf.cnri.reston.va.us:~/ietf-mail-archive/iplpdn", "type": "wg", "name": "IP Over Switched Megabit Data Service"}}, {"pk": 1088, "model": "group.group", "fields": {"charter": "charter-ietf-ippcp", "unused_states": [], "ad": null, "parent": 1052, "list_email": "ippcp@external.cisco.com", "acronym": "ippcp", "comments": "Conclude message sent August 6, 1998.", "list_subscribe": "mailer@cisco.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp-eng.cisco.com/ippcp/ippcp", "type": "wg", "name": "IP Payload Compression Protocol"}}, -{"pk": 1089, "model": "group.group", "fields": {"charter": "charter-ietf-ippm", "unused_states": [], "ad": 110856, "parent": 1324, "list_email": "ippm@ietf.org", "acronym": "ippm", "comments": "1st meeting 32nd IETF Danvers, MA April 3-7, 1995 mw", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ippm", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ippm/", "type": "wg", "name": "IP Performance Metrics"}}, +{"pk": 1089, "model": "group.group", "fields": {"charter": "charter-ietf-ippm", "unused_states": [], "ad": null, "parent": 1324, "list_email": "ippm@ietf.org", "acronym": "ippm", "comments": "1st meeting 32nd IETF Danvers, MA April 3-7, 1995 mw", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ippm", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ippm/", "type": "wg", "name": "IP Performance Metrics"}}, {"pk": 1090, "model": "group.group", "fields": {"charter": "charter-ietf-mobileip", "unused_states": [], "ad": null, "parent": 1052, "list_email": "mobile-ip@sunroof.eng.sun.com", "acronym": "mobileip", "comments": "Kannan replaced Deering as co-Chair 6/1/94. Li repl Minshall 10/12/94. Solomon repl Alagappan 3/10/95.Nordmark repl Li 6/7/96. Patil repl Solomon 4/6/99", "list_subscribe": "mobile-ip-request@sunroof.eng.sun.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://playground.sun.com/mobile-ip/", "type": "wg", "name": "IP Routing for Wireless/Mobile Hosts"}}, {"pk": 1091, "model": "group.group", "fields": {"charter": "charter-ietf-ipsec", "unused_states": [], "ad": null, "parent": 1260, "list_email": "ipsec@ietf.org", "acronym": "ipsec", "comments": "", "list_subscribe": "ipsec-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipsec/", "type": "wg", "name": "IP Security Protocol"}}, {"pk": 1093, "model": "group.group", "fields": {"charter": "charter-ietf-ipngwg", "unused_states": [], "ad": null, "parent": 1052, "list_email": "ipng@sunroof.eng.sun.com", "acronym": "ipngwg", "comments": "1st meeting Toronto IETF. mw This is to be *the* IPng Working Group, and this meeting as a BOF is its 'proto-WG' meeting. /jws", "list_subscribe": "majordomo@sunroof.eng.sun.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://playground.sun.com/pub/ipng/mail-archive", "type": "wg", "name": "IPNG"}}, {"pk": 1094, "model": "group.group", "fields": {"charter": "charter-ietf-ipdecide", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ipdecide", "comments": "1st IETF Meeting: Amsterdam: 97-03: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPng Decision Process"}}, -{"pk": 1095, "model": "group.group", "fields": {"charter": "charter-ietf-ngdir", "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "ngdir", "comments": "1st IETF MEETING: Seattle IETF: 94-03", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPNG Directorate"}}, -{"pk": 1096, "model": "group.group", "fields": {"charter": "charter-ietf-ngreqs", "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "ngreqs", "comments": "1st IETF Meeting: Seattle: 94-03: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPng Requirements"}}, +{"pk": 1095, "model": "group.group", "fields": {"charter": "charter-ietf-ngdir", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ngdir", "comments": "1st IETF MEETING: Seattle IETF: 94-03", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPNG Directorate"}}, +{"pk": 1096, "model": "group.group", "fields": {"charter": "charter-ietf-ngreqs", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ngreqs", "comments": "1st IETF Meeting: Seattle: 94-03: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPng Requirements"}}, {"pk": 1097, "model": "group.group", "fields": {"charter": "charter-ietf-6bonebof", "unused_states": [], "ad": null, "parent": 1193, "list_email": "6bone@isi.edu", "acronym": "6bonebof", "comments": "1st meeting at 36th IETF - Montreal, Canada", "list_subscribe": "majordomo@isi.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Transitions Planning"}}, {"pk": 1098, "model": "group.group", "fields": {"charter": "charter-ietf-ipv6mib", "unused_states": [], "ad": null, "parent": 1052, "list_email": "ip6mib@research.ftp.com", "acronym": "ipv6mib", "comments": "AD was Burgan", "list_subscribe": "ip6mib-request@research.ftp.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://research.ftp.com/pub/ip6mib/archive", "type": "wg", "name": "IPv6 MIB"}}, {"pk": 1099, "model": "group.group", "fields": {"charter": "charter-ietf-nbmav6", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "nbmav6", "comments": "1st meeting at 35th IETF - Los Angeles, CA - March 1996", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPv6 over NBMA"}}, {"pk": 1100, "model": "group.group", "fields": {"charter": "charter-ietf-bigaddr", "unused_states": [], "ad": null, "parent": 1249, "list_email": "", "acronym": "bigaddr", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPv7 Addressing"}}, {"pk": 1101, "model": "group.group", "fields": {"charter": "charter-ietf-ircup", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-ircup@imc.org", "acronym": "ircup", "comments": "1st meeting at 38th IETF - Memphis, TN\r\n2nd meeting at 41st IETF - Los Angeles, CA", "list_subscribe": "http://www.imc.org/ietf-ircup", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.imc.org/ietf-ircup/mail-archive/", "type": "wg", "name": "IRC Update"}}, -{"pk": 1102, "model": "group.group", "fields": {"charter": "charter-ietf-isis", "unused_states": [], "ad": 104198, "parent": 1249, "list_email": "isis-wg@ietf.org", "acronym": "isis", "comments": "ISIS-wg now hosted at IETF site.", "list_subscribe": "isis-wg-request@ietf.org", "state": "active", "time": "2012-06-14 12:06:58", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/isis-wg/", "type": "wg", "name": "IS-IS for IP Internets"}}, +{"pk": 1102, "model": "group.group", "fields": {"charter": "charter-ietf-isis", "unused_states": [], "ad": null, "parent": 1249, "list_email": "isis-wg@ietf.org", "acronym": "isis", "comments": "ISIS-wg now hosted at IETF site.", "list_subscribe": "isis-wg-request@ietf.org", "state": "active", "time": "2012-06-14 12:06:58", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/isis-wg/", "type": "wg", "name": "IS-IS for IP Internets"}}, {"pk": 1103, "model": "group.group", "fields": {"charter": "charter-ietf-isdnmib", "unused_states": [], "ad": null, "parent": 1052, "list_email": "isdn-mib@cisco.com", "acronym": "isdnmib", "comments": "1st meeting 32nd IETF, Danvers, MA 1/18/95 mw (BOF) List 'owner': owner-isdn-mib@cisco.com\r\n\r\nAD was Jeff Burgan", "list_subscribe": "isdn-mib-request@cisco.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp-eng.cisco.com/ftp/isdn-mib/isdn-mib", "type": "wg", "name": "ISDN MIB"}}, -{"pk": 1104, "model": "group.group", "fields": {"charter": "charter-ietf-jomann", "unused_states": [], "ad": 2324, "parent": 1193, "list_email": "njm@merit.edu", "acronym": "jomann", "comments": "", "list_subscribe": "njm-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Joint Monitoring Access for Adjacent Networks NSF"}}, -{"pk": 1105, "model": "group.group", "fields": {"charter": "charter-ietf-lanman", "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "lanmanwg@cnd.hp.com", "acronym": "lanman", "comments": "Microsoft took back control of the Lan Manager protocol and MIB. There is no further work for the working group.", "list_subscribe": "lanmanwg-request@cnd.hp.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "LAN Manager"}}, +{"pk": 1104, "model": "group.group", "fields": {"charter": "charter-ietf-jomann", "unused_states": [], "ad": null, "parent": 1193, "list_email": "njm@merit.edu", "acronym": "jomann", "comments": "", "list_subscribe": "njm-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Joint Monitoring Access for Adjacent Networks NSF"}}, +{"pk": 1105, "model": "group.group", "fields": {"charter": "charter-ietf-lanman", "unused_states": [], "ad": null, "parent": 1157, "list_email": "lanmanwg@cnd.hp.com", "acronym": "lanman", "comments": "Microsoft took back control of the Lan Manager protocol and MIB. There is no further work for the working group.", "list_subscribe": "lanmanwg-request@cnd.hp.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "LAN Manager"}}, {"pk": 1106, "model": "group.group", "fields": {"charter": "charter-ietf-lsma", "unused_states": [], "ad": null, "parent": 934, "list_email": "lsma@gmu.edu", "acronym": "lsma", "comments": "", "list_subscribe": "lsma-request@gmu.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Large Scale Multicast Applications"}}, {"pk": 1107, "model": "group.group", "fields": {"charter": "charter-ietf-lsthdr", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "lsthdr", "comments": "1st meeting at 38th IETF - Memphis", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Listheader"}}, -{"pk": 1108, "model": "group.group", "fields": {"charter": "charter-ietf-livdoc", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "", "acronym": "livdoc", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Living Documents"}}, -{"pk": 1109, "model": "group.group", "fields": {"charter": "charter-ietf-loip", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "", "acronym": "loip", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Low Cost IP Hardware Wish List"}}, -{"pk": 1110, "model": "group.group", "fields": {"charter": "charter-ietf-wg-llt", "unused_states": [], "ad": 188, "parent": 1179, "list_email": "", "acronym": "wg-llt", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Lower Layers Technology"}}, +{"pk": 1108, "model": "group.group", "fields": {"charter": "charter-ietf-livdoc", "unused_states": [], "ad": null, "parent": 1346, "list_email": "", "acronym": "livdoc", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Living Documents"}}, +{"pk": 1109, "model": "group.group", "fields": {"charter": "charter-ietf-loip", "unused_states": [], "ad": null, "parent": 1346, "list_email": "", "acronym": "loip", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Low Cost IP Hardware Wish List"}}, +{"pk": 1110, "model": "group.group", "fields": {"charter": "charter-ietf-wg-llt", "unused_states": [], "ad": null, "parent": 1179, "list_email": "", "acronym": "wg-llt", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Lower Layers Technology"}}, {"pk": 1111, "model": "group.group", "fields": {"charter": "charter-ietf-madman", "unused_states": [], "ad": null, "parent": 934, "list_email": "madman@innosoft.com", "acronym": "madman", "comments": "Orig End 1/11/94. Reactivated for Dallas IETF as Applications Area WG.", "list_subscribe": "mailserv@innosoft.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://innosoft.com/anon/files/ietf-madman/archive.digest", "type": "wg", "name": "Mail and Directory Management"}}, -{"pk": 1112, "model": "group.group", "fields": {"charter": "charter-ietf-wg-msg", "unused_states": [], "ad": 188, "parent": 934, "list_email": "", "acronym": "wg-msg", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Mail and Messaging"}}, +{"pk": 1112, "model": "group.group", "fields": {"charter": "charter-ietf-wg-msg", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "wg-msg", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Mail and Messaging"}}, {"pk": 1113, "model": "group.group", "fields": {"charter": "charter-ietf-mailext", "unused_states": [], "ad": null, "parent": 934, "list_email": "mailext@list.cren.net", "acronym": "mailext", "comments": "1st meeting 30th IETF, Toronto July 1994 BOF mw.", "list_subscribe": "listproc@list.cren.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Mail Extensions"}}, -{"pk": 1114, "model": "group.group", "fields": {"charter": "charter-ietf-mailftp", "unused_states": [], "ad": 2744, "parent": null, "list_email": "", "acronym": "mailftp", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Mail-based File Distribution"}}, -{"pk": 1115, "model": "group.group", "fields": {"charter": "charter-ietf-wg8", "unused_states": [], "ad": 188, "parent": 1179, "list_email": "", "acronym": "wg8", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Management of Network Application Services"}}, -{"pk": 1116, "model": "group.group", "fields": {"charter": "charter-ietf-msi", "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "msiwg@decwrl.dec.com", "acronym": "msi", "comments": "Took the better part of valor", "list_subscribe": "msiwg-request@decwrl.dec.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Management Services Interface"}}, -{"pk": 1117, "model": "group.group", "fields": {"charter": "charter-ietf-atmmib", "unused_states": [], "ad": 4763, "parent": null, "list_email": "", "acronym": "atmmib", "comments": "Bacame the atommib WG after the Boston Meeting.", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Managing ATM with SNMP"}}, -{"pk": 1118, "model": "group.group", "fields": {"charter": "charter-ietf-mboned", "unused_states": [], "ad": 101568, "parent": 1193, "list_email": "mboned@ietf.org", "acronym": "mboned", "comments": "AD was Harald", "list_subscribe": "https://www.ietf.org/mailman/listinfo/mboned", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mboned", "type": "wg", "name": "MBONE Deployment"}}, -{"pk": 1119, "model": "group.group", "fields": {"charter": "charter-ietf-mboneng", "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "mboneng", "comments": "1st meeting BOF: 34th IETF: Dallas, TX December 4-8, 1995 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "MBone Engineering"}}, -{"pk": 1120, "model": "group.group", "fields": {"charter": "charter-ietf-mbone", "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "mbone", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "MBONE Engineering and Operations"}}, -{"pk": 1121, "model": "group.group", "fields": {"charter": "charter-ietf-wg1", "unused_states": [], "ad": 188, "parent": 1179, "list_email": "", "acronym": "wg1", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Message Handeling Systems"}}, +{"pk": 1114, "model": "group.group", "fields": {"charter": "charter-ietf-mailftp", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "mailftp", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Mail-based File Distribution"}}, +{"pk": 1115, "model": "group.group", "fields": {"charter": "charter-ietf-wg8", "unused_states": [], "ad": null, "parent": 1179, "list_email": "", "acronym": "wg8", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Management of Network Application Services"}}, +{"pk": 1116, "model": "group.group", "fields": {"charter": "charter-ietf-msi", "unused_states": [], "ad": null, "parent": 1157, "list_email": "msiwg@decwrl.dec.com", "acronym": "msi", "comments": "Took the better part of valor", "list_subscribe": "msiwg-request@decwrl.dec.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Management Services Interface"}}, +{"pk": 1117, "model": "group.group", "fields": {"charter": "charter-ietf-atmmib", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "atmmib", "comments": "Bacame the atommib WG after the Boston Meeting.", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Managing ATM with SNMP"}}, +{"pk": 1118, "model": "group.group", "fields": {"charter": "charter-ietf-mboned", "unused_states": [], "ad": null, "parent": 1193, "list_email": "mboned@ietf.org", "acronym": "mboned", "comments": "AD was Harald", "list_subscribe": "https://www.ietf.org/mailman/listinfo/mboned", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mboned", "type": "wg", "name": "MBONE Deployment"}}, +{"pk": 1119, "model": "group.group", "fields": {"charter": "charter-ietf-mboneng", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "mboneng", "comments": "1st meeting BOF: 34th IETF: Dallas, TX December 4-8, 1995 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "MBone Engineering"}}, +{"pk": 1120, "model": "group.group", "fields": {"charter": "charter-ietf-mbone", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "mbone", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "MBONE Engineering and Operations"}}, +{"pk": 1121, "model": "group.group", "fields": {"charter": "charter-ietf-wg1", "unused_states": [], "ad": null, "parent": 1179, "list_email": "", "acronym": "wg1", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Message Handeling Systems"}}, {"pk": 1122, "model": "group.group", "fields": {"charter": "charter-ietf-msp", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "msp", "comments": "1st meeting at Los Angeles IETF, 35th IETF, March 1996", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Message Security Protocol"}}, {"pk": 1123, "model": "group.group", "fields": {"charter": "charter-ietf-mhsds", "unused_states": [], "ad": null, "parent": 934, "list_email": "mhs-ds@mercury.udev.cdc.com", "acronym": "mhsds", "comments": "Moved from SAP to APP on 10 May 1994 by JWS>", "list_subscribe": "mhs-ds-request@mercury.udev.cdc.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "mercury.udev.cdc.com:~/pub/archives/mhs-ds-archive", "type": "wg", "name": "MHS-DS"}}, {"pk": 1124, "model": "group.group", "fields": {"charter": "charter-ietf-mixer", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-mixer@innosoft.com", "acronym": "mixer", "comments": "Danvers IETF, April 3-7, 1995 (closed session)", "list_subscribe": "mailserv@innosoft.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.innosoft.com/ietf-mixer/", "type": "wg", "name": "MIME - X.400 Gateway"}}, @@ -297,115 +297,115 @@ {"pk": 1129, "model": "group.group", "fields": {"charter": "charter-ietf-pgpmime", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "pgpmime", "comments": "1st Meeting at 37th IETF - San Jose", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "MIME Security with Pretty Good Privacy"}}, {"pk": 1130, "model": "group.group", "fields": {"charter": "charter-ietf-mimemhs", "unused_states": [], "ad": null, "parent": 934, "list_email": "mime-mhs@surfnet.nl", "acronym": "mimemhs", "comments": "", "list_subscribe": "mime-mhs-request@surfnet.nl", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "MIME-MHS Interworking"}}, {"pk": 1131, "model": "group.group", "fields": {"charter": "charter-ietf-thinosi", "unused_states": [], "ad": null, "parent": 934, "list_email": "thinosi@ulcc.ac.uk", "acronym": "thinosi", "comments": "Moved from SAP to TSV on 10 May 1994 by JWS.", "list_subscribe": "thinosi-request@ulcc.ac.uk", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "pluto.ulcc.ac.uk:/ulcc/thinosi/thinosi-mail-archive.txt", "type": "wg", "name": "Minimal OSI Upper-Layers"}}, -{"pk": 1132, "model": "group.group", "fields": {"charter": "charter-ietf-manet", "unused_states": [], "ad": 104198, "parent": 1249, "list_email": "manet@ietf.org", "acronym": "manet", "comments": "", "list_subscribe": "manet-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/manet/", "type": "wg", "name": "Mobile Ad-hoc Networks"}}, +{"pk": 1132, "model": "group.group", "fields": {"charter": "charter-ietf-manet", "unused_states": [], "ad": null, "parent": 1249, "list_email": "manet@ietf.org", "acronym": "manet", "comments": "", "list_subscribe": "manet-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/manet/", "type": "wg", "name": "Mobile Ad-hoc Networks"}}, {"pk": 1133, "model": "group.group", "fields": {"charter": "charter-ietf-mmnet", "unused_states": [], "ad": null, "parent": 1249, "list_email": "mmnet@itd.nrl.navy.mil", "acronym": "mmnet", "comments": "1st met as BOF, 34th IETF: Dallas, Tx December 4-8, 1995 mw", "list_subscribe": "majordomo@itd.nrl.navy.mil", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://mars.itd.nrl.navy.mil/pub/mmnet", "type": "wg", "name": "Mobile Mesh Networks"}}, -{"pk": 1134, "model": "group.group", "fields": {"charter": "charter-ietf-modemmgt", "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "modemmgt@Telebit.com", "acronym": "modemmgt", "comments": "", "list_subscribe": "majordomo@Telebit.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp.telebit.com:~/pub/modemmgt", "type": "wg", "name": "Modem Management"}}, +{"pk": 1134, "model": "group.group", "fields": {"charter": "charter-ietf-modemmgt", "unused_states": [], "ad": null, "parent": 1157, "list_email": "modemmgt@Telebit.com", "acronym": "modemmgt", "comments": "", "list_subscribe": "majordomo@Telebit.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp.telebit.com:~/pub/modemmgt", "type": "wg", "name": "Modem Management"}}, {"pk": 1135, "model": "group.group", "fields": {"charter": "charter-ietf-mmb", "unused_states": [], "ad": null, "parent": 1052, "list_email": "mmbwg@fibercom.com", "acronym": "mmb", "comments": "", "list_subscribe": "mmbwg-request@fibercom.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Multi-Media Bridging"}}, {"pk": 1136, "model": "group.group", "fields": {"charter": "charter-ietf-mospf", "unused_states": [], "ad": null, "parent": 1249, "list_email": "mospf@gated.cornell.edu", "acronym": "mospf", "comments": "", "list_subscribe": "mospf-request@gated.cornell.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Multicast Extensions to OSPF"}}, {"pk": 1137, "model": "group.group", "fields": {"charter": "charter-ietf-mcwww", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "mcwww", "comments": "1st meeting at 38th IETF - Memphis, TN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Multicast WWW"}}, -{"pk": 1138, "model": "group.group", "fields": {"charter": "charter-ietf-mmusic", "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "mmusic@ietf.org", "acronym": "mmusic", "comments": "", "list_subscribe": "mmusic-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mmusic/", "type": "wg", "name": "Multiparty Multimedia Session Control"}}, -{"pk": 1139, "model": "group.group", "fields": {"charter": "charter-ietf-mplxmib", "unused_states": [], "ad": 4763, "parent": null, "list_email": "", "acronym": "mplxmib", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Multiplexing SNMP Agents BOF"}}, -{"pk": 1140, "model": "group.group", "fields": {"charter": "charter-ietf-mpls", "unused_states": [], "ad": 104198, "parent": 1249, "list_email": "mpls@ietf.org", "acronym": "mpls", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/mpls", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mpls/", "type": "wg", "name": "Multiprotocol Label Switching"}}, +{"pk": 1138, "model": "group.group", "fields": {"charter": "charter-ietf-mmusic", "unused_states": [], "ad": null, "parent": 1683, "list_email": "mmusic@ietf.org", "acronym": "mmusic", "comments": "", "list_subscribe": "mmusic-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mmusic/", "type": "wg", "name": "Multiparty Multimedia Session Control"}}, +{"pk": 1139, "model": "group.group", "fields": {"charter": "charter-ietf-mplxmib", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "mplxmib", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Multiplexing SNMP Agents BOF"}}, +{"pk": 1140, "model": "group.group", "fields": {"charter": "charter-ietf-mpls", "unused_states": [], "ad": null, "parent": 1249, "list_email": "mpls@ietf.org", "acronym": "mpls", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/mpls", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mpls/", "type": "wg", "name": "Multiprotocol Label Switching"}}, {"pk": 1141, "model": "group.group", "fields": {"charter": "charter-ietf-mptrans", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "mptrans", "comments": "1st meeting 31st IETF (December 5-9, 1994/San Jose) mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Multiprotocol Transport"}}, {"pk": 1142, "model": "group.group", "fields": {"charter": "charter-ietf-napmime", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "napmime", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "NAPLPS Graphics and Character Sets as a MIME"}}, {"pk": 1143, "model": "group.group", "fields": {"charter": "charter-ietf-nasreqng", "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "nasreqng", "comments": "1st meeting at 42nd IETF - Chicago, IL; 2nd meeting at 43rd IETF - Orlando, FL\r\nAD was Harald", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Next Generation Network Access Server Requirements"}}, {"pk": 1145, "model": "group.group", "fields": {"charter": "charter-ietf-rtqos", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "rtqos", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Net Support for QOS and Real-Time Traffic"}}, -{"pk": 1146, "model": "group.group", "fields": {"charter": "charter-ietf-abby", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "", "acronym": "abby", "comments": "1st meeting Toronto IETF (30th), Martyne Hallgren chaired. mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Netiquette"}}, +{"pk": 1146, "model": "group.group", "fields": {"charter": "charter-ietf-abby", "unused_states": [], "ad": null, "parent": 1346, "list_email": "", "acronym": "abby", "comments": "1st meeting Toronto IETF (30th), Martyne Hallgren chaired. mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Netiquette"}}, {"pk": 1147, "model": "group.group", "fields": {"charter": "charter-ietf-nasreq", "unused_states": [], "ad": null, "parent": 1193, "list_email": "nasreq@ops.ietf.org", "acronym": "nasreq", "comments": "Ostart: 14jul92,concluded 7mar95.", "list_subscribe": "nasreq-request@ops.ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://ops.ietf.org/lists/nasreq/", "type": "wg", "name": "Network Access Server Requirements"}}, {"pk": 1148, "model": "group.group", "fields": {"charter": "charter-ietf-nat", "unused_states": [], "ad": null, "parent": 1324, "list_email": "nat@ietf.org", "acronym": "nat", "comments": "", "list_subscribe": "nat-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.ietf.org/ietf-mail-archive/nat/", "type": "wg", "name": "Network Address Translators"}}, -{"pk": 1149, "model": "group.group", "fields": {"charter": "charter-ietf-wg-nap", "unused_states": [], "ad": 188, "parent": 1179, "list_email": "", "acronym": "wg-nap", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Applications Support"}}, -{"pk": 1150, "model": "group.group", "fields": {"charter": "charter-ietf-netdata", "unused_states": [], "ad": 2744, "parent": 934, "list_email": "ietf-ndb@ucdavis.edu", "acronym": "netdata", "comments": "", "list_subscribe": "ietf-ndb-request@ucdavis.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Database"}}, +{"pk": 1149, "model": "group.group", "fields": {"charter": "charter-ietf-wg-nap", "unused_states": [], "ad": null, "parent": 1179, "list_email": "", "acronym": "wg-nap", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Applications Support"}}, +{"pk": 1150, "model": "group.group", "fields": {"charter": "charter-ietf-netdata", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-ndb@ucdavis.edu", "acronym": "netdata", "comments": "", "list_subscribe": "ietf-ndb-request@ucdavis.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Database"}}, {"pk": 1151, "model": "group.group", "fields": {"charter": "charter-ietf-netfax", "unused_states": [], "ad": null, "parent": 934, "list_email": "netfax@stubbs.ucop.edu", "acronym": "netfax", "comments": "", "list_subscribe": "netfax-request@stubbs.ucop.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "/pub/netfax@stubbs.ucop.edu", "type": "wg", "name": "Network Fax"}}, -{"pk": 1152, "model": "group.group", "fields": {"charter": "charter-ietf-nfsv4", "unused_states": [], "ad": 105519, "parent": 1324, "list_email": "nfsv4@ietf.org", "acronym": "nfsv4", "comments": "1st meeting at 37th IETF - San Jose, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/nfsv4", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/nfsv4/", "type": "wg", "name": "Network File System Version 4"}}, +{"pk": 1152, "model": "group.group", "fields": {"charter": "charter-ietf-nfsv4", "unused_states": [], "ad": null, "parent": 1324, "list_email": "nfsv4@ietf.org", "acronym": "nfsv4", "comments": "1st meeting at 37th IETF - San Jose, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/nfsv4", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/nfsv4/", "type": "wg", "name": "Network File System Version 4"}}, {"pk": 1153, "model": "group.group", "fields": {"charter": "charter-ietf-netgraph", "unused_states": [], "ad": null, "parent": 934, "list_email": "netgraph@nri.reston.va.us", "acronym": "netgraph", "comments": "", "list_subscribe": "netgraph-request@nri.reston.va.us", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Graphics"}}, -{"pk": 1154, "model": "group.group", "fields": {"charter": "charter-ietf-nisi", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "nisi@merit.edu", "acronym": "nisi", "comments": "Pat Smith resigned as co-chair in April 1994 mw", "list_subscribe": "nisi-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Information Services Infrastructure"}}, -{"pk": 1155, "model": "group.group", "fields": {"charter": "charter-ietf-njm", "unused_states": [], "ad": 2324, "parent": 1193, "list_email": "njm@merit.edu", "acronym": "njm", "comments": "", "list_subscribe": "njm-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Joint Management"}}, -{"pk": 1156, "model": "group.group", "fields": {"charter": "charter-ietf-x3s3.3", "unused_states": [], "ad": 188, "parent": null, "list_email": "", "acronym": "x3s3.3", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Level Standards"}}, -{"pk": 1158, "model": "group.group", "fields": {"charter": "charter-ietf-nmarea", "unused_states": [], "ad": 4763, "parent": null, "list_email": "", "acronym": "nmarea", "comments": "formerly met as the SNMP Network Management Directorate", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Management Area Open Meeting"}}, +{"pk": 1154, "model": "group.group", "fields": {"charter": "charter-ietf-nisi", "unused_states": [], "ad": null, "parent": 1346, "list_email": "nisi@merit.edu", "acronym": "nisi", "comments": "Pat Smith resigned as co-chair in April 1994 mw", "list_subscribe": "nisi-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Information Services Infrastructure"}}, +{"pk": 1155, "model": "group.group", "fields": {"charter": "charter-ietf-njm", "unused_states": [], "ad": null, "parent": 1193, "list_email": "njm@merit.edu", "acronym": "njm", "comments": "", "list_subscribe": "njm-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Joint Management"}}, +{"pk": 1156, "model": "group.group", "fields": {"charter": "charter-ietf-x3s3.3", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "x3s3.3", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Level Standards"}}, +{"pk": 1158, "model": "group.group", "fields": {"charter": "charter-ietf-nmarea", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "nmarea", "comments": "formerly met as the SNMP Network Management Directorate", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Management Area Open Meeting"}}, {"pk": 1159, "model": "group.group", "fields": {"charter": "charter-ietf-nntp", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-nntp@turbo.bio.net", "acronym": "nntp", "comments": "", "list_subscribe": "ietf-nntp-request@turbo.bio.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network News Transport Protocol"}}, -{"pk": 1160, "model": "group.group", "fields": {"charter": "charter-ietf-wg-nop", "unused_states": [], "ad": 188, "parent": 1179, "list_email": "", "acronym": "wg-nop", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Operations"}}, -{"pk": 1161, "model": "group.group", "fields": {"charter": "charter-ietf-wg4", "unused_states": [], "ad": 188, "parent": 1179, "list_email": "", "acronym": "wg4", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Operations and X.25"}}, -{"pk": 1162, "model": "group.group", "fields": {"charter": "charter-ietf-noop", "unused_states": [], "ad": 2324, "parent": 1199, "list_email": "noop@merit.edu", "acronym": "noop", "comments": "", "list_subscribe": "noop-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "merit.edu:~/pub/noop-archive", "type": "wg", "name": "Network OSI Operations"}}, -{"pk": 1163, "model": "group.group", "fields": {"charter": "charter-ietf-npp", "unused_states": [], "ad": 2744, "parent": 934, "list_email": "print-wg@pa.dec.com", "acronym": "npp", "comments": "", "list_subscribe": "print-wg-request@pa.dec.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Printing Protocol"}}, -{"pk": 1164, "model": "group.group", "fields": {"charter": "charter-ietf-netstat", "unused_states": [], "ad": 2324, "parent": 1193, "list_email": "njm@merit.edu", "acronym": "netstat", "comments": "", "list_subscribe": "njm-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Status Reports"}}, -{"pk": 1165, "model": "group.group", "fields": {"charter": "charter-ietf-trainmat", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "network-training-tf@mailbase.ac.uk", "acronym": "trainmat", "comments": "", "list_subscribe": "mailbase@mailbase.ac.uk", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://mailbase.ac.uk/pub/lists/network-training-tf/archives/", "type": "wg", "name": "Network Training Materials"}}, -{"pk": 1166, "model": "group.group", "fields": {"charter": "charter-ietf-nir", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "nir@mailbase.ac.uk", "acronym": "nir", "comments": "", "list_subscribe": "mailbase@mailbase.ac.uk", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "mailbase.ac.uk:~/pub/nir", "type": "wg", "name": "Networked Information Retrieval"}}, +{"pk": 1160, "model": "group.group", "fields": {"charter": "charter-ietf-wg-nop", "unused_states": [], "ad": null, "parent": 1179, "list_email": "", "acronym": "wg-nop", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Operations"}}, +{"pk": 1161, "model": "group.group", "fields": {"charter": "charter-ietf-wg4", "unused_states": [], "ad": null, "parent": 1179, "list_email": "", "acronym": "wg4", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Operations and X.25"}}, +{"pk": 1162, "model": "group.group", "fields": {"charter": "charter-ietf-noop", "unused_states": [], "ad": null, "parent": 1199, "list_email": "noop@merit.edu", "acronym": "noop", "comments": "", "list_subscribe": "noop-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "merit.edu:~/pub/noop-archive", "type": "wg", "name": "Network OSI Operations"}}, +{"pk": 1163, "model": "group.group", "fields": {"charter": "charter-ietf-npp", "unused_states": [], "ad": null, "parent": 934, "list_email": "print-wg@pa.dec.com", "acronym": "npp", "comments": "", "list_subscribe": "print-wg-request@pa.dec.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Printing Protocol"}}, +{"pk": 1164, "model": "group.group", "fields": {"charter": "charter-ietf-netstat", "unused_states": [], "ad": null, "parent": 1193, "list_email": "njm@merit.edu", "acronym": "netstat", "comments": "", "list_subscribe": "njm-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Status Reports"}}, +{"pk": 1165, "model": "group.group", "fields": {"charter": "charter-ietf-trainmat", "unused_states": [], "ad": null, "parent": 1346, "list_email": "network-training-tf@mailbase.ac.uk", "acronym": "trainmat", "comments": "", "list_subscribe": "mailbase@mailbase.ac.uk", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://mailbase.ac.uk/pub/lists/network-training-tf/archives/", "type": "wg", "name": "Network Training Materials"}}, +{"pk": 1166, "model": "group.group", "fields": {"charter": "charter-ietf-nir", "unused_states": [], "ad": null, "parent": 1346, "list_email": "nir@mailbase.ac.uk", "acronym": "nir", "comments": "", "list_subscribe": "mailbase@mailbase.ac.uk", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "mailbase.ac.uk:~/pub/nir", "type": "wg", "name": "Networked Information Retrieval"}}, {"pk": 1167, "model": "group.group", "fields": {"charter": "charter-ietf-multiapp", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "multiapp", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Networking Multimedia Applications"}}, {"pk": 1168, "model": "group.group", "fields": {"charter": "charter-ietf-nimrod", "unused_states": [], "ad": null, "parent": 1249, "list_email": "nimrod-wg@bbn.com", "acronym": "nimrod", "comments": "1st IETF Meeting: Santa Fe: 91-11: BOF", "list_subscribe": "nimrod-wg-request@bbn.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://bbn.com/pub/nimrod-wg/nimrod-wg.archive", "type": "wg", "name": "New Internet Routing and Addressing Architecture"}}, {"pk": 1169, "model": "group.group", "fields": {"charter": "charter-ietf-nttcp", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "nttcp", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "New Technology TCP"}}, -{"pk": 1170, "model": "group.group", "fields": {"charter": "charter-ietf-newdom", "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "newdom", "comments": "1st meeting at 37th IETF - San Jose", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "New Top Level Domains"}}, -{"pk": 1171, "model": "group.group", "fields": {"charter": "charter-ietf-nosi", "unused_states": [], "ad": 2324, "parent": null, "list_email": "nosi@sunroof.eng.sun.com", "acronym": "nosi", "comments": "1st meeting, San Jose December 5-9, 1994 mw", "list_subscribe": "majordomo@sunroof.eng.sun.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Next Generation and OSI"}}, -{"pk": 1172, "model": "group.group", "fields": {"charter": "charter-ietf-newgen", "unused_states": [], "ad": 2853, "parent": 1179, "list_email": "", "acronym": "newgen", "comments": "1st meeting at 37th IETF - San Jose, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Next Generation Internet Initiative"}}, +{"pk": 1170, "model": "group.group", "fields": {"charter": "charter-ietf-newdom", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "newdom", "comments": "1st meeting at 37th IETF - San Jose", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "New Top Level Domains"}}, +{"pk": 1171, "model": "group.group", "fields": {"charter": "charter-ietf-nosi", "unused_states": [], "ad": null, "parent": null, "list_email": "nosi@sunroof.eng.sun.com", "acronym": "nosi", "comments": "1st meeting, San Jose December 5-9, 1994 mw", "list_subscribe": "majordomo@sunroof.eng.sun.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Next Generation and OSI"}}, +{"pk": 1172, "model": "group.group", "fields": {"charter": "charter-ietf-newgen", "unused_states": [], "ad": null, "parent": 1179, "list_email": "", "acronym": "newgen", "comments": "1st meeting at 37th IETF - San Jose, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Next Generation Internet Initiative"}}, {"pk": 1173, "model": "group.group", "fields": {"charter": "charter-ietf-tcpng", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "tcpng", "comments": "1st meeting December 1994 IETF, San Jose. mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Next Generation TCP"}}, {"pk": 1174, "model": "group.group", "fields": {"charter": "charter-ietf-ngtrans", "unused_states": [], "ad": null, "parent": 1193, "list_email": "ngtrans@sunroof.eng.sun.com", "acronym": "ngtrans", "comments": "1st meeting 31st IETF, San Jose 5-9 December 1994 BOF mw.", "list_subscribe": "majordomo@sunroof.eng.sun.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.ietf.org/ietf-mail-archive/ngtrans/", "type": "wg", "name": "Next Generation Transition"}}, -{"pk": 1175, "model": "group.group", "fields": {"charter": "charter-ietf-onc", "unused_states": [], "ad": 2744, "parent": null, "list_email": "", "acronym": "onc", "comments": "1st IETF Meeting: Amsterdam: 93-07: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "NFS and ONC IETF Standards Effort"}}, +{"pk": 1175, "model": "group.group", "fields": {"charter": "charter-ietf-onc", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "onc", "comments": "1st IETF Meeting: Amsterdam: 93-07: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "NFS and ONC IETF Standards Effort"}}, {"pk": 1176, "model": "group.group", "fields": {"charter": "charter-ietf-nntpext", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-nntp@lists.eyrie.org", "acronym": "nntpext", "comments": "WG Information: http://www.academ.com/academ/nntp/ietf.html", "list_subscribe": "http://lists.eyrie.org/mailman/listinfo/ietf-nntp", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.eyrie.org/pipermail/ietf-nntp/", "type": "wg", "name": "NNTP Extensions"}}, -{"pk": 1177, "model": "group.group", "fields": {"charter": "charter-ietf-noctool2", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "noctools@merit.edu", "acronym": "noctool2", "comments": "", "list_subscribe": "noctools-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "NOC-Tool Catalogue Revisions"}}, -{"pk": 1178, "model": "group.group", "fields": {"charter": "charter-ietf-noctools", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "noctools@merit.edu", "acronym": "noctools", "comments": "", "list_subscribe": "noctools-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "NOC-Tools"}}, +{"pk": 1177, "model": "group.group", "fields": {"charter": "charter-ietf-noctool2", "unused_states": [], "ad": null, "parent": 1346, "list_email": "noctools@merit.edu", "acronym": "noctool2", "comments": "", "list_subscribe": "noctools-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "NOC-Tool Catalogue Revisions"}}, +{"pk": 1178, "model": "group.group", "fields": {"charter": "charter-ietf-noctools", "unused_states": [], "ad": null, "parent": 1346, "list_email": "noctools@merit.edu", "acronym": "noctools", "comments": "", "list_subscribe": "noctools-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "NOC-Tools"}}, {"pk": 1180, "model": "group.group", "fields": {"charter": "charter-ietf-notary", "unused_states": [], "ad": null, "parent": 934, "list_email": "notifications@cs.utk.edu", "acronym": "notary", "comments": "", "list_subscribe": "notifications-request@cs.utk.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Notifications and Acknowledgements Requirements"}}, {"pk": 1182, "model": "group.group", "fields": {"charter": "charter-ietf-ios", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ios", "comments": "1st meeting San Jose 12/94: mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Object/Document Security"}}, {"pk": 1183, "model": "group.group", "fields": {"charter": "charter-ietf-oda", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-osi-oda@cs.ucl.ac.uk", "acronym": "oda", "comments": "", "list_subscribe": "ietf-osi-oda-request@cs.ucl.ac.uk", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Office Document Architecture"}}, {"pk": 1184, "model": "group.group", "fields": {"charter": "charter-ietf-oncrpc", "unused_states": [], "ad": null, "parent": 1324, "list_email": "oncrpc-wg@sunroof.eng.sun.com", "acronym": "oncrpc", "comments": "1st IETF Meeting: Seattle: 94-03: WG. Moved from SAP to TSV on 10 May 1994 by JWS.", "list_subscribe": "oncrpc-wg-request@sunroof.eng.sun.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://playground.sun.com/pub/oncrpc", "type": "wg", "name": "ONC Remote Procedure Call"}}, {"pk": 1185, "model": "group.group", "fields": {"charter": "charter-ietf-otp", "unused_states": [], "ad": null, "parent": 1260, "list_email": "ietf-otp@research.telcordia.com", "acronym": "otp", "comments": "Met as skey BOF in Danvers.", "list_subscribe": "ietf-otp-request@research.telcordia.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.research.telcordia.com/pub/ietf-otp/archive", "type": "wg", "name": "One Time Password Authentication"}}, {"pk": 1186, "model": "group.group", "fields": {"charter": "charter-ietf-odv", "unused_states": [], "ad": null, "parent": 1249, "list_email": "odvigp@rutgers.edu", "acronym": "odv", "comments": "", "list_subscribe": "odvigp-request@rutgers.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Open Distance Vector IGP"}}, -{"pk": 1187, "model": "group.group", "fields": {"charter": "charter-ietf-saag", "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "saag@mit.edu", "acronym": "saag", "comments": "6/7/94 Jeff Schiller closed to form Security Area Directorate. 10/94 Jeff want SAAG for open meeting, SECDIR for closed. mw", "list_subscribe": "saag-request@mit.edu", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ag", "name": "Security Area Open Meeting"}}, -{"pk": 1188, "model": "group.group", "fields": {"charter": "charter-ietf-ospf", "unused_states": [], "ad": 2329, "parent": 1249, "list_email": "ospf@ietf.org", "acronym": "ospf", "comments": "Additional Working Group Site: http://rtg.ietf.org/ospf/", "list_subscribe": "ospf-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ospf/", "type": "wg", "name": "Open Shortest Path First IGP"}}, +{"pk": 1187, "model": "group.group", "fields": {"charter": "charter-ietf-saag", "unused_states": [], "ad": null, "parent": 1260, "list_email": "saag@mit.edu", "acronym": "saag", "comments": "6/7/94 Jeff Schiller closed to form Security Area Directorate. 10/94 Jeff want SAAG for open meeting, SECDIR for closed. mw", "list_subscribe": "saag-request@mit.edu", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ag", "name": "Security Area Open Meeting"}}, +{"pk": 1188, "model": "group.group", "fields": {"charter": "charter-ietf-ospf", "unused_states": [], "ad": null, "parent": 1249, "list_email": "ospf@ietf.org", "acronym": "ospf", "comments": "Additional Working Group Site: http://rtg.ietf.org/ospf/", "list_subscribe": "ospf-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ospf/", "type": "wg", "name": "Open Shortest Path First IGP"}}, {"pk": 1189, "model": "group.group", "fields": {"charter": "charter-ietf-otsv", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "otsv", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Open Transport Area Meeting"}}, -{"pk": 1191, "model": "group.group", "fields": {"charter": "charter-ietf-orad", "unused_states": [], "ad": 2324, "parent": null, "list_email": "orad@sdsc.edu", "acronym": "orad", "comments": "", "list_subscribe": "orad-request@sdsc.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Operational Requirements Area Directorate"}}, -{"pk": 1192, "model": "group.group", "fields": {"charter": "charter-ietf-opstat", "unused_states": [], "ad": 2324, "parent": 1193, "list_email": "oswg-l@wugate.wustl.edu", "acronym": "opstat", "comments": "Henry and Nevil replaced Phill Gross and Bernhard Stockman as chairs", "list_subscribe": "oswg-l-request@wugate.wustl.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://wuarchive.wustl.edu/doc/mailing-lists/oswg-l", "type": "wg", "name": "Operational Statistics"}}, +{"pk": 1191, "model": "group.group", "fields": {"charter": "charter-ietf-orad", "unused_states": [], "ad": null, "parent": null, "list_email": "orad@sdsc.edu", "acronym": "orad", "comments": "", "list_subscribe": "orad-request@sdsc.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Operational Requirements Area Directorate"}}, +{"pk": 1192, "model": "group.group", "fields": {"charter": "charter-ietf-opstat", "unused_states": [], "ad": null, "parent": 1193, "list_email": "oswg-l@wugate.wustl.edu", "acronym": "opstat", "comments": "Henry and Nevil replaced Phill Gross and Bernhard Stockman as chairs", "list_subscribe": "oswg-l-request@wugate.wustl.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://wuarchive.wustl.edu/doc/mailing-lists/oswg-l", "type": "wg", "name": "Operational Statistics"}}, {"pk": 1194, "model": "group.group", "fields": {"charter": "charter-ietf-omarea", "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "omarea", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Operations and Management Open Area Meeting"}}, {"pk": 1195, "model": "group.group", "fields": {"charter": "charter-ietf-dce", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "dce", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "OSF Distributed Computing Environment"}}, {"pk": 1196, "model": "group.group", "fields": {"charter": "charter-ietf-osids", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-osi-ds@cs.ucl.ac.uk", "acronym": "osids", "comments": "", "list_subscribe": "ietf-osi-ds-request@cs.ucl.ac.uk", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "OSI Directory Services"}}, -{"pk": 1197, "model": "group.group", "fields": {"charter": "charter-ietf-osigen", "unused_states": [], "ad": 2372, "parent": 1199, "list_email": "ietf-osi@cs.wisc.edu", "acronym": "osigen", "comments": "", "list_subscribe": "ietf-osi-request@cs.wisc.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "janeb.cs.wisc.edu:/pub/archives/ietf-osi", "type": "wg", "name": "OSI General"}}, +{"pk": 1197, "model": "group.group", "fields": {"charter": "charter-ietf-osigen", "unused_states": [], "ad": null, "parent": 1199, "list_email": "ietf-osi@cs.wisc.edu", "acronym": "osigen", "comments": "", "list_subscribe": "ietf-osi-request@cs.wisc.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "janeb.cs.wisc.edu:/pub/archives/ietf-osi", "type": "wg", "name": "OSI General"}}, {"pk": 1198, "model": "group.group", "fields": {"charter": "charter-ietf-ipidrp", "unused_states": [], "ad": null, "parent": 1249, "list_email": "idrp-for-ip@merit.edu", "acronym": "ipidrp", "comments": "IPIDRP merged with BGP to make IDR.", "list_subscribe": "idrp-for-ip-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "merit.edu:~/pub/archive/idrp", "type": "wg", "name": "OSI IDRP for IP Over IP"}}, -{"pk": 1200, "model": "group.group", "fields": {"charter": "charter-ietf-oim", "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "oim@mbunix.mitre.org", "acronym": "oim", "comments": "", "list_subscribe": "oim-request@mbunix.mitre.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "OSI Internet Management"}}, -{"pk": 1201, "model": "group.group", "fields": {"charter": "charter-ietf-ositrans", "unused_states": [], "ad": 2372, "parent": null, "list_email": "", "acronym": "ositrans", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "OSI Transition"}}, +{"pk": 1200, "model": "group.group", "fields": {"charter": "charter-ietf-oim", "unused_states": [], "ad": null, "parent": 1157, "list_email": "oim@mbunix.mitre.org", "acronym": "oim", "comments": "", "list_subscribe": "oim-request@mbunix.mitre.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "OSI Internet Management"}}, +{"pk": 1201, "model": "group.group", "fields": {"charter": "charter-ietf-ositrans", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ositrans", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "OSI Transition"}}, {"pk": 1202, "model": "group.group", "fields": {"charter": "charter-ietf-skinstak", "unused_states": [], "ad": null, "parent": 1199, "list_email": "skinstak@ulcc.ac.uk", "acronym": "skinstak", "comments": "Replaced by the Thinosi WG.", "list_subscribe": "skinstak-request@ulcc.ac.uk", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ulcc/skinstak@ulcc.ac.uk", "type": "wg", "name": "OSI Upper-Layer Communications for Applications"}}, -{"pk": 1203, "model": "group.group", "fields": {"charter": "charter-ietf-osix400", "unused_states": [], "ad": 2372, "parent": 1199, "list_email": "ietf-osi-x400@cs.wisc.edu", "acronym": "osix400", "comments": "Superceded by the X.400 Operations working group (x400ops)", "list_subscribe": "ietf-osi-x400-request@cs.wisc.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "janeb.cs.wisc.edu:/pub/archives/ietf-osi-x400", "type": "wg", "name": "OSI X.400"}}, -{"pk": 1204, "model": "group.group", "fields": {"charter": "charter-ietf-pip", "unused_states": [], "ad": 2324, "parent": 1052, "list_email": "pip@thumper.bellcore.com", "acronym": "pip", "comments": "Merged with sip to become the sipp working group.", "list_subscribe": "pip-request@thumper.bellcore.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "thumper.bellcore.com:~/pub/tsuchiya/pip-archive", "type": "wg", "name": "P. Internet Protocol"}}, +{"pk": 1203, "model": "group.group", "fields": {"charter": "charter-ietf-osix400", "unused_states": [], "ad": null, "parent": 1199, "list_email": "ietf-osi-x400@cs.wisc.edu", "acronym": "osix400", "comments": "Superceded by the X.400 Operations working group (x400ops)", "list_subscribe": "ietf-osi-x400-request@cs.wisc.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "janeb.cs.wisc.edu:/pub/archives/ietf-osi-x400", "type": "wg", "name": "OSI X.400"}}, +{"pk": 1204, "model": "group.group", "fields": {"charter": "charter-ietf-pip", "unused_states": [], "ad": null, "parent": 1052, "list_email": "pip@thumper.bellcore.com", "acronym": "pip", "comments": "Merged with sip to become the sipp working group.", "list_subscribe": "pip-request@thumper.bellcore.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "thumper.bellcore.com:~/pub/tsuchiya/pip-archive", "type": "wg", "name": "P. Internet Protocol"}}, {"pk": 1205, "model": "group.group", "fields": {"charter": "charter-ietf-pktway", "unused_states": [], "ad": null, "parent": 1052, "list_email": "pktway@isi.edu", "acronym": "pktway", "comments": "Was names MessageWay (msgway). Changed to PacketWay (pktway) on 8/28/96.", "list_subscribe": "http://WWW.ERC.MsState.Edu/packetway/mail-list.html", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.isi.edu/pktway/pktway.mail", "type": "wg", "name": "PacketWay"}}, {"pk": 1206, "model": "group.group", "fields": {"charter": "charter-ietf-pcc", "unused_states": [], "ad": null, "parent": 1052, "list_email": "ietf-perf@gateway.mitre.org", "acronym": "pcc", "comments": "", "list_subscribe": "ietf-perf-request@gateway.mitre.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Performance and Congestion Control"}}, -{"pk": 1207, "model": "group.group", "fields": {"charter": "charter-ietf-nsfnet", "unused_states": [], "ad": 188, "parent": null, "list_email": "", "acronym": "nsfnet", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Perspectives on the Next Generation of the NSFnet"}}, +{"pk": 1207, "model": "group.group", "fields": {"charter": "charter-ietf-nsfnet", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "nsfnet", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Perspectives on the Next Generation of the NSFnet"}}, {"pk": 1208, "model": "group.group", "fields": {"charter": "charter-ietf-ptopomib", "unused_states": [], "ad": null, "parent": 1193, "list_email": "ptopo@3com.com", "acronym": "ptopomib", "comments": "AD was Harald", "list_subscribe": "ptopo-request@3com.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp ftp.3com.com (login: ptopo, passwd: ptopo)", "type": "wg", "name": "Physical Topology MIB"}}, {"pk": 1209, "model": "group.group", "fields": {"charter": "charter-ietf-ppp", "unused_states": [], "ad": null, "parent": 1052, "list_email": "ietf-ppp@ucdavis.edu", "acronym": "ppp", "comments": "", "list_subscribe": "ietf-ppp-request@ucdavis.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Point-to-Point Protocol"}}, -{"pk": 1210, "model": "group.group", "fields": {"charter": "charter-ietf-pppext", "unused_states": [], "ad": 100664, "parent": 1052, "list_email": "pppext@ietf.org", "acronym": "pppext", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/pppext", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pppext/", "type": "wg", "name": "Point-to-Point Protocol Extensions"}}, -{"pk": 1211, "model": "group.group", "fields": {"charter": "charter-ietf-poised95", "unused_states": [], "ad": 2853, "parent": 1179, "list_email": "poised@tis.com", "acronym": "poised95", "comments": "Rechartered as the Poisson WG.", "list_subscribe": "poised-request@tis.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://tis.com/pub/ietf/poised/poised.mbox", "type": "wg", "name": "Poised 95"}}, +{"pk": 1210, "model": "group.group", "fields": {"charter": "charter-ietf-pppext", "unused_states": [], "ad": null, "parent": 1052, "list_email": "pppext@ietf.org", "acronym": "pppext", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/pppext", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pppext/", "type": "wg", "name": "Point-to-Point Protocol Extensions"}}, +{"pk": 1211, "model": "group.group", "fields": {"charter": "charter-ietf-poised95", "unused_states": [], "ad": null, "parent": 1179, "list_email": "poised@tis.com", "acronym": "poised95", "comments": "Rechartered as the Poisson WG.", "list_subscribe": "poised-request@tis.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://tis.com/pub/ietf/poised/poised.mbox", "type": "wg", "name": "Poised 95"}}, {"pk": 1212, "model": "group.group", "fields": {"charter": "charter-ietf-pop", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-pop@dbc.mtview.ca.us", "acronym": "pop", "comments": "Waiting for the chair to lift a 'hold for SMP' O-Proposed & Start: 6/10/92", "list_subscribe": "ietf-pop-request@dbc.mtview.ca.us", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Post Office Protocol"}}, -{"pk": 1213, "model": "group.group", "fields": {"charter": "charter-ietf-piara", "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "piara", "comments": "1st meeting at Montreal, Canada - 36th IETF June 1996", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Pricing for Internet Addresses and Route Assignmen"}}, -{"pk": 1214, "model": "group.group", "fields": {"charter": "charter-ietf-printjob", "unused_states": [], "ad": 4763, "parent": null, "list_email": "", "acronym": "printjob", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Print Job Management"}}, +{"pk": 1213, "model": "group.group", "fields": {"charter": "charter-ietf-piara", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "piara", "comments": "1st meeting at Montreal, Canada - 36th IETF June 1996", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Pricing for Internet Addresses and Route Assignmen"}}, +{"pk": 1214, "model": "group.group", "fields": {"charter": "charter-ietf-printjob", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "printjob", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Print Job Management"}}, {"pk": 1215, "model": "group.group", "fields": {"charter": "charter-ietf-printmib", "unused_states": [], "ad": null, "parent": 934, "list_email": "pmp@pwg.org", "acronym": "printmib", "comments": "Met as a bof in Houston. Orig-Prop: 1/19/94, start 1/31/94, conclude 3/22/95. Reactivated 11/4/96", "list_subscribe": "majordomo@pwg.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.pwg.org/hypermail/pmp/", "type": "wg", "name": "Printer MIB"}}, {"pk": 1216, "model": "group.group", "fields": {"charter": "charter-ietf-pem", "unused_states": [], "ad": null, "parent": 1260, "list_email": "pem-dev@tis.com", "acronym": "pem", "comments": "", "list_subscribe": "pem-dev-request@tis.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "pem-dev-request@tis.com", "type": "wg", "name": "Privacy-Enhanced Electronic Mail"}}, {"pk": 1217, "model": "group.group", "fields": {"charter": "charter-ietf-pdnrout", "unused_states": [], "ad": null, "parent": 1249, "list_email": "pdn-wg@bbn.com", "acronym": "pdnrout", "comments": "", "list_subscribe": "pdn-request@bbn.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Private Data Network Routing"}}, {"pk": 1218, "model": "group.group", "fields": {"charter": "charter-ietf-pier", "unused_states": [], "ad": null, "parent": 1193, "list_email": "pier@isi.edu", "acronym": "pier", "comments": "1st meeting 34th IETF, Dallas (December 4-8, 1996) mw\r\nAD was Harald", "list_subscribe": "pier-request@isi.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.isi.edu/pier-archive", "type": "wg", "name": "Procedures for Internet/Enterprise Renumbering"}}, -{"pk": 1219, "model": "group.group", "fields": {"charter": "charter-ietf-poised", "unused_states": [], "ad": 2853, "parent": 1179, "list_email": "poised@tis.com", "acronym": "poised", "comments": "POISED was never concluded, but as of the Seattle IETF, it was informally reactivated in doing its 'two-year checkup'.", "list_subscribe": "poised-request@tis.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ietf.cnri.reston.va.us:~/ietf-mail-archive/poised/*", "type": "wg", "name": "Process for Organization of Internet Standards"}}, -{"pk": 1220, "model": "group.group", "fields": {"charter": "charter-ietf-poisson", "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "poised@lists.tislabs.com", "acronym": "poisson", "comments": "Was named Poised95. Renamed with new charter and milestones on 7/25.", "list_subscribe": "poised-request@lists.tislabs.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.tis.com/pub/lists/poised/poised.yymm", "type": "wg", "name": "Process for Organization of Internet Standards ONgoing"}}, -{"pk": 1221, "model": "group.group", "fields": {"charter": "charter-ietf-prottest", "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "prottest", "comments": "1st meeting 32nd IETF Danvers, MA (April 3-7, 1995) mw has now been chartered as the stdguide WG. 10/31/95 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Protocol Testing"}}, +{"pk": 1219, "model": "group.group", "fields": {"charter": "charter-ietf-poised", "unused_states": [], "ad": null, "parent": 1179, "list_email": "poised@tis.com", "acronym": "poised", "comments": "POISED was never concluded, but as of the Seattle IETF, it was informally reactivated in doing its 'two-year checkup'.", "list_subscribe": "poised-request@tis.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ietf.cnri.reston.va.us:~/ietf-mail-archive/poised/*", "type": "wg", "name": "Process for Organization of Internet Standards"}}, +{"pk": 1220, "model": "group.group", "fields": {"charter": "charter-ietf-poisson", "unused_states": [], "ad": null, "parent": 1008, "list_email": "poised@lists.tislabs.com", "acronym": "poisson", "comments": "Was named Poised95. Renamed with new charter and milestones on 7/25.", "list_subscribe": "poised-request@lists.tislabs.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.tis.com/pub/lists/poised/poised.yymm", "type": "wg", "name": "Process for Organization of Internet Standards ONgoing"}}, +{"pk": 1221, "model": "group.group", "fields": {"charter": "charter-ietf-prottest", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "prottest", "comments": "1st meeting 32nd IETF Danvers, MA (April 3-7, 1995) mw has now been chartered as the stdguide WG. 10/31/95 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Protocol Testing"}}, {"pk": 1222, "model": "group.group", "fields": {"charter": "charter-ietf-pint", "unused_states": [], "ad": null, "parent": 1324, "list_email": "pint@lists.bell-labs.com", "acronym": "pint", "comments": "1st meeting at 38th IETF - Memphis, TN", "list_subscribe": "pint-request@lists.bell-labs.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.bell-labs.com/mailing-lists/pint/", "type": "wg", "name": "PSTN and Internet Internetworking"}}, -{"pk": 1223, "model": "group.group", "fields": {"charter": "charter-ietf-pkix", "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "pkix@ietf.org", "acronym": "pkix", "comments": "1st met, 34th IETF Dallas, TX (December 4-8, 1995)", "list_subscribe": "pkix-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pkix/", "type": "wg", "name": "Public-Key Infrastructure (X.509)"}}, +{"pk": 1223, "model": "group.group", "fields": {"charter": "charter-ietf-pkix", "unused_states": [], "ad": null, "parent": 1260, "list_email": "pkix@ietf.org", "acronym": "pkix", "comments": "1st met, 34th IETF Dallas, TX (December 4-8, 1995)", "list_subscribe": "pkix-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pkix/", "type": "wg", "name": "Public-Key Infrastructure (X.509)"}}, {"pk": 1224, "model": "group.group", "fields": {"charter": "charter-ietf-qosr", "unused_states": [], "ad": null, "parent": 1249, "list_email": "qosr@newbridge.com", "acronym": "qosr", "comments": "", "list_subscribe": "qosr-request@newbridge.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "QoS Routing"}}, {"pk": 1225, "model": "group.group", "fields": {"charter": "charter-ietf-quis", "unused_states": [], "ad": null, "parent": 934, "list_email": "quality@naic.nasa.gov", "acronym": "quis", "comments": "1st meeting July 1994/Toronto mw. as of 24 oct 94, going for wg status /jws.", "list_subscribe": "listmanager@naic.nasa.gov", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "listmanager@naic.nasa.gov body=`index quality'", "type": "wg", "name": "Quality Information Services"}}, -{"pk": 1226, "model": "group.group", "fields": {"charter": "charter-ietf-rtl", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "", "acronym": "rtl", "comments": "1st met as BOF 33rd IETF: Stockholm: 17-21 July 1995, jointly under USV and APPS area mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Read the Label"}}, +{"pk": 1226, "model": "group.group", "fields": {"charter": "charter-ietf-rtl", "unused_states": [], "ad": null, "parent": 1346, "list_email": "", "acronym": "rtl", "comments": "1st met as BOF 33rd IETF: Stockholm: 17-21 July 1995, jointly under USV and APPS area mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Read the Label"}}, {"pk": 1227, "model": "group.group", "fields": {"charter": "charter-ietf-realtime", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "realtime", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Realtime Packet Forwarding and Admission Control"}}, {"pk": 1228, "model": "group.group", "fields": {"charter": "charter-ietf-rtfm", "unused_states": [], "ad": null, "parent": 1324, "list_email": "rtfm@auckland.ac.nz", "acronym": "rtfm", "comments": "1st met at 34th IETF Dallas (December 4-8, 1995) mw", "list_subscribe": "majordomo@auckland.ac.nz", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.auckland.ac.nz/pub/rtfm/ml-archive", "type": "wg", "name": "Realtime Traffic Flow Measurement"}}, {"pk": 1229, "model": "group.group", "fields": {"charter": "charter-ietf-receipt", "unused_states": [], "ad": null, "parent": 934, "list_email": "receipt@cs.utk.edu", "acronym": "receipt", "comments": "1st met as BOF: 33rd IETF: Stockholm 17-21 July 1995 mw", "list_subscribe": "receipt-request@cs.utk.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://cs.utk.edu/pub/receipt/mail-archive", "type": "wg", "name": "Receipt Notifications for Internet Mail"}}, -{"pk": 1230, "model": "group.group", "fields": {"charter": "charter-ietf-raidmib", "unused_states": [], "ad": 4763, "parent": null, "list_email": "raidmib-l@netx.com", "acronym": "raidmib", "comments": "1st met as BOF, 34th IETF - Dallas, TX December 4-8, 1995, mw", "list_subscribe": "raidmib-l-request@netx.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Redundant Arrays of Independent Disks MIB"}}, +{"pk": 1230, "model": "group.group", "fields": {"charter": "charter-ietf-raidmib", "unused_states": [], "ad": null, "parent": null, "list_email": "raidmib-l@netx.com", "acronym": "raidmib", "comments": "1st met as BOF, 34th IETF - Dallas, TX December 4-8, 1995, mw", "list_subscribe": "raidmib-l-request@netx.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Redundant Arrays of Independent Disks MIB"}}, {"pk": 1231, "model": "group.group", "fields": {"charter": "charter-ietf-ride", "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "ride", "comments": "1st meeting - 38th IETF - Memphis, TN; 2nd meeting - 39th IETF - Munich, Germany", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Registry Information Database Exchange Formats & P"}}, -{"pk": 1232, "model": "group.group", "fields": {"charter": "charter-ietf-rdbmsmib", "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "rdbmsmib@us.oracle.com", "acronym": "rdbmsmib", "comments": "", "list_subscribe": "rdbmsmib-request@us.oracle.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "gatekeeper.dec.com:~/pub/net/info/ietf", "type": "wg", "name": "Relational Database Management Systems MIB"}}, -{"pk": 1233, "model": "group.group", "fields": {"charter": "charter-ietf-ramp", "unused_states": [], "ad": 2744, "parent": null, "list_email": "", "acronym": "ramp", "comments": "1st IETF Meeting: Seattle: 94-03: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Remote Account Maintenance Protocol"}}, +{"pk": 1232, "model": "group.group", "fields": {"charter": "charter-ietf-rdbmsmib", "unused_states": [], "ad": null, "parent": 1157, "list_email": "rdbmsmib@us.oracle.com", "acronym": "rdbmsmib", "comments": "", "list_subscribe": "rdbmsmib-request@us.oracle.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "gatekeeper.dec.com:~/pub/net/info/ietf", "type": "wg", "name": "Relational Database Management Systems MIB"}}, +{"pk": 1233, "model": "group.group", "fields": {"charter": "charter-ietf-ramp", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ramp", "comments": "1st IETF Meeting: Seattle: 94-03: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Remote Account Maintenance Protocol"}}, {"pk": 1234, "model": "group.group", "fields": {"charter": "charter-ietf-radius", "unused_states": [], "ad": null, "parent": 1193, "list_email": "ietf-radius@livingston.com", "acronym": "radius", "comments": "1st meeting 32nd IETF, Danvers, MA April 3-7, 1995 mw", "list_subscribe": "ietf-radius-request@livingston.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.livingston.com/pub/radius/archive", "type": "wg", "name": "Remote Authentication Dial-In User Service"}}, {"pk": 1235, "model": "group.group", "fields": {"charter": "charter-ietf-remconf", "unused_states": [], "ad": null, "parent": 934, "list_email": "rem-conf@es.net", "acronym": "remconf", "comments": "1st met as bof in Boston. 92-07", "list_subscribe": "rem-conf-request@es.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "nic.es.net:./ietf.rem-conf/rem-conf-archive", "type": "wg", "name": "Remote Conferencing"}}, {"pk": 1236, "model": "group.group", "fields": {"charter": "charter-ietf-remmail", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "remmail", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Remote Mail Protocol"}}, {"pk": 1237, "model": "group.group", "fields": {"charter": "charter-ietf-rmonmib", "unused_states": [], "ad": null, "parent": 1193, "list_email": "rmonmib@ietf.org", "acronym": "rmonmib", "comments": "The group was renamed from rlanmib. Original start date 8/1/90, end date 3/20/92. Mike Erlinger replaced 31 Oct. /jws", "list_subscribe": "http://www.ietf.org/mailman/listinfo/rmonmib", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rmonmib/", "type": "wg", "name": "Remote Network Monitoring"}}, -{"pk": 1238, "model": "group.group", "fields": {"charter": "charter-ietf-tpcint", "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "tpcint", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Remote Printing on Glodal Facsimile Devices"}}, -{"pk": 1239, "model": "group.group", "fields": {"charter": "charter-ietf-resdisc", "unused_states": [], "ad": 188, "parent": null, "list_email": "", "acronym": "resdisc", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Resource Discovery"}}, +{"pk": 1238, "model": "group.group", "fields": {"charter": "charter-ietf-tpcint", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "tpcint", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Remote Printing on Glodal Facsimile Devices"}}, +{"pk": 1239, "model": "group.group", "fields": {"charter": "charter-ietf-resdisc", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "resdisc", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Resource Discovery"}}, {"pk": 1240, "model": "group.group", "fields": {"charter": "charter-ietf-rsvp", "unused_states": [], "ad": null, "parent": 1324, "list_email": "rsvp@isi.edu", "acronym": "rsvp", "comments": "", "list_subscribe": "rsvp-request@isi.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.isi.edu/rsvp/rsvp.mail", "type": "wg", "name": "Resource Reservation Setup Protocol"}}, -{"pk": 1241, "model": "group.group", "fields": {"charter": "charter-ietf-run", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "ietf-run@mailbag.intel.com", "acronym": "run", "comments": "1st meeting: San Jose 12/94 mw. Closed 10/20.95. Reactivated 10/8/96", "list_subscribe": "listserv@mailbag.intel.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.intel.com/pub/ietf-run", "type": "wg", "name": "Responsible Use of the Network"}}, +{"pk": 1241, "model": "group.group", "fields": {"charter": "charter-ietf-run", "unused_states": [], "ad": null, "parent": 1346, "list_email": "ietf-run@mailbag.intel.com", "acronym": "run", "comments": "1st meeting: San Jose 12/94 mw. Closed 10/20.95. Reactivated 10/8/96", "list_subscribe": "listserv@mailbag.intel.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.intel.com/pub/ietf-run", "type": "wg", "name": "Responsible Use of the Network"}}, {"pk": 1242, "model": "group.group", "fields": {"charter": "charter-ietf-rfc1006", "unused_states": [], "ad": null, "parent": null, "list_email": "nosi@sunroof.eng.sun.com", "acronym": "rfc1006", "comments": "1st BOF meeting 33rd IETF/Stockholm 17-21 July 1995 mw", "list_subscribe": "majordomo@sunroof.eng.sun.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "RFC1006bis/ISO TP over IPv6"}}, {"pk": 1243, "model": "group.group", "fields": {"charter": "charter-ietf-ripv2", "unused_states": [], "ad": null, "parent": 1249, "list_email": "ietf-rip@xylogics.com", "acronym": "ripv2", "comments": "Originally chartered 1/23/92, concluded 1/12/93. Rechartered to become RIP 2/28/95", "list_subscribe": "ietf-rip-request@xylogics.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://xylogics.com/gmalkin/rip/rip-arc", "type": "wg", "name": "RIP Version II"}}, {"pk": 1244, "model": "group.group", "fields": {"charter": "charter-ietf-roamops", "unused_states": [], "ad": null, "parent": 1193, "list_email": "roamops@tdmx.rutgers.edu", "acronym": "roamops", "comments": "", "list_subscribe": "roamops-request@tdmx.rutgers.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp-no.rutgers.edu/misc/IETF/roamops", "type": "wg", "name": "Roaming Operations"}}, {"pk": 1245, "model": "group.group", "fields": {"charter": "charter-ietf-rdisc", "unused_states": [], "ad": null, "parent": 1052, "list_email": "gw-discovery@gregorio.stanford.edu", "acronym": "rdisc", "comments": "", "list_subscribe": "gw-discovery-request@gregorio.stanford.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Router Discovery"}}, {"pk": 1246, "model": "group.group", "fields": {"charter": "charter-ietf-rreq", "unused_states": [], "ad": null, "parent": 1249, "list_email": "rreq@isi.edu", "acronym": "rreq", "comments": "Dormant for long time (3/1/93). Original chair - Phil Almquist. Jumpstarted on March 31, 1994", "list_subscribe": "rreq-request@isi.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Router Requirements"}}, -{"pk": 1247, "model": "group.group", "fields": {"charter": "charter-ietf-rreqlist", "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "rreqlist", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Router Requirements Checklist"}}, +{"pk": 1247, "model": "group.group", "fields": {"charter": "charter-ietf-rreqlist", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "rreqlist", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Router Requirements Checklist"}}, {"pk": 1248, "model": "group.group", "fields": {"charter": "charter-ietf-road", "unused_states": [], "ad": null, "parent": 1249, "list_email": "", "acronym": "road", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Routing and Addressing"}}, {"pk": 1250, "model": "group.group", "fields": {"charter": "charter-ietf-rip", "unused_states": [], "ad": null, "parent": 1249, "list_email": "rip@ietf.org", "acronym": "rip", "comments": "Rechartering of the RIPv2 WG", "list_subscribe": "rip-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rip/", "type": "wg", "name": "Routing Information Protocol"}}, {"pk": 1251, "model": "group.group", "fields": {"charter": "charter-ietf-rolc", "unused_states": [], "ad": null, "parent": 1249, "list_email": "rolc@nexen.com", "acronym": "rolc", "comments": "Combined with ipatm to form ION.", "list_subscribe": "rolc-request@nexen.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://cnri.reston.va.us/ietf-mail-archive/rolc/", "type": "wg", "name": "Routing over Large Clouds"}}, @@ -418,36 +418,36 @@ {"pk": 1258, "model": "group.group", "fields": {"charter": "charter-ietf-smime", "unused_states": [], "ad": null, "parent": 1260, "list_email": "smime@ietf.org", "acronym": "smime", "comments": "", "list_subscribe": "smime-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/smime/", "type": "wg", "name": "S/MIME Mail Security"}}, {"pk": 1259, "model": "group.group", "fields": {"charter": "charter-ietf-secsh", "unused_states": [], "ad": null, "parent": 1260, "list_email": "ietf-ssh@netbsd.org", "acronym": "secsh", "comments": "", "list_subscribe": "majordomo@netbsd.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.ietf.org/ietf-mail-archive/secsh/", "type": "wg", "name": "Secure Shell"}}, {"pk": 1261, "model": "group.group", "fields": {"charter": "charter-ietf-secdir", "unused_states": [], "ad": null, "parent": 1260, "list_email": "saag@tis.com", "acronym": "secdir", "comments": "6/7/94 Jeff Schiller closed to form Security Area Directorate. 10/94 Jeff wants SAAG for open meeting, SECDIR for closed. mw", "list_subscribe": "saag-request@tis.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "team", "name": "Security Area Directorate"}}, -{"pk": 1262, "model": "group.group", "fields": {"charter": "charter-ietf-wg-sec", "unused_states": [], "ad": 188, "parent": 1179, "list_email": "", "acronym": "wg-sec", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Security Technology"}}, +{"pk": 1262, "model": "group.group", "fields": {"charter": "charter-ietf-wg-sec", "unused_states": [], "ad": null, "parent": 1179, "list_email": "", "acronym": "wg-sec", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Security Technology"}}, {"pk": 1263, "model": "group.group", "fields": {"charter": "charter-ietf-select", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "select", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Selection Criteria"}}, {"pk": 1265, "model": "group.group", "fields": {"charter": "charter-ietf-svrloc", "unused_states": [], "ad": null, "parent": 1052, "list_email": "srvloc@srvloc.org", "acronym": "svrloc", "comments": "Moved from SAP to INT on 10 May 1994 by JWS.", "list_subscribe": "srvloc-request@srvloc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.srvloc.org/hypermail/index.htm", "type": "wg", "name": "Service Location Protocol"}}, {"pk": 1266, "model": "group.group", "fields": {"charter": "charter-ietf-ssl", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ssl", "comments": "1st met as BOF 33rd IETF: Stockholm: 17-21 July 1995 mw Meet again at 35th IETF, name changed to TLS on 2/24/96 per Jeff Schiller", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Session Layer Security"}}, {"pk": 1267, "model": "group.group", "fields": {"charter": "charter-ietf-whois", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "whois", "comments": "1st meeting at 49th IETF-San Diego, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Whois Protocol"}}, -{"pk": 1268, "model": "group.group", "fields": {"charter": "charter-ietf-sip-o", "unused_states": [], "ad": 2324, "parent": 934, "list_email": "sip@caldera.usc.edu", "acronym": "sip-o", "comments": "SIP Merged with pip to become the sipp working group. Changed to SIP-O to accommodate new WG (Session Initiation Protocol) acronym.", "list_subscribe": "sip-request@caldera.usc.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Simple Internet Protocol"}}, -{"pk": 1269, "model": "group.group", "fields": {"charter": "charter-ietf-sipp", "unused_states": [], "ad": 2515, "parent": 1092, "list_email": "sipp@sunroof.eng.sun.com", "acronym": "sipp", "comments": "merged pip and sip working groups", "list_subscribe": "sipp-request@sunroof.eng.sun.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "parcftp.xerox.com: pub/sipp", "type": "wg", "name": "Simple Internet Protocol Plus"}}, +{"pk": 1268, "model": "group.group", "fields": {"charter": "charter-ietf-sip-o", "unused_states": [], "ad": null, "parent": 934, "list_email": "sip@caldera.usc.edu", "acronym": "sip-o", "comments": "SIP Merged with pip to become the sipp working group. Changed to SIP-O to accommodate new WG (Session Initiation Protocol) acronym.", "list_subscribe": "sip-request@caldera.usc.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Simple Internet Protocol"}}, +{"pk": 1269, "model": "group.group", "fields": {"charter": "charter-ietf-sipp", "unused_states": [], "ad": null, "parent": 1092, "list_email": "sipp@sunroof.eng.sun.com", "acronym": "sipp", "comments": "merged pip and sip working groups", "list_subscribe": "sipp-request@sunroof.eng.sun.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "parcftp.xerox.com: pub/sipp", "type": "wg", "name": "Simple Internet Protocol Plus"}}, {"pk": 1270, "model": "group.group", "fields": {"charter": "charter-ietf-skip", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "skip", "comments": "1st met as BOF 33rd IETF Stockholm 17-21 July, 1995 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Simple Key Management for IP"}}, -{"pk": 1271, "model": "group.group", "fields": {"charter": "charter-ietf-smpframe", "unused_states": [], "ad": 4763, "parent": null, "list_email": "", "acronym": "smpframe", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Simple Management Protocol (SMP) Framework"}}, -{"pk": 1272, "model": "group.group", "fields": {"charter": "charter-ietf-snmp", "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "snmp@psi.com", "acronym": "snmp", "comments": "", "list_subscribe": "snmp-request@psi.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Simple Network Management Protocol"}}, +{"pk": 1271, "model": "group.group", "fields": {"charter": "charter-ietf-smpframe", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "smpframe", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Simple Management Protocol (SMP) Framework"}}, +{"pk": 1272, "model": "group.group", "fields": {"charter": "charter-ietf-snmp", "unused_states": [], "ad": null, "parent": 1157, "list_email": "snmp@psi.com", "acronym": "snmp", "comments": "", "list_subscribe": "snmp-request@psi.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Simple Network Management Protocol"}}, {"pk": 1273, "model": "group.group", "fields": {"charter": "charter-ietf-spki", "unused_states": [], "ad": null, "parent": 1260, "list_email": "spki@c2.net", "acronym": "spki", "comments": "", "list_subscribe": "majordomo@c2.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Simple Public Key Infrastructure"}}, -{"pk": 1274, "model": "group.group", "fields": {"charter": "charter-ietf-ssh", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "ssh@cert.org", "acronym": "ssh", "comments": "Originally concluded 3/5/91.", "list_subscribe": "ssh-request@cert.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://info.cert.org/pub/ietf/ssh", "type": "wg", "name": "Site Security Handbook"}}, -{"pk": 1275, "model": "group.group", "fields": {"charter": "charter-ietf-smibof", "unused_states": [], "ad": 4763, "parent": null, "list_email": "", "acronym": "smibof", "comments": "1st meeting at 36th IETF - Montreal, Canada", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SMI Documentation"}}, +{"pk": 1274, "model": "group.group", "fields": {"charter": "charter-ietf-ssh", "unused_states": [], "ad": null, "parent": 1346, "list_email": "ssh@cert.org", "acronym": "ssh", "comments": "Originally concluded 3/5/91.", "list_subscribe": "ssh-request@cert.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://info.cert.org/pub/ietf/ssh", "type": "wg", "name": "Site Security Handbook"}}, +{"pk": 1275, "model": "group.group", "fields": {"charter": "charter-ietf-smibof", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "smibof", "comments": "1st meeting at 36th IETF - Montreal, Canada", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SMI Documentation"}}, {"pk": 1276, "model": "group.group", "fields": {"charter": "charter-ietf-snadlc", "unused_states": [], "ad": null, "parent": 1249, "list_email": "snadlcmib@cisco.com", "acronym": "snadlc", "comments": "replaced Jeff Hilgeman as chair 2/94 mw", "list_subscribe": "snadlcmib-request@cisco.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNA DLC Services MIB"}}, {"pk": 1277, "model": "group.group", "fields": {"charter": "charter-ietf-snanau", "unused_states": [], "ad": null, "parent": 1249, "list_email": "snanaumib@external.cisco.com", "acronym": "snanau", "comments": "revised charter and milestones received 2/7/94. Original charter in snanau-1.desc.txt. updated 6/3/97 (prev. in snanau-2.desc.txt", "list_subscribe": "snanaumib-request@cisco.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.cisco.com/snanaumib/mail-archive", "type": "wg", "name": "SNA NAU Services MIB"}}, {"pk": 1278, "model": "group.group", "fields": {"charter": "charter-ietf-snapper", "unused_states": [], "ad": null, "parent": null, "list_email": "snapper@cisco.com", "acronym": "snapper", "comments": "", "list_subscribe": "snapper-request@cisco.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNA Peer-to-Peer Networking"}}, -{"pk": 1279, "model": "group.group", "fields": {"charter": "charter-ietf-snamib", "unused_states": [], "ad": 4763, "parent": null, "list_email": "snanaumib@thumper.bellcore.com", "acronym": "snamib", "comments": "", "list_subscribe": "snanaumib-request@thumper.bellcore.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNA Systems Management"}}, -{"pk": 1280, "model": "group.group", "fields": {"charter": "charter-ietf-snmp-ng", "unused_states": [], "ad": 2324, "parent": 1190, "list_email": "snmp-ng@tis.com", "acronym": "snmp-ng", "comments": "", "list_subscribe": "snmp-ng-request@tis.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.tis.com/pub/ietf/snmp-ng", "type": "wg", "name": "SNMP - Next Generation"}}, -{"pk": 1281, "model": "group.group", "fields": {"charter": "charter-ietf-snmpagen", "unused_states": [], "ad": 4763, "parent": null, "list_email": "", "acronym": "snmpagen", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNMP Agent Description"}}, +{"pk": 1279, "model": "group.group", "fields": {"charter": "charter-ietf-snamib", "unused_states": [], "ad": null, "parent": null, "list_email": "snanaumib@thumper.bellcore.com", "acronym": "snamib", "comments": "", "list_subscribe": "snanaumib-request@thumper.bellcore.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNA Systems Management"}}, +{"pk": 1280, "model": "group.group", "fields": {"charter": "charter-ietf-snmp-ng", "unused_states": [], "ad": null, "parent": 1190, "list_email": "snmp-ng@tis.com", "acronym": "snmp-ng", "comments": "", "list_subscribe": "snmp-ng-request@tis.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.tis.com/pub/ietf/snmp-ng", "type": "wg", "name": "SNMP - Next Generation"}}, +{"pk": 1281, "model": "group.group", "fields": {"charter": "charter-ietf-snmpagen", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "snmpagen", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNMP Agent Description"}}, {"pk": 1282, "model": "group.group", "fields": {"charter": "charter-ietf-agentx", "unused_states": [], "ad": null, "parent": 1193, "list_email": "agentx@ietf.org", "acronym": "agentx", "comments": "Old email archive at: ftp://ftp.ietf.org/ietf-mail-archive/agentx/", "list_subscribe": "agentx-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/working-groups/agentx/current/maillist.html", "type": "wg", "name": "SNMP Agent Extensibility"}}, -{"pk": 1283, "model": "group.group", "fields": {"charter": "charter-ietf-sam", "unused_states": [], "ad": 4763, "parent": null, "list_email": "", "acronym": "sam", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNMP Application Monitoring"}}, -{"pk": 1284, "model": "group.group", "fields": {"charter": "charter-ietf-snmpauth", "unused_states": [], "ad": 4763, "parent": 1260, "list_email": "awg@bitsy.mit.edu", "acronym": "snmpauth", "comments": "This group has died in a dishonorable state.", "list_subscribe": "awg-request@bitsy.mit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNMP Authentication"}}, -{"pk": 1285, "model": "group.group", "fields": {"charter": "charter-ietf-devdisc", "unused_states": [], "ad": 4763, "parent": null, "list_email": "", "acronym": "devdisc", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNMP Device Discovery"}}, +{"pk": 1283, "model": "group.group", "fields": {"charter": "charter-ietf-sam", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "sam", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNMP Application Monitoring"}}, +{"pk": 1284, "model": "group.group", "fields": {"charter": "charter-ietf-snmpauth", "unused_states": [], "ad": null, "parent": 1260, "list_email": "awg@bitsy.mit.edu", "acronym": "snmpauth", "comments": "This group has died in a dishonorable state.", "list_subscribe": "awg-request@bitsy.mit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNMP Authentication"}}, +{"pk": 1285, "model": "group.group", "fields": {"charter": "charter-ietf-devdisc", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "devdisc", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNMP Device Discovery"}}, {"pk": 1286, "model": "group.group", "fields": {"charter": "charter-ietf-mpsnmp", "unused_states": [], "ad": null, "parent": 1157, "list_email": "snmp-foo@thumper.bellcore.com", "acronym": "mpsnmp", "comments": "", "list_subscribe": "snmp-foo-request@thumper.bellcore.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "thumper.bellcore.com:~/pub/snmp-foo/archive", "type": "wg", "name": "SNMP Over a Multi-Protocol Internet"}}, -{"pk": 1287, "model": "group.group", "fields": {"charter": "charter-ietf-snmpxns", "unused_states": [], "ad": 4763, "parent": null, "list_email": "", "acronym": "snmpxns", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNMP Over XNS"}}, +{"pk": 1287, "model": "group.group", "fields": {"charter": "charter-ietf-snmpxns", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "snmpxns", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNMP Over XNS"}}, {"pk": 1288, "model": "group.group", "fields": {"charter": "charter-ietf-snmpsec", "unused_states": [], "ad": null, "parent": 1260, "list_email": "snmp-sec-dev@tis.com", "acronym": "snmpsec", "comments": "The Group is continuing the work of the SNMP authentication WG.", "list_subscribe": "snmp-sec-dev-request@tis.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "snmp-sec-dev-request@tis.com", "type": "wg", "name": "SNMP Security"}}, {"pk": 1289, "model": "group.group", "fields": {"charter": "charter-ietf-snmpseci", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "snmpseci", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNMP Security Implementors"}}, -{"pk": 1290, "model": "group.group", "fields": {"charter": "charter-ietf-snmpv2", "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "snmpv2@tis.com", "acronym": "snmpv2", "comments": "orig. prop. 8/5/92, iesg 9/1/92, start 9/27/92, end 5/3/93", "list_subscribe": "snmpv2-request@tis.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.tis.com/pub/ietf/snmpv2", "type": "wg", "name": "SNMP Version 2"}}, +{"pk": 1290, "model": "group.group", "fields": {"charter": "charter-ietf-snmpv2", "unused_states": [], "ad": null, "parent": 1157, "list_email": "snmpv2@tis.com", "acronym": "snmpv2", "comments": "orig. prop. 8/5/92, iesg 9/1/92, start 9/27/92, end 5/3/93", "list_subscribe": "snmpv2-request@tis.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.tis.com/pub/ietf/snmpv2", "type": "wg", "name": "SNMP Version 2"}}, {"pk": 1291, "model": "group.group", "fields": {"charter": "charter-ietf-snmpv3", "unused_states": [], "ad": null, "parent": 1193, "list_email": "snmpv3@lists.tislabs.com", "acronym": "snmpv3", "comments": "", "list_subscribe": "snmpv3-request@lists.tislabs.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.tislabs.com/pub/ietf/snmpv3", "type": "wg", "name": "SNMP Version 3"}}, -{"pk": 1292, "model": "group.group", "fields": {"charter": "charter-ietf-mibcomp", "unused_states": [], "ad": 4763, "parent": null, "list_email": "", "acronym": "mibcomp", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNMPMIB Compiler"}}, +{"pk": 1292, "model": "group.group", "fields": {"charter": "charter-ietf-mibcomp", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "mibcomp", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SNMPMIB Compiler"}}, {"pk": 1293, "model": "group.group", "fields": {"charter": "charter-ietf-sdr", "unused_states": [], "ad": null, "parent": 1249, "list_email": "sdrp@catarina.usc.edu", "acronym": "sdr", "comments": "was originally formed as Source Demand Routing Protocol (sdrp)", "list_subscribe": "sdrp-request@catarina.usc.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://catarina.usc.edu/pub/sdrp", "type": "wg", "name": "Source Demand Routing"}}, {"pk": 1294, "model": "group.group", "fields": {"charter": "charter-ietf-shr", "unused_states": [], "ad": null, "parent": null, "list_email": "ietf-hosts@nnsc.nsf.net", "acronym": "shr", "comments": "", "list_subscribe": "ietf-hosts-request@nnsc.nsf.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Special Host Requirements"}}, {"pk": 1295, "model": "group.group", "fields": {"charter": "charter-ietf-stif", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "stif", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Structured Text Interchange Format"}}, @@ -460,31 +460,31 @@ {"pk": 1302, "model": "group.group", "fields": {"charter": "charter-ietf-tcpsat", "unused_states": [], "ad": null, "parent": 1324, "list_email": "tcpsat@grc.nasa.gov", "acronym": "tcpsat", "comments": "1st meeting at 38th IETF - Memphis, TN", "list_subscribe": "majordomo@grc.nasa.gov", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://tcpsat.grc.nasa.gov/tcpsat/mail.html", "type": "wg", "name": "TCP Over Satellite"}}, {"pk": 1303, "model": "group.group", "fields": {"charter": "charter-ietf-tcpfix", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "tcpfix", "comments": "1st meeting, 34th IETF: Dallas, TX December 4-8, 1995 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "TCP Short-Term Problems"}}, {"pk": 1304, "model": "group.group", "fields": {"charter": "charter-ietf-tuba", "unused_states": [], "ad": null, "parent": 1052, "list_email": "tuba@lanl.gov", "acronym": "tuba", "comments": "", "list_subscribe": "tuba-request@lanl.gov", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "TCP/UDP Over CLNP-Addressed Networks"}}, -{"pk": 1305, "model": "group.group", "fields": {"charter": "charter-ietf-telework", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "", "acronym": "telework", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Telecommuting"}}, +{"pk": 1305, "model": "group.group", "fields": {"charter": "charter-ietf-telework", "unused_states": [], "ad": null, "parent": 1346, "list_email": "", "acronym": "telework", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Telecommuting"}}, {"pk": 1306, "model": "group.group", "fields": {"charter": "charter-ietf-teleconf", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "teleconf", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Teleconferencing"}}, {"pk": 1307, "model": "group.group", "fields": {"charter": "charter-ietf-telarch", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "telarch", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Teleconferencing Architecture"}}, {"pk": 1308, "model": "group.group", "fields": {"charter": "charter-ietf-telnet", "unused_states": [], "ad": null, "parent": 934, "list_email": "telnet-ietf@cray.com", "acronym": "telnet", "comments": "", "list_subscribe": "telnet-ietf-request@cray.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "TELNET"}}, {"pk": 1309, "model": "group.group", "fields": {"charter": "charter-ietf-telnetlm", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "telnetlm", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "TELNET Linemode Working Group"}}, {"pk": 1310, "model": "group.group", "fields": {"charter": "charter-ietf-tn3270e", "unused_states": [], "ad": null, "parent": 934, "list_email": "tn3270e@list.nih.gov", "acronym": "tn3270e", "comments": "pro 4/13. iesg 4/26. start 4/29/93. concluded on 6/25/95. Reactivated for SJ-2 meeting.", "list_subscribe": "listserv@list.nih.gov", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "listserv@list.nih.gov", "type": "wg", "name": "Telnet TN3270 Enhancements"}}, -{"pk": 1311, "model": "group.group", "fields": {"charter": "charter-ietf-termacct", "unused_states": [], "ad": 4763, "parent": null, "list_email": "auth-acct@angband.stanford.edu", "acronym": "termacct", "comments": "1st meeting 22nd IETF, Santa Fe November 18-22, 1991 mw", "list_subscribe": "auth-acct-request@angband.stanford.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Terminal Server Accounting and Authentication"}}, -{"pk": 1312, "model": "group.group", "fields": {"charter": "charter-ietf-testing", "unused_states": [], "ad": 2324, "parent": 934, "list_email": "dod-test@cavebear.com", "acronym": "testing", "comments": "1st meeting Toronto IETF, mw", "list_subscribe": "dod-test-request@cavebear.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Testing"}}, +{"pk": 1311, "model": "group.group", "fields": {"charter": "charter-ietf-termacct", "unused_states": [], "ad": null, "parent": null, "list_email": "auth-acct@angband.stanford.edu", "acronym": "termacct", "comments": "1st meeting 22nd IETF, Santa Fe November 18-22, 1991 mw", "list_subscribe": "auth-acct-request@angband.stanford.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Terminal Server Accounting and Authentication"}}, +{"pk": 1312, "model": "group.group", "fields": {"charter": "charter-ietf-testing", "unused_states": [], "ad": null, "parent": 934, "list_email": "dod-test@cavebear.com", "acronym": "testing", "comments": "1st meeting Toronto IETF, mw", "list_subscribe": "dod-test-request@cavebear.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Testing"}}, {"pk": 1313, "model": "group.group", "fields": {"charter": "charter-ietf-tftpexts", "unused_states": [], "ad": null, "parent": 934, "list_email": "tftpexts@hpindsh.cup.hp.com", "acronym": "tftpexts", "comments": "1st meeting December 1994 IETF, San Jose. mw", "list_subscribe": "tftpexts-request@hpindsh.cup.hp.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "onet2.cup.hp.com:/dist/tftpexts/tftpexts_archive", "type": "wg", "name": "TFTP Extensions"}}, -{"pk": 1314, "model": "group.group", "fields": {"charter": "charter-ietf-arts", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "", "acronym": "arts", "comments": "5/95 became the Humanities and Arts WG (harts) mw see separate record.", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "The Arts: Sharing Center Stage on the Internet"}}, +{"pk": 1314, "model": "group.group", "fields": {"charter": "charter-ietf-arts", "unused_states": [], "ad": null, "parent": 1346, "list_email": "", "acronym": "arts", "comments": "5/95 became the Humanities and Arts WG (harts) mw see separate record.", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "The Arts: Sharing Center Stage on the Internet"}}, {"pk": 1315, "model": "group.group", "fields": {"charter": "charter-ietf-2000", "unused_states": [], "ad": null, "parent": 1193, "list_email": "2000@nic.surfnet.nl", "acronym": "2000", "comments": "gopher://HEARN.nic.SURF net.nl:70/11/1.%20LISTSERVs%20public %20archives%20on%20HEARN.nic.SURFnet. NL/2000", "list_subscribe": "listserv@nic.surfnet.nl", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://listserv.surfnet.nl/archives/2000.html", "type": "wg", "name": "The Internet and the Millennium Problem"}}, -{"pk": 1316, "model": "group.group", "fields": {"charter": "charter-ietf-trmon", "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "rmonmib@lexcel.com", "acronym": "trmon", "comments": "", "list_subscribe": "rmonmib-request@lexcel.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Token Ring Remote Monitoring"}}, -{"pk": 1317, "model": "group.group", "fields": {"charter": "charter-ietf-tpix", "unused_states": [], "ad": 2324, "parent": 1052, "list_email": "tpix@world.std.com", "acronym": "tpix", "comments": "Not really concluded. tpix was changed to catnip", "list_subscribe": "tpix-request@world.std.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "world.std.com:~/pub/tpix/*", "type": "wg", "name": "TP/IX"}}, +{"pk": 1316, "model": "group.group", "fields": {"charter": "charter-ietf-trmon", "unused_states": [], "ad": null, "parent": 1157, "list_email": "rmonmib@lexcel.com", "acronym": "trmon", "comments": "", "list_subscribe": "rmonmib-request@lexcel.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Token Ring Remote Monitoring"}}, +{"pk": 1317, "model": "group.group", "fields": {"charter": "charter-ietf-tpix", "unused_states": [], "ad": null, "parent": 1052, "list_email": "tpix@world.std.com", "acronym": "tpix", "comments": "Not really concluded. tpix was changed to catnip", "list_subscribe": "tpix-request@world.std.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "world.std.com:~/pub/tpix/*", "type": "wg", "name": "TP/IX"}}, {"pk": 1318, "model": "group.group", "fields": {"charter": "charter-ietf-tracerte", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "tracerte", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Traceroute"}}, -{"pk": 1319, "model": "group.group", "fields": {"charter": "charter-ietf-trafchar", "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "trafchar", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Traffic Collection, Measurement & Characterization"}}, +{"pk": 1319, "model": "group.group", "fields": {"charter": "charter-ietf-trafchar", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "trafchar", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Traffic Collection, Measurement & Characterization"}}, {"pk": 1320, "model": "group.group", "fields": {"charter": "charter-ietf-tip", "unused_states": [], "ad": null, "parent": 934, "list_email": "tip@tandem.com", "acronym": "tip", "comments": "1st meeting - 38th IETF, Memphis, TN; 2nd meeting - 39th IETF, Munich, Germany", "list_subscribe": "listserv@tandem.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Transaction Internet Protocol"}}, {"pk": 1321, "model": "group.group", "fields": {"charter": "charter-ietf-ttcp", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "ttcp", "comments": "First meeting 35th IETF - Los Angeles, CA - March 1996", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Transaction TCP"}}, -{"pk": 1322, "model": "group.group", "fields": {"charter": "charter-ietf-tacit", "unused_states": [], "ad": 2324, "parent": null, "list_email": "", "acronym": "tacit", "comments": "1st IETF Meeting: Seattle: 94-03: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Transition and Coexistence Including Testing"}}, -{"pk": 1323, "model": "group.group", "fields": {"charter": "charter-ietf-transmib", "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "trans-wg@nisc.nyser.net", "acronym": "transmib", "comments": "", "list_subscribe": "trans-wg-request@nisc.nyser.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Transmission Mib"}}, +{"pk": 1322, "model": "group.group", "fields": {"charter": "charter-ietf-tacit", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "tacit", "comments": "1st IETF Meeting: Seattle: 94-03: BOF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Transition and Coexistence Including Testing"}}, +{"pk": 1323, "model": "group.group", "fields": {"charter": "charter-ietf-transmib", "unused_states": [], "ad": null, "parent": 1157, "list_email": "trans-wg@nisc.nyser.net", "acronym": "transmib", "comments": "", "list_subscribe": "trans-wg-request@nisc.nyser.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Transmission Mib"}}, {"pk": 1325, "model": "group.group", "fields": {"charter": "charter-ietf-tsvdir", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "tsvdir", "comments": "1st met: 34th IETF: Dallas, TX December 4-8, 1995 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "team", "name": "Transport Area Directorate Open Meeting"}}, -{"pk": 1326, "model": "group.group", "fields": {"charter": "charter-ietf-tls", "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "tls@ietf.org", "acronym": "tls", "comments": "Was formerly called SSL", "list_subscribe": "https://www.ietf.org/mailman/listinfo/tls", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/tls/", "type": "wg", "name": "Transport Layer Security"}}, -{"pk": 1327, "model": "group.group", "fields": {"charter": "charter-ietf-tadmin", "unused_states": [], "ad": 188, "parent": null, "list_email": "", "acronym": "tadmin", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Trusted Administration"}}, +{"pk": 1326, "model": "group.group", "fields": {"charter": "charter-ietf-tls", "unused_states": [], "ad": null, "parent": 1260, "list_email": "tls@ietf.org", "acronym": "tls", "comments": "Was formerly called SSL", "list_subscribe": "https://www.ietf.org/mailman/listinfo/tls", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/tls/", "type": "wg", "name": "Transport Layer Security"}}, +{"pk": 1327, "model": "group.group", "fields": {"charter": "charter-ietf-tadmin", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "tadmin", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Trusted Administration"}}, {"pk": 1328, "model": "group.group", "fields": {"charter": "charter-ietf-tnfs", "unused_states": [], "ad": null, "parent": 1324, "list_email": "tnfs@wdl1.wdl.loral.com", "acronym": "tnfs", "comments": "Moved from SAP to SEC on 10 May 1994 by JWS. This group began in TSIG.", "list_subscribe": "tnfs-request@wdl1.wdl.loral.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "archive-server@wdl1.wdl.loral.com", "type": "wg", "name": "Trusted Network File Systems"}}, -{"pk": 1329, "model": "group.group", "fields": {"charter": "charter-ietf-tsess", "unused_states": [], "ad": 188, "parent": null, "list_email": "", "acronym": "tsess", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Trusted Sessions"}}, -{"pk": 1330, "model": "group.group", "fields": {"charter": "charter-ietf-txwg", "unused_states": [], "ad": 188, "parent": null, "list_email": "", "acronym": "txwg", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Trusted X"}}, +{"pk": 1329, "model": "group.group", "fields": {"charter": "charter-ietf-tsess", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "tsess", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Trusted Sessions"}}, +{"pk": 1330, "model": "group.group", "fields": {"charter": "charter-ietf-txwg", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "txwg", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Trusted X"}}, {"pk": 1331, "model": "group.group", "fields": {"charter": "charter-ietf-tcoord", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "tcoord", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "TSIG/IETF Coordination"}}, {"pk": 1332, "model": "group.group", "fields": {"charter": "charter-ietf-usm", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "usm", "comments": "1st meeting in Los Angeles, CA - 35th IETF", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Ubiquitous Secure Mail"}}, {"pk": 1333, "model": "group.group", "fields": {"charter": "charter-ietf-ucs", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "ucs", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "UCS Character Set"}}, @@ -495,24 +495,24 @@ {"pk": 1338, "model": "group.group", "fields": {"charter": "charter-ietf-url", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "url", "comments": "1st meeting at 37th IETF - San Jose, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Uniform Resource Locators"}}, {"pk": 1339, "model": "group.group", "fields": {"charter": "charter-ietf-urn", "unused_states": [], "ad": null, "parent": 934, "list_email": "urn-ietf@lists.netsol.com", "acronym": "urn", "comments": "1st met as BOF, 34th IETF, Dallas, TX Decembe4 4-8, 1995 mw", "list_subscribe": "listserv@lists.netsol.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.netsol.com/archives/urn-ietf.html", "type": "wg", "name": "Uniform Resource Names"}}, {"pk": 1340, "model": "group.group", "fields": {"charter": "charter-ietf-upsmib", "unused_states": [], "ad": null, "parent": 1193, "list_email": "ups-mib@cs.utk.edu", "acronym": "upsmib", "comments": "O-Proposed/IESG: 9/25/92. O-Start 10/5/92. Conclude 5/24/94", "list_subscribe": "ups-mib-request@cs.utk.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ucs.utk.edu:~/pub/ups-mib/mail-archive", "type": "wg", "name": "Uninterruptible Power Supply"}}, -{"pk": 1341, "model": "group.group", "fields": {"charter": "charter-ietf-udi", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "", "acronym": "udi", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Universal Document Identifiers"}}, -{"pk": 1342, "model": "group.group", "fields": {"charter": "charter-ietf-ucp", "unused_states": [], "ad": 2324, "parent": null, "list_email": "ucp@nic.near.net", "acronym": "ucp", "comments": "", "list_subscribe": "ucp-request@nic.near.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "User Connectivity"}}, -{"pk": 1343, "model": "group.group", "fields": {"charter": "charter-ietf-userdoc", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "user-doc@nnsc.nsf.net", "acronym": "userdoc", "comments": "", "list_subscribe": "user-doc-request@nnsc.nsf.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "User Documents"}}, -{"pk": 1344, "model": "group.group", "fields": {"charter": "charter-ietf-userdoc2", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "user-doc@merit.edu", "acronym": "userdoc2", "comments": "", "list_subscribe": "user-doc-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "User Documents Revisions"}}, -{"pk": 1345, "model": "group.group", "fields": {"charter": "charter-ietf-uswg", "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "uswg@isc.org", "acronym": "uswg", "comments": "", "list_subscribe": "uswg-request@isc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.isc.org/ml-archives/uswg/2000/maillist.html", "type": "wg", "name": "User Services"}}, -{"pk": 1347, "model": "group.group", "fields": {"charter": "charter-ietf-usac", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "", "acronym": "usac", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "team", "name": "User Services Area Council"}}, -{"pk": 1348, "model": "group.group", "fields": {"charter": "charter-ietf-vrrp", "unused_states": [], "ad": 104198, "parent": 1249, "list_email": "vrrp@ietf.org", "acronym": "vrrp", "comments": "1st meeting at 38th IETF - Memphis, TN", "list_subscribe": "vrrp-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/vrrp/", "type": "wg", "name": "Virtual Router Redundancy Protocol"}}, +{"pk": 1341, "model": "group.group", "fields": {"charter": "charter-ietf-udi", "unused_states": [], "ad": null, "parent": 1346, "list_email": "", "acronym": "udi", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Universal Document Identifiers"}}, +{"pk": 1342, "model": "group.group", "fields": {"charter": "charter-ietf-ucp", "unused_states": [], "ad": null, "parent": null, "list_email": "ucp@nic.near.net", "acronym": "ucp", "comments": "", "list_subscribe": "ucp-request@nic.near.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "User Connectivity"}}, +{"pk": 1343, "model": "group.group", "fields": {"charter": "charter-ietf-userdoc", "unused_states": [], "ad": null, "parent": 1346, "list_email": "user-doc@nnsc.nsf.net", "acronym": "userdoc", "comments": "", "list_subscribe": "user-doc-request@nnsc.nsf.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "User Documents"}}, +{"pk": 1344, "model": "group.group", "fields": {"charter": "charter-ietf-userdoc2", "unused_states": [], "ad": null, "parent": 1346, "list_email": "user-doc@merit.edu", "acronym": "userdoc2", "comments": "", "list_subscribe": "user-doc-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "User Documents Revisions"}}, +{"pk": 1345, "model": "group.group", "fields": {"charter": "charter-ietf-uswg", "unused_states": [], "ad": null, "parent": 1008, "list_email": "uswg@isc.org", "acronym": "uswg", "comments": "", "list_subscribe": "uswg-request@isc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.isc.org/ml-archives/uswg/2000/maillist.html", "type": "wg", "name": "User Services"}}, +{"pk": 1347, "model": "group.group", "fields": {"charter": "charter-ietf-usac", "unused_states": [], "ad": null, "parent": 1346, "list_email": "", "acronym": "usac", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "team", "name": "User Services Area Council"}}, +{"pk": 1348, "model": "group.group", "fields": {"charter": "charter-ietf-vrrp", "unused_states": [], "ad": null, "parent": 1249, "list_email": "vrrp@ietf.org", "acronym": "vrrp", "comments": "1st meeting at 38th IETF - Memphis, TN", "list_subscribe": "vrrp-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/vrrp/", "type": "wg", "name": "Virtual Router Redundancy Protocol"}}, {"pk": 1349, "model": "group.group", "fields": {"charter": "charter-ietf-vtp", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "vtp", "comments": "1st meeting at 37th IETF - San Jose, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Virtual Tunneling Protocol BOF"}}, {"pk": 1350, "model": "group.group", "fields": {"charter": "charter-ietf-vac", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "vac", "comments": "1st meeting 34th IETF Dallas, December 4-8, 1995 mw", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Voluntary Access Control"}}, -{"pk": 1351, "model": "group.group", "fields": {"charter": "charter-ietf-wais", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "", "acronym": "wais", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "WAIS and Directory Integration"}}, +{"pk": 1351, "model": "group.group", "fields": {"charter": "charter-ietf-wais", "unused_states": [], "ad": null, "parent": 1346, "list_email": "", "acronym": "wais", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "WAIS and Directory Integration"}}, {"pk": 1352, "model": "group.group", "fields": {"charter": "charter-ietf-index", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "index", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Web Indexing and Related Issues"}}, {"pk": 1353, "model": "group.group", "fields": {"charter": "charter-ietf-wts", "unused_states": [], "ad": null, "parent": 1260, "list_email": "www-security@nsmx.rutgers.edu", "acronym": "wts", "comments": "", "list_subscribe": "www-security-request@nsmx.rutgers.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www-ns.rutgers.edu/www-security", "type": "wg", "name": "Web Transaction Security"}}, {"pk": 1354, "model": "group.group", "fields": {"charter": "charter-ietf-atminfo", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "atminfo", "comments": "One time BOF at Houston to provide informational update/status on the world of ATM", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Whither ATM - an update"}}, -{"pk": 1355, "model": "group.group", "fields": {"charter": "charter-ietf-wnils", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "ietf-wnils@ucdavis.edu", "acronym": "wnils", "comments": "", "list_subscribe": "ietf-wnils-request@ucdavis.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ucdavis.edu/archive/wnils", "type": "wg", "name": "Whois and Network Information Lookup Service"}}, -{"pk": 1356, "model": "group.group", "fields": {"charter": "charter-ietf-wg-char", "unused_states": [], "ad": 188, "parent": 1179, "list_email": "", "acronym": "wg-char", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Working Group on International Character Sets"}}, -{"pk": 1357, "model": "group.group", "fields": {"charter": "charter-ietf-www", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "", "acronym": "www", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "World-Wide Web"}}, +{"pk": 1355, "model": "group.group", "fields": {"charter": "charter-ietf-wnils", "unused_states": [], "ad": null, "parent": 1346, "list_email": "ietf-wnils@ucdavis.edu", "acronym": "wnils", "comments": "", "list_subscribe": "ietf-wnils-request@ucdavis.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ucdavis.edu/archive/wnils", "type": "wg", "name": "Whois and Network Information Lookup Service"}}, +{"pk": 1356, "model": "group.group", "fields": {"charter": "charter-ietf-wg-char", "unused_states": [], "ad": null, "parent": 1179, "list_email": "", "acronym": "wg-char", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Working Group on International Character Sets"}}, +{"pk": 1357, "model": "group.group", "fields": {"charter": "charter-ietf-www", "unused_states": [], "ad": null, "parent": 1346, "list_email": "", "acronym": "www", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "World-Wide Web"}}, {"pk": 1358, "model": "group.group", "fields": {"charter": "charter-ietf-webdav", "unused_states": [], "ad": null, "parent": 934, "list_email": "w3c-dist-auth@w3.org", "acronym": "webdav", "comments": "", "list_subscribe": "w3c-dist-auth-request@w3.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.w3.org/Archives/Public/w3c-dist-auth/", "type": "wg", "name": "WWW Distributed Authoring and Versioning"}}, -{"pk": 1359, "model": "group.group", "fields": {"charter": "charter-ietf-x25mib", "unused_states": [], "ad": 4763, "parent": 1157, "list_email": "x25mib@dg-rtp.dg.com", "acronym": "x25mib", "comments": "", "list_subscribe": "x25mib-request@dg-rtp.dg.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "dg-rtp.dg.com:~/x25mib/Current.Mail", "type": "wg", "name": "X.25 Management Information Base"}}, +{"pk": 1359, "model": "group.group", "fields": {"charter": "charter-ietf-x25mib", "unused_states": [], "ad": null, "parent": 1157, "list_email": "x25mib@dg-rtp.dg.com", "acronym": "x25mib", "comments": "", "list_subscribe": "x25mib-request@dg-rtp.dg.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "dg-rtp.dg.com:~/x25mib/Current.Mail", "type": "wg", "name": "X.25 Management Information Base"}}, {"pk": 1360, "model": "group.group", "fields": {"charter": "charter-ietf-x400ops", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-osi-x400ops@cs.wisc.edu", "acronym": "x400ops", "comments": "", "list_subscribe": "ietf-osi-x400ops-request@cs.wisc.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "X.400 Operations"}}, {"pk": 1363, "model": "group.group", "fields": {"charter": "charter-ietf-ldapext", "unused_states": [], "ad": null, "parent": 934, "list_email": "ldapext@ietf.org", "acronym": "ldapext", "comments": "", "list_subscribe": "https://www1.ietf.org/mailman/listinfo/ldapext", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ldapext/", "type": "wg", "name": "LDAP Extension"}}, {"pk": 1364, "model": "group.group", "fields": {"charter": "charter-ietf-dirdep", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "dirdep", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Directory Deployment"}}, @@ -529,7 +529,7 @@ {"pk": 1375, "model": "group.group", "fields": {"charter": "charter-ietf-adapts", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "adapts", "comments": "1st meeting at 40th IETF-Washington,DC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Adaptive Applications Support"}}, {"pk": 1376, "model": "group.group", "fields": {"charter": "charter-ietf-vpn", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "vpn", "comments": "1st meeting at 40th IETF-Washington, DC; 2nd meeting at 43rd IETF-Orlando, FL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Virtual Private Networking"}}, {"pk": 1377, "model": "group.group", "fields": {"charter": "charter-ietf-adsl", "unused_states": [], "ad": null, "parent": 1052, "list_email": "adsl@xlist.agcs.com", "acronym": "adsl", "comments": "", "list_subscribe": "mgr@xlist.agcs.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Asymmetric Digital Subscriber Line"}}, -{"pk": 1378, "model": "group.group", "fields": {"charter": "charter-ietf-webpriv", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "", "acronym": "webpriv", "comments": "1st Meeting - 40th IETF, Washington", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Web User Privacy: Expectations & Threats"}}, +{"pk": 1378, "model": "group.group", "fields": {"charter": "charter-ietf-webpriv", "unused_states": [], "ad": null, "parent": 1346, "list_email": "", "acronym": "webpriv", "comments": "1st Meeting - 40th IETF, Washington", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Web User Privacy: Expectations & Threats"}}, {"pk": 1379, "model": "group.group", "fields": {"charter": "charter-ietf-mnnp", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "mnnp", "comments": "1st meeting-40th IETF-Washington", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Multicast NetNews Protocol"}}, {"pk": 1381, "model": "group.group", "fields": {"charter": "charter-ietf-malloc", "unused_states": [], "ad": null, "parent": 1324, "list_email": "malloc@ietf.org", "acronym": "malloc", "comments": "1st meeting-40th IETF, Washington, DC", "list_subscribe": "https://www1.ietf.org/mailman/listinfo/malloc/", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.ietf.org/ietf-mail-archive/malloc/", "type": "wg", "name": "Multicast-Address Allocation"}}, {"pk": 1382, "model": "group.group", "fields": {"charter": "charter-ietf-posse", "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "posse", "comments": "1st meeting at 40th IETF, Washington, DC\r\nAD was Harald", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Packet Over SONET/SDH Examination"}}, @@ -539,31 +539,31 @@ {"pk": 1386, "model": "group.group", "fields": {"charter": "charter-ietf-cidf", "unused_states": [], "ad": null, "parent": 1260, "list_email": "cidf@cs.ucdavis.edu", "acronym": "cidf", "comments": "1st meeting at 41st IETF-Los Angeles, CA", "list_subscribe": "cidf-request@cs.ucdavis.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Common Intrusion Detection Framework"}}, {"pk": 1387, "model": "group.group", "fields": {"charter": "charter-ietf-ecn", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "ecn", "comments": "1st meeting at 41st IETF-Los Angeles, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Explicit Congestion Notification"}}, {"pk": 1388, "model": "group.group", "fields": {"charter": "charter-ietf-diffserv", "unused_states": [], "ad": null, "parent": 1324, "list_email": "diffserv@ietf.org", "acronym": "diffserv", "comments": "", "list_subscribe": "diffserv-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp.ietf.org/ietf-mail-archive/diffserv/", "type": "wg", "name": "Differentiated Services"}}, -{"pk": 1389, "model": "group.group", "fields": {"charter": "charter-ietf-sieve", "unused_states": [], "ad": 18321, "parent": 934, "list_email": "sieve@ietf.org", "acronym": "sieve", "comments": "1st meeting at 41st IETF-Los Angeles, CA; 2nd meeting at 44th IETF -Minneapolis, MN; 3rd meeting at 61st IETF", "list_subscribe": "sieve-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sieve/", "type": "wg", "name": "Sieve Mail Filtering Language"}}, +{"pk": 1389, "model": "group.group", "fields": {"charter": "charter-ietf-sieve", "unused_states": [], "ad": null, "parent": 934, "list_email": "sieve@ietf.org", "acronym": "sieve", "comments": "1st meeting at 41st IETF-Los Angeles, CA; 2nd meeting at 44th IETF -Minneapolis, MN; 3rd meeting at 61st IETF", "list_subscribe": "sieve-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sieve/", "type": "wg", "name": "Sieve Mail Filtering Language"}}, {"pk": 1390, "model": "group.group", "fields": {"charter": "charter-ietf-dasl", "unused_states": [], "ad": null, "parent": 934, "list_email": "www-webdav-dasl@w3.org", "acronym": "dasl", "comments": "1st meeting at 41st IETF-Los Angeles, CA; 2nd meeting at 42nd IETF-Chicago, IL", "list_subscribe": "www-webdav-dasl-request@w3.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.w3.org/Archives/Public/www-webdav-dasl/", "type": "wg", "name": "DAV Searching and Locating"}}, {"pk": 1391, "model": "group.group", "fields": {"charter": "charter-ietf-httpext", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-http-ext@w3.org", "acronym": "httpext", "comments": "1st meeting at 41st IETF-Los Angeles", "list_subscribe": "ietf-http-ext-request@w3.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.w3.org/Archives/Public/ietf-http-ext/", "type": "wg", "name": "HTTP Extensions"}}, {"pk": 1392, "model": "group.group", "fields": {"charter": "charter-ietf-aatn", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "aatn", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Avoidance of Address Translation in Networks"}}, {"pk": 1393, "model": "group.group", "fields": {"charter": "charter-ietf-wasrv", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "wasrv", "comments": "1st meeting at 41st IETF-Los Angeles", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Wide Area Service Location"}}, {"pk": 1394, "model": "group.group", "fields": {"charter": "charter-ietf-pipr", "unused_states": [], "ad": null, "parent": 934, "list_email": "rvp@iastate.edu", "acronym": "pipr", "comments": "1st meeting at 41st IETF-Los Angeles; 2nd meeting at 42nd IETF-Chicago, IL", "list_subscribe": "rvp-request@iastate.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "rvp-request@iastate.edu", "type": "wg", "name": "Presence Information Protocol Requirements"}}, {"pk": 1395, "model": "group.group", "fields": {"charter": "charter-ietf-trade", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-trade@lists.eListX.com", "acronym": "trade", "comments": "1st meeting at 41st IETF-Los Angeles", "list_subscribe": "ietf-trade-request@lists.eListX.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.eListX.com/archives/ietf-trade", "type": "wg", "name": "Internet Open Trading Protocol"}}, -{"pk": 1396, "model": "group.group", "fields": {"charter": "charter-ietf-adslmib", "unused_states": [], "ad": 105682, "parent": 1193, "list_email": "adslmib@ietf.org", "acronym": "adslmib", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/adslmib", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/adslmib/", "type": "wg", "name": "ADSL MIB"}}, -{"pk": 1397, "model": "group.group", "fields": {"charter": "charter-ietf-pim", "unused_states": [], "ad": 104198, "parent": 1249, "list_email": "pim@ietf.org", "acronym": "pim", "comments": "Full FTP archives (including old)\r\nftp://ftp.ietf.org/ietf-mail-archive/pim/", "list_subscribe": "https://www.ietf.org/mailman/listinfo/pim/", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pim/", "type": "wg", "name": "Protocol Independent Multicast"}}, +{"pk": 1396, "model": "group.group", "fields": {"charter": "charter-ietf-adslmib", "unused_states": [], "ad": null, "parent": 1193, "list_email": "adslmib@ietf.org", "acronym": "adslmib", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/adslmib", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/adslmib/", "type": "wg", "name": "ADSL MIB"}}, +{"pk": 1397, "model": "group.group", "fields": {"charter": "charter-ietf-pim", "unused_states": [], "ad": null, "parent": 1249, "list_email": "pim@ietf.org", "acronym": "pim", "comments": "Full FTP archives (including old)\r\nftp://ftp.ietf.org/ietf-mail-archive/pim/", "list_subscribe": "https://www.ietf.org/mailman/listinfo/pim/", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pim/", "type": "wg", "name": "Protocol Independent Multicast"}}, {"pk": 1398, "model": "group.group", "fields": {"charter": "charter-ietf-ss7", "unused_states": [], "ad": null, "parent": 1324, "list_email": "ss7-internet@baynetworks.com", "acronym": "ss7", "comments": "1st BOF held at 42nd IETF-Chicago, IL", "list_subscribe": "majordomo@baynetworks.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.baynetworks.com/pub/outgoing/long/ss7", "type": "wg", "name": "SS7/Internet"}}, -{"pk": 1399, "model": "group.group", "fields": {"charter": "charter-ietf-opsarea", "unused_states": [], "ad": 6699, "parent": 1193, "list_email": "", "acronym": "opsarea", "comments": "", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ag", "name": "Operations & Management Area Open Meeting"}}, +{"pk": 1399, "model": "group.group", "fields": {"charter": "charter-ietf-opsarea", "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "opsarea", "comments": "", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ag", "name": "Operations & Management Area Open Meeting"}}, {"pk": 1400, "model": "group.group", "fields": {"charter": "charter-ietf-trustmgt", "unused_states": [], "ad": null, "parent": 1260, "list_email": "trustmgt@east.isi.edu", "acronym": "trustmgt", "comments": "1st meeting - 42nd IETF, Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.cairn.net/trustmgt", "type": "wg", "name": "Trust Management"}}, {"pk": 1401, "model": "group.group", "fields": {"charter": "charter-ietf-policy", "unused_states": [], "ad": null, "parent": 1193, "list_email": "policy@ietf.org", "acronym": "policy", "comments": "1st meeting - 42nd IETF, Chicago, IL", "list_subscribe": "policy-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/policy/", "type": "wg", "name": "Policy Framework"}}, {"pk": 1402, "model": "group.group", "fields": {"charter": "charter-ietf-stp", "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "stp", "comments": "1st meeting - 42nd IETF, Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Secure Transport Proxy"}}, {"pk": 1403, "model": "group.group", "fields": {"charter": "charter-ietf-artmib", "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "artmib", "comments": "1st meeting at 42nd IETF-Chicago, IL\r\n\r\nAD was Harald", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Application Response Time MIB"}}, -{"pk": 1404, "model": "group.group", "fields": {"charter": "charter-ietf-rtgarea", "unused_states": [], "ad": 2329, "parent": 1249, "list_email": "", "acronym": "rtgarea", "comments": "", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ag", "name": "Routing Area Open Meeting"}}, +{"pk": 1404, "model": "group.group", "fields": {"charter": "charter-ietf-rtgarea", "unused_states": [], "ad": null, "parent": 1249, "list_email": "", "acronym": "rtgarea", "comments": "", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ag", "name": "Routing Area Open Meeting"}}, {"pk": 1405, "model": "group.group", "fields": {"charter": "charter-ietf-hmibs", "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "hmibs", "comments": "1st meeting at 42nd IETF-Chicago, IL\r\n\r\nAD was Harald", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "H.Multimedia MIBs"}}, {"pk": 1406, "model": "group.group", "fields": {"charter": "charter-ietf-smiv2", "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "smiv2", "comments": "1st meeting - 42nd IETF, Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Structure of Management Information Version 2"}}, {"pk": 1407, "model": "group.group", "fields": {"charter": "charter-ietf-mailrev", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "mailrev", "comments": "1st meeting-42nd IETF, Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Review of Short Mail-related Extension Proposals"}}, -{"pk": 1408, "model": "group.group", "fields": {"charter": "charter-ietf-aaa", "unused_states": [], "ad": 6699, "parent": 1193, "list_email": "aaa-wg@merit.edu", "acronym": "aaa", "comments": "1st meeting - 42nd IETF, Chicago, IL; 2nd meeting-43rd IETF, Orlando, FL", "list_subscribe": "majordomo@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.merit.edu/mail.archives/aaa-wg/", "type": "wg", "name": "Authentication, Authorization and Accounting"}}, +{"pk": 1408, "model": "group.group", "fields": {"charter": "charter-ietf-aaa", "unused_states": [], "ad": null, "parent": 1193, "list_email": "aaa-wg@merit.edu", "acronym": "aaa", "comments": "1st meeting - 42nd IETF, Chicago, IL; 2nd meeting-43rd IETF, Orlando, FL", "list_subscribe": "majordomo@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.merit.edu/mail.archives/aaa-wg/", "type": "wg", "name": "Authentication, Authorization and Accounting"}}, {"pk": 1409, "model": "group.group", "fields": {"charter": "charter-ietf-imapext", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-imapext@imc.org", "acronym": "imapext", "comments": "1st meeting at 42nd IETF-Chicago, IL; 2nd meeting at 45th IETF-Oslo, Norway", "list_subscribe": "ietf-imapext-request@imc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.imc.org/ietf-imapext/", "type": "wg", "name": "Internet Message Access Protocol Extension"}}, {"pk": 1410, "model": "group.group", "fields": {"charter": "charter-ietf-notify", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "notify", "comments": "1st meeting at 42nd IETF-Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Event Notification Service"}}, {"pk": 1411, "model": "group.group", "fields": {"charter": "charter-ietf-metad", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "metad", "comments": "1st meeting at 42nd IETF-Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "MIME Enabled Textually Accessed Directories"}}, {"pk": 1412, "model": "group.group", "fields": {"charter": "charter-ietf-mailcap", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "mailcap", "comments": "1st meeting at 42nd IETF-Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Mail Recipient Capabilities"}}, -{"pk": 1413, "model": "group.group", "fields": {"charter": "charter-ietf-enum", "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "enum@ietf.org", "acronym": "enum", "comments": "1st meeting at 42nd IETF-Chicago, IL; 2nd meeting at 43rd IETF-Orlando, FL", "list_subscribe": "https://www.ietf.org/mailman/listinfo/enum", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/enum/", "type": "wg", "name": "Telephone Number Mapping"}}, +{"pk": 1413, "model": "group.group", "fields": {"charter": "charter-ietf-enum", "unused_states": [], "ad": null, "parent": 1683, "list_email": "enum@ietf.org", "acronym": "enum", "comments": "1st meeting at 42nd IETF-Chicago, IL; 2nd meeting at 43rd IETF-Orlando, FL", "list_subscribe": "https://www.ietf.org/mailman/listinfo/enum", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/enum/", "type": "wg", "name": "Telephone Number Mapping"}}, {"pk": 1414, "model": "group.group", "fields": {"charter": "charter-ietf-pppoe", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "pppoe", "comments": "1st meeting at 42nd IETF-Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "PPP Over Ethernet"}}, {"pk": 1415, "model": "group.group", "fields": {"charter": "charter-ietf-wrec", "unused_states": [], "ad": null, "parent": 934, "list_email": "wrec@cs.utk.edu", "acronym": "wrec", "comments": "1st meeting at 42nd IETF-Chicago, IL; 2nd meeting at 43rd IETF-Orlando, FL; acronym has changed from webrepl to wrec on 1/14/99", "list_subscribe": "wrec-request@cs.utk.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://cs.utk.edu/pub/wrec", "type": "wg", "name": "Web Replication and Caching"}}, {"pk": 1416, "model": "group.group", "fields": {"charter": "charter-ietf-findstuf", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "findstuf", "comments": "1st meeting at 42nd IETF-Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Finding Stuff"}}, @@ -578,20 +578,20 @@ {"pk": 1425, "model": "group.group", "fields": {"charter": "charter-ietf-impp", "unused_states": [], "ad": null, "parent": 934, "list_email": "impp@iastate.edu", "acronym": "impp", "comments": "", "list_subscribe": "impp-request@iastate.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.imppwg.org", "type": "wg", "name": "Instant Messaging and Presence Protocol"}}, {"pk": 1426, "model": "group.group", "fields": {"charter": "charter-ietf-ruts", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "ruts", "comments": "1st meeting at 43rd IETF-Orlando, FL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Requirements for Unicast Transport/Sessions"}}, {"pk": 1427, "model": "group.group", "fields": {"charter": "charter-ietf-pilc", "unused_states": [], "ad": null, "parent": 1324, "list_email": "pilc@ietf.org", "acronym": "pilc", "comments": "1st meeting at 43rd IETF - Orlando, FL; 2nd meeting at 44th IETF-Minneapolis, MN", "list_subscribe": "pilc-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pilc/", "type": "wg", "name": "Performance Implications of Link Characteristics"}}, -{"pk": 1428, "model": "group.group", "fields": {"charter": "charter-ietf-eap", "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "eap@frascone.com", "acronym": "eap", "comments": "1st meeting at 43rd IETF-Orlando, FL", "list_subscribe": "eap-request@frascone.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://mail.frascone.com/pipermail/eap/", "type": "wg", "name": "Extensible Authentication Protocol"}}, +{"pk": 1428, "model": "group.group", "fields": {"charter": "charter-ietf-eap", "unused_states": [], "ad": null, "parent": 1052, "list_email": "eap@frascone.com", "acronym": "eap", "comments": "1st meeting at 43rd IETF-Orlando, FL", "list_subscribe": "eap-request@frascone.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://mail.frascone.com/pipermail/eap/", "type": "wg", "name": "Extensible Authentication Protocol"}}, {"pk": 1429, "model": "group.group", "fields": {"charter": "charter-ietf-newsnmp", "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "newsnmp", "comments": "1st meeting at 43rd IETF-Orlando, FL\r\n\r\nAD was Harald", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "New Work in the Network Management Area"}}, {"pk": 1430, "model": "group.group", "fields": {"charter": "charter-ietf-cnrp", "unused_states": [], "ad": null, "parent": 934, "list_email": "cnrp-ietf@lists.netsol.com", "acronym": "cnrp", "comments": "1st meeting at 43rd IETF-Orlando, FL; 2nd meeting at 44th IETF-Minneapolis, MN; name changed from HFN to CNRP 3/2/99;3rd meeting at 45th IETF-Oslo, Norway", "list_subscribe": "cnrp-ietf-request@lists.netsol.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.netsol.com/archives/cnrp-ietf.html", "type": "wg", "name": "Common Name Resolution Protocol"}}, {"pk": 1431, "model": "group.group", "fields": {"charter": "charter-ietf-ikstel", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "ikstel", "comments": "1st meeting 43rd IETF-Orlando, FL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet Kermit Services/Outstanding Telnet Option"}}, {"pk": 1432, "model": "group.group", "fields": {"charter": "charter-ietf-laser", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "laser", "comments": "1st meeting at 43rd IETF-Orlando, FL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "LDAP Schema for E-mail Routing"}}, {"pk": 1433, "model": "group.group", "fields": {"charter": "charter-ietf-drp", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "drp", "comments": "1st meeting at 43rd IETF-Orlando, FL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Domain Registry Protocol"}}, -{"pk": 1434, "model": "group.group", "fields": {"charter": "charter-ietf-gsmp", "unused_states": [], "ad": 6842, "parent": 1541, "list_email": "gsmp@ietf.org", "acronym": "gsmp", "comments": "1st meeting at 43rd IETF-Orlando, FL", "list_subscribe": "gsmp-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/gsmp/", "type": "wg", "name": "General Switch Management Protocol"}}, +{"pk": 1434, "model": "group.group", "fields": {"charter": "charter-ietf-gsmp", "unused_states": [], "ad": null, "parent": 1541, "list_email": "gsmp@ietf.org", "acronym": "gsmp", "comments": "1st meeting at 43rd IETF-Orlando, FL", "list_subscribe": "gsmp-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/gsmp/", "type": "wg", "name": "General Switch Management Protocol"}}, {"pk": 1435, "model": "group.group", "fields": {"charter": "charter-ietf-stime", "unused_states": [], "ad": null, "parent": 1260, "list_email": "authtime@nist.gov", "acronym": "stime", "comments": "1st meeting at 43rd IETF-Orlando, FL; 2nd meeting at 44th IETF-Minneapolis, MN; acronym changed from secntp stime 3/1/99", "list_subscribe": "listproc@nist.gov", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.nist.gov/itl/div896/emaildir/authtime/maillist.html", "type": "wg", "name": "Secure Network Time Protocol"}}, {"pk": 1436, "model": "group.group", "fields": {"charter": "charter-ietf-ipsp", "unused_states": [], "ad": null, "parent": 1260, "list_email": "ipsec-policy@vpnc.org", "acronym": "ipsp", "comments": "1st meeting at 44th IETF-Minneapolis, MN; 2nd meeting at 45th IETF-Oslo, Norway", "list_subscribe": "ipsec-policy-request@vpnc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.vpnc.org/ipsec-policy/", "type": "wg", "name": "IP Security Policy"}}, -{"pk": 1437, "model": "group.group", "fields": {"charter": "charter-ietf-rmt", "unused_states": [], "ad": 105519, "parent": 1324, "list_email": "rmt@ietf.org", "acronym": "rmt", "comments": "", "list_subscribe": "rmt-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rmt/", "type": "wg", "name": "Reliable Multicast Transport"}}, -{"pk": 1438, "model": "group.group", "fields": {"charter": "charter-ietf-weird", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "ietf-weird@imc.org", "acronym": "weird", "comments": "1st meeting at 44th IETF-Minneapolis, MN", "list_subscribe": "ietf-weird-request@imc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.imc.org/ietf-weird/", "type": "wg", "name": "Web Elucidation of Internet-Related Developments"}}, +{"pk": 1437, "model": "group.group", "fields": {"charter": "charter-ietf-rmt", "unused_states": [], "ad": null, "parent": 1324, "list_email": "rmt@ietf.org", "acronym": "rmt", "comments": "", "list_subscribe": "rmt-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rmt/", "type": "wg", "name": "Reliable Multicast Transport"}}, +{"pk": 1438, "model": "group.group", "fields": {"charter": "charter-ietf-weird", "unused_states": [], "ad": null, "parent": 1346, "list_email": "ietf-weird@imc.org", "acronym": "weird", "comments": "1st meeting at 44th IETF-Minneapolis, MN", "list_subscribe": "ietf-weird-request@imc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.imc.org/ietf-weird/", "type": "wg", "name": "Web Elucidation of Internet-Related Developments"}}, {"pk": 1439, "model": "group.group", "fields": {"charter": "charter-ietf-slums", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "slums", "comments": "1st meeting at 44th IETF-Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Support for Lots of Unicast Multiplexed Sessions"}}, -{"pk": 1440, "model": "group.group", "fields": {"charter": "charter-ietf-usvarea", "unused_states": [], "ad": 4356, "parent": 934, "list_email": "", "acronym": "usvarea", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ag", "name": "User Services Area Open Meeting"}}, -{"pk": 1441, "model": "group.group", "fields": {"charter": "charter-ietf-fyiup", "unused_states": [], "ad": 4356, "parent": 1346, "list_email": "ietf-fyiup@imc.org", "acronym": "fyiup", "comments": "1st meeting at 44th IETF-Minneapolis, MN", "list_subscribe": "ietf-fyiup-request@imc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.imc.org/ietf-fyiup/", "type": "wg", "name": "FYI Updates"}}, +{"pk": 1440, "model": "group.group", "fields": {"charter": "charter-ietf-usvarea", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "usvarea", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ag", "name": "User Services Area Open Meeting"}}, +{"pk": 1441, "model": "group.group", "fields": {"charter": "charter-ietf-fyiup", "unused_states": [], "ad": null, "parent": 1346, "list_email": "ietf-fyiup@imc.org", "acronym": "fyiup", "comments": "1st meeting at 44th IETF-Minneapolis, MN", "list_subscribe": "ietf-fyiup-request@imc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.imc.org/ietf-fyiup/", "type": "wg", "name": "FYI Updates"}}, {"pk": 1442, "model": "group.group", "fields": {"charter": "charter-ietf-xmldsig", "unused_states": [], "ad": null, "parent": 1260, "list_email": "w3c-ietf-xmldsig@w3.org", "acronym": "xmldsig", "comments": "1st meeting at 44th IETF-Minneapolis, MN", "list_subscribe": "w3c-ietf-xmldsig-request@w3.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.w3.org/Archives/Public/w3c-ietf-xmldsig", "type": "wg", "name": "XML Digital Signatures"}}, {"pk": 1443, "model": "group.group", "fields": {"charter": "charter-ietf-nits", "unused_states": [], "ad": null, "parent": 1052, "list_email": "nits@merit.edu", "acronym": "nits", "comments": "1st meeting at 44th IETF-Minneapolis, MN; 2nd meeting at 45th IETF-Oslo. Became zeroconf WG", "list_subscribe": "nits-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.ietf.org/ietf-mail/archive/nits", "type": "wg", "name": "Networks in the Small - aka Home Networks"}}, {"pk": 1444, "model": "group.group", "fields": {"charter": "charter-ietf-tfesp", "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "tfesp", "comments": "1st meeting at 44th IETF-Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Transport Friendly ESP"}}, @@ -602,39 +602,39 @@ {"pk": 1449, "model": "group.group", "fields": {"charter": "charter-ietf-remboot", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "remboot", "comments": "1st meeting at 44th IETF-Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Remote Boot Protocol"}}, {"pk": 1450, "model": "group.group", "fields": {"charter": "charter-ietf-qualdocs", "unused_states": [], "ad": null, "parent": 934, "list_email": "ifx@pwg.org", "acronym": "qualdocs", "comments": "1st meeting at 44th IETF-Minneapolis, MN; 2nd meeting at 46th IETF-Washington; changed name from IPP2IFAX; 3rd meeting at 47th IETF-Adelaide, AU", "list_subscribe": "majordomo@pwg.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.pwg.org/hypermail/ifx", "type": "wg", "name": "High Quality Document Transfer"}}, {"pk": 1451, "model": "group.group", "fields": {"charter": "charter-ietf-vpim", "unused_states": [], "ad": null, "parent": 934, "list_email": "vpim@ietf.org", "acronym": "vpim", "comments": "1st meeting at 44th IETF-Minneapolis, MN; 2nd meeting at 45th IETF-Oslo, Norway\r\nFTP Archive: ftp://ftp.ietf.org/ietf-mail-archive/rtgwg/", "list_subscribe": "vpim-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/vpim/", "type": "wg", "name": "Voice Profile for Internet Mail"}}, -{"pk": 1452, "model": "group.group", "fields": {"charter": "charter-ietf-dnsop", "unused_states": [], "ad": 101568, "parent": 1193, "list_email": "dnsop@ietf.org", "acronym": "dnsop", "comments": "1st meeting at 44th IETF-Minneapolis, MN\r\n\r\nAD was Harald", "list_subscribe": "http://www.ietf.org/mailman/listinfo/dnsop", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dnsop", "type": "wg", "name": "Domain Name System Operations"}}, +{"pk": 1452, "model": "group.group", "fields": {"charter": "charter-ietf-dnsop", "unused_states": [], "ad": null, "parent": 1193, "list_email": "dnsop@ietf.org", "acronym": "dnsop", "comments": "1st meeting at 44th IETF-Minneapolis, MN\r\n\r\nAD was Harald", "list_subscribe": "http://www.ietf.org/mailman/listinfo/dnsop", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dnsop", "type": "wg", "name": "Domain Name System Operations"}}, {"pk": 1453, "model": "group.group", "fields": {"charter": "charter-ietf-ipsra", "unused_states": [], "ad": null, "parent": 1260, "list_email": "ietf-ipsra@vpnc.org", "acronym": "ipsra", "comments": "1st meeting at 44th IETF-Minneapolis, MN; 2nd meeting at 46th IETF-Washington, DC; 3rd meeting at 47th IETF-Adelaide, AU", "list_subscribe": "ietf-ipsra-request@vpnc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.vpnc.org/ietf-ipsra/mail-archive/", "type": "wg", "name": "IP Security Remote Access"}}, {"pk": 1454, "model": "group.group", "fields": {"charter": "charter-ietf-decides", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "decides", "comments": "1st meeting at 45th IETF-Oslo, Norway; 2nd meeting at 46th IETF-Washington, DC; full name is Deployment Considerations of Implementing Differentiated Services", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Deployment Considerations of Implementing Differen"}}, {"pk": 1455, "model": "group.group", "fields": {"charter": "charter-ietf-netwklr", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "netwklr", "comments": "1st meeting at 45th IETF-Oslo, Norway", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Layer"}}, {"pk": 1456, "model": "group.group", "fields": {"charter": "charter-ietf-bgmp", "unused_states": [], "ad": null, "parent": 1249, "list_email": "bgmp@ietf.org", "acronym": "bgmp", "comments": "1st meeting held at 45th IETF-Oslo, Norway\r\nFTP archive: ftp://ftp.ietf.org/ietf-mail-archive/bgmp/", "list_subscribe": "http://www1.ietf.org/mailman/listinfo/bgmp/", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/bgmp/", "type": "wg", "name": "Border Gateway Multicast Protocol"}}, {"pk": 1457, "model": "group.group", "fields": {"charter": "charter-ietf-cm", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "cm", "comments": "1st meeting at 45th IETF-Oslo, Norway", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Congestion Management"}}, -{"pk": 1458, "model": "group.group", "fields": {"charter": "charter-ietf-tewg", "unused_states": [], "ad": 6842, "parent": 1541, "list_email": "te-wg@ops.ietf.org", "acronym": "tewg", "comments": "1st meeting at 45th IETF-Oslo, Norway; 2nd meeting at 46th IETF-Washington, DC", "list_subscribe": "te-wg-request@ops.ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://ops.ietf.org/lists/te-wg", "type": "wg", "name": "Internet Traffic Engineering"}}, +{"pk": 1458, "model": "group.group", "fields": {"charter": "charter-ietf-tewg", "unused_states": [], "ad": null, "parent": 1541, "list_email": "te-wg@ops.ietf.org", "acronym": "tewg", "comments": "1st meeting at 45th IETF-Oslo, Norway; 2nd meeting at 46th IETF-Washington, DC", "list_subscribe": "te-wg-request@ops.ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://ops.ietf.org/lists/te-wg", "type": "wg", "name": "Internet Traffic Engineering"}}, {"pk": 1459, "model": "group.group", "fields": {"charter": "charter-ietf-lsd2", "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "lsd2", "comments": "1st meeting at 45th IETF-Oslo, Norway", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "LDAP Service Deployment - Take 2"}}, {"pk": 1460, "model": "group.group", "fields": {"charter": "charter-ietf-maestro", "unused_states": [], "ad": null, "parent": 1249, "list_email": "", "acronym": "maestro", "comments": "1st meeting at 45th IETF-Oslo, Norway", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Multicast Addr. Exten. & Simple Transmitter Opti."}}, {"pk": 1461, "model": "group.group", "fields": {"charter": "charter-ietf-zeroconf", "unused_states": [], "ad": null, "parent": 1052, "list_email": "zeroconf@merit.edu", "acronym": "zeroconf", "comments": "Was nits (Networks in the Small)", "list_subscribe": "zeroconf-request@merit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.merit.edu/mail.archives/zeroconf/", "type": "wg", "name": "Zero Configuration Networking"}}, {"pk": 1462, "model": "group.group", "fields": {"charter": "charter-ietf-sip", "unused_states": [], "ad": null, "parent": 1683, "list_email": "sip@ietf.org", "acronym": "sip", "comments": "", "list_subscribe": "sip-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sip/", "type": "wg", "name": "Session Initiation Protocol"}}, -{"pk": 1463, "model": "group.group", "fields": {"charter": "charter-ietf-tsvwg", "unused_states": [], "ad": 105519, "parent": 1324, "list_email": "tsvwg@ietf.org", "acronym": "tsvwg", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/tsvwg", "state": "active", "time": "2012-07-06 09:19:09", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/tsvwg/", "type": "wg", "name": "Transport Area Working Group"}}, +{"pk": 1463, "model": "group.group", "fields": {"charter": "charter-ietf-tsvwg", "unused_states": [], "ad": null, "parent": 1324, "list_email": "tsvwg@ietf.org", "acronym": "tsvwg", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/tsvwg", "state": "active", "time": "2012-07-06 09:19:09", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/tsvwg/", "type": "wg", "name": "Transport Area Working Group"}}, {"pk": 1464, "model": "group.group", "fields": {"charter": "charter-ietf-polterm", "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "polterm", "comments": "1st meeting at 46th IETF-Washington, DC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Policy Terminology"}}, {"pk": 1465, "model": "group.group", "fields": {"charter": "charter-ietf-cfgmgmt", "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "cfgmgmt", "comments": "1st meeting at 46th IETF-Washington, DC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Configuration Management"}}, {"pk": 1466, "model": "group.group", "fields": {"charter": "charter-ietf-ecm", "unused_states": [], "ad": null, "parent": 1324, "list_email": "ecm@aciri.org", "acronym": "ecm", "comments": "1st meeting at 46th IETF-Washington, DC", "list_subscribe": "ecm-request@aciri.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.ietf.org/ietf-mail-archive/", "type": "wg", "name": "Endpoint Congestion Management"}}, -{"pk": 1467, "model": "group.group", "fields": {"charter": "charter-ietf-srp", "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "", "acronym": "srp", "comments": "1st meeting at 46th IETF-Washington, DC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Spatial Reuse Protocol"}}, -{"pk": 1468, "model": "group.group", "fields": {"charter": "charter-ietf-syslog", "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "syslog@ietf.org", "acronym": "syslog", "comments": "1st meeting at 46th IETF-Washington, DC; 2nd meeting at 47th IETF-Adelaide, AU", "list_subscribe": "syslog-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/syslog", "type": "wg", "name": "Security Issues in Network Event Logging"}}, -{"pk": 1469, "model": "group.group", "fields": {"charter": "charter-ietf-l2tpext", "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "l2tpext@ietf.org", "acronym": "l2tpext", "comments": "1st meeting at 46th IETF-Washington, DC", "list_subscribe": "l2tpext-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/l2tpext/", "type": "wg", "name": "Layer Two Tunneling Protocol Extensions"}}, +{"pk": 1467, "model": "group.group", "fields": {"charter": "charter-ietf-srp", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "srp", "comments": "1st meeting at 46th IETF-Washington, DC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Spatial Reuse Protocol"}}, +{"pk": 1468, "model": "group.group", "fields": {"charter": "charter-ietf-syslog", "unused_states": [], "ad": null, "parent": 1260, "list_email": "syslog@ietf.org", "acronym": "syslog", "comments": "1st meeting at 46th IETF-Washington, DC; 2nd meeting at 47th IETF-Adelaide, AU", "list_subscribe": "syslog-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/syslog", "type": "wg", "name": "Security Issues in Network Event Logging"}}, +{"pk": 1469, "model": "group.group", "fields": {"charter": "charter-ietf-l2tpext", "unused_states": [], "ad": null, "parent": 1052, "list_email": "l2tpext@ietf.org", "acronym": "l2tpext", "comments": "1st meeting at 46th IETF-Washington, DC", "list_subscribe": "l2tpext-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/l2tpext/", "type": "wg", "name": "Layer Two Tunneling Protocol Extensions"}}, {"pk": 1470, "model": "group.group", "fields": {"charter": "charter-ietf-micropay", "unused_states": [], "ad": null, "parent": 1260, "list_email": "micropayments@elab.co.uk", "acronym": "micropay", "comments": "1st meeting at 46th IETF-Washington, DC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Micro Payments"}}, {"pk": 1471, "model": "group.group", "fields": {"charter": "charter-ietf-spirits", "unused_states": [], "ad": null, "parent": 1324, "list_email": "spirits@lists.bell-lab.com", "acronym": "spirits", "comments": "", "list_subscribe": "spirits-request@lists.bell-labs.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.bell-labs.com/mailing-lists/spirits/", "type": "wg", "name": "Service in the PSTN/IN Requesting InTernet Service"}}, {"pk": 1472, "model": "group.group", "fields": {"charter": "charter-ietf-gr303", "unused_states": [], "ad": null, "parent": 1193, "list_email": "gr303mib@tollbridgetech.com", "acronym": "gr303", "comments": "1st meeting at 46th IETF-Washington, DC", "list_subscribe": "gr303mib-request@tollbridgetech.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "GR-303 MIB"}}, {"pk": 1473, "model": "group.group", "fields": {"charter": "charter-ietf-ecml", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "ecml", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Electronic Commerce Modeling Lanugage"}}, -{"pk": 1474, "model": "group.group", "fields": {"charter": "charter-ietf-rohc", "unused_states": [], "ad": 17253, "parent": 1324, "list_email": "rohc@ietf.org", "acronym": "rohc", "comments": "1st meeting at 46th IETF-Washington, DC; 2nd meeting at 47th IETF-Adelaide, AU", "list_subscribe": "rohc-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rohc/", "type": "wg", "name": "Robust Header Compression"}}, +{"pk": 1474, "model": "group.group", "fields": {"charter": "charter-ietf-rohc", "unused_states": [], "ad": null, "parent": 1324, "list_email": "rohc@ietf.org", "acronym": "rohc", "comments": "1st meeting at 46th IETF-Washington, DC; 2nd meeting at 47th IETF-Adelaide, AU", "list_subscribe": "rohc-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rohc/", "type": "wg", "name": "Robust Header Compression"}}, {"pk": 1475, "model": "group.group", "fields": {"charter": "charter-ietf-anycast", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "anycast", "comments": "1st meeting at 46th IETF-Washington, DC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Anycast"}}, {"pk": 1476, "model": "group.group", "fields": {"charter": "charter-ietf-ippext", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "ippext", "comments": "1st meeting at 46th IETF-Washington, DC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPP Extensions"}}, {"pk": 1477, "model": "group.group", "fields": {"charter": "charter-ietf-mmms", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "mmms", "comments": "1st meeting at 46th IETF-Washington, DC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Mobile Multimedia Messaging Service"}}, {"pk": 1478, "model": "group.group", "fields": {"charter": "charter-ietf-idn", "unused_states": [], "ad": null, "parent": 934, "list_email": "idn@ops.ietf.org", "acronym": "idn", "comments": "1st meeting at 46th IETF-Washington, DC; changed area and reopened as a BOF for the 71st IETF-Philadelphia, PA", "list_subscribe": "idn-request@ops.ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ops.ietf.org/pub/lists/idn*", "type": "wg", "name": "Internationalized Domain Name"}}, -{"pk": 1479, "model": "group.group", "fields": {"charter": "charter-ietf-dnsext", "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "dnsext@ietf.org", "acronym": "dnsext", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/dnsext", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dnsext/", "type": "wg", "name": "DNS Extensions"}}, +{"pk": 1479, "model": "group.group", "fields": {"charter": "charter-ietf-dnsext", "unused_states": [], "ad": null, "parent": 1052, "list_email": "dnsext@ietf.org", "acronym": "dnsext", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/dnsext", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dnsext/", "type": "wg", "name": "DNS Extensions"}}, {"pk": 1480, "model": "group.group", "fields": {"charter": "charter-ietf-snmpconf", "unused_states": [], "ad": null, "parent": 1193, "list_email": "snmpconf@snmp.com", "acronym": "snmpconf", "comments": "", "list_subscribe": "snmpconf-request@snmp.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "mailto:snmpconf-request@snmp.com (index snmpconf in body)", "type": "wg", "name": "Configuration Management with SNMP"}}, {"pk": 1481, "model": "group.group", "fields": {"charter": "charter-ietf-blocks", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "blocks", "comments": "1st meeting at 47th IETF-Adelaide, AU", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "An Application Protocol Framework & A Model Applic"}}, {"pk": 1482, "model": "group.group", "fields": {"charter": "charter-ietf-sigprodi", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "sigprodi", "comments": "1st meeting at 47th IETF-Adelaide, AU-was cancelled", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Signaling Protocols Discussion"}}, {"pk": 1483, "model": "group.group", "fields": {"charter": "charter-ietf-itrace", "unused_states": [], "ad": null, "parent": 1052, "list_email": "ietf-itrace@research.att.com", "acronym": "itrace", "comments": "1st meeting at 47th IETF-Adelaide, AU", "list_subscribe": "majordomo@research.att.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.research.att.com/lists/ietf-itrace", "type": "wg", "name": "ICMP Traceback"}}, -{"pk": 1484, "model": "group.group", "fields": {"charter": "charter-ietf-ipo", "unused_states": [], "ad": 103264, "parent": 1541, "list_email": "ip-optical@lists.bell-labs.com", "acronym": "ipo", "comments": "1st meeting at 47th IETF-Adelaide, AU; 2nd meeting at 48th IETF-Pittsburgh, PA", "list_subscribe": "http://lists.bell-labs.com/mailman/listinfo/ip-optical", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.bell-labs.com/mailing-lists/ip-optical/", "type": "wg", "name": "IP over Optical"}}, +{"pk": 1484, "model": "group.group", "fields": {"charter": "charter-ietf-ipo", "unused_states": [], "ad": null, "parent": 1541, "list_email": "ip-optical@lists.bell-labs.com", "acronym": "ipo", "comments": "1st meeting at 47th IETF-Adelaide, AU; 2nd meeting at 48th IETF-Pittsburgh, PA", "list_subscribe": "http://lists.bell-labs.com/mailman/listinfo/ip-optical", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.bell-labs.com/mailing-lists/ip-optical/", "type": "wg", "name": "IP over Optical"}}, {"pk": 1485, "model": "group.group", "fields": {"charter": "charter-ietf-ips", "unused_states": [], "ad": null, "parent": 1324, "list_email": "ips@ietf.org", "acronym": "ips", "comments": "1st meeting at 47th IETF-Adelaide, AU; 2nd meeting at 48th IETF-Pittsburgh, PA", "list_subscribe": "https://www1.ietf.org/mailman/listinfo/ips", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ips/", "type": "wg", "name": "IP Storage"}}, {"pk": 1486, "model": "group.group", "fields": {"charter": "charter-ietf-b2bxml", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "b2bxml", "comments": "1st meeting at 47th IETF-Adelaide, AU", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Business to Business XML Data Commun. Strategies"}}, {"pk": 1487, "model": "group.group", "fields": {"charter": "charter-ietf-vompls", "unused_states": [], "ad": null, "parent": 1324, "list_email": "vompls@lists.integralaccess.com", "acronym": "vompls", "comments": "1st meeting at 47th IETF-Adelaide, AU", "list_subscribe": "vompls-request@lists.integralaccess.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://sonic.sparklist.com/scripts/lyris.pl?enter=vompls", "type": "wg", "name": "Voice over IP over MPLS"}}, @@ -643,65 +643,65 @@ {"pk": 1490, "model": "group.group", "fields": {"charter": "charter-ietf-spatial", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-spatial@research.nokia.com", "acronym": "spatial", "comments": "1st meeting at 47th IETF-Adelaide, AU; 2nd meeting at 48th IETF-Pittsburgh, PA", "list_subscribe": "majordom@oresearch.nokia.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www-nrc.nokia.com/mail-archive/ietf-spatial/", "type": "wg", "name": "Spatial Location"}}, {"pk": 1491, "model": "group.group", "fields": {"charter": "charter-ietf-foglamps", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "foglamps", "comments": "1st meeting at 47th IETF-Adelaide, AU", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Limitations of Multiple Addressing Realms"}}, {"pk": 1492, "model": "group.group", "fields": {"charter": "charter-ietf-sip323", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "sip323", "comments": "1st meeting at 47th IETF-Adelaide, AU", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SIP and H.323 Interworking"}}, -{"pk": 1493, "model": "group.group", "fields": {"charter": "charter-ietf-iww", "unused_states": [], "ad": 188, "parent": 934, "list_email": "iab-wireless-workshop-interest@ietf.org", "acronym": "iww", "comments": "1st meeting at 47th IETF-Adelaide, AU", "list_subscribe": "iab-wireless-workshop-interest-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IAB Wireless Workshop"}}, +{"pk": 1493, "model": "group.group", "fields": {"charter": "charter-ietf-iww", "unused_states": [], "ad": null, "parent": 934, "list_email": "iab-wireless-workshop-interest@ietf.org", "acronym": "iww", "comments": "1st meeting at 47th IETF-Adelaide, AU", "list_subscribe": "iab-wireless-workshop-interest-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IAB Wireless Workshop"}}, {"pk": 1494, "model": "group.group", "fields": {"charter": "charter-ietf-rperfman", "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "rperfman", "comments": "1st meeting at 47th IETF-Adelaide, AU", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Remote Performance Management"}}, {"pk": 1495, "model": "group.group", "fields": {"charter": "charter-ietf-beep", "unused_states": [], "ad": null, "parent": 934, "list_email": "beepwg@lists.beepcore.org", "acronym": "beep", "comments": "", "list_subscribe": "beepwg-request@lists.beepcore.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.beepcore.org/mailman/listinfo/beepwg/", "type": "wg", "name": "Blocks Extensible Exchange Protocol"}}, -{"pk": 1496, "model": "group.group", "fields": {"charter": "charter-ietf-krb-wg", "unused_states": [], "ad": 19177, "parent": 1260, "list_email": "ietf-krb-wg@lists.anl.gov", "acronym": "krb-wg", "comments": "", "list_subscribe": "https://lists.anl.gov/mailman/listinfo/ietf-krb-wg", "state": "active", "time": "2012-10-01 09:27:45", "unused_tags": [], "list_archive": "https://lists.anl.gov/pipermail/ietf-krb-wg/", "type": "wg", "name": "Kerberos"}}, +{"pk": 1496, "model": "group.group", "fields": {"charter": "charter-ietf-krb-wg", "unused_states": [], "ad": null, "parent": 1260, "list_email": "ietf-krb-wg@lists.anl.gov", "acronym": "krb-wg", "comments": "", "list_subscribe": "https://lists.anl.gov/mailman/listinfo/ietf-krb-wg", "state": "active", "time": "2012-10-01 09:27:45", "unused_tags": [], "list_archive": "https://lists.anl.gov/pipermail/ietf-krb-wg/", "type": "wg", "name": "Kerberos"}}, {"pk": 1497, "model": "group.group", "fields": {"charter": "charter-ietf-ssm", "unused_states": [], "ad": null, "parent": 1249, "list_email": "ssm@ietf.org", "acronym": "ssm", "comments": "Old Archives at:\r\nftp://ftp.ietf.org/ietf-mail-archive/ssm/", "list_subscribe": "ssm-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ssm/", "type": "wg", "name": "Source-Specific Multicast"}}, -{"pk": 1498, "model": "group.group", "fields": {"charter": "charter-ietf-ppvpn", "unused_states": [], "ad": 103264, "parent": 1541, "list_email": "ppvpn@nortelnetworks.com", "acronym": "ppvpn", "comments": "", "list_subscribe": "lyris@nortelnetworks.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://standards.nortelnetworks.com/ppvpn/index.htm", "type": "wg", "name": "Provider Provisioned Virtual Private Networks"}}, +{"pk": 1498, "model": "group.group", "fields": {"charter": "charter-ietf-ppvpn", "unused_states": [], "ad": null, "parent": 1541, "list_email": "ppvpn@nortelnetworks.com", "acronym": "ppvpn", "comments": "", "list_subscribe": "lyris@nortelnetworks.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://standards.nortelnetworks.com/ppvpn/index.htm", "type": "wg", "name": "Provider Provisioned Virtual Private Networks"}}, {"pk": 1499, "model": "group.group", "fields": {"charter": "charter-ietf-seamoby", "unused_states": [], "ad": null, "parent": 1324, "list_email": "seamoby@ietf.org", "acronym": "seamoby", "comments": "Used to be craps (Common Radio Access Protocol Set).\r\n1st meeting at 48th IETF-Pittsburgh, PA.\r\n2nd meeting at 49th IETF-San Diego, CA", "list_subscribe": "seamoby-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/seamoby/", "type": "wg", "name": "Context Transfer, Handoff Candidate Discovery, and Dormant Mode Host Alerting"}}, {"pk": 1500, "model": "group.group", "fields": {"charter": "charter-ietf-sgm", "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "sgm", "comments": "1st meeting at 48th IETF-Pittsburgh, PA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Small Group Multicast"}}, {"pk": 1501, "model": "group.group", "fields": {"charter": "charter-ietf-sacred", "unused_states": [], "ad": null, "parent": 1260, "list_email": "ietf-sacred@imc.org", "acronym": "sacred", "comments": "1st meeting at 48th IETF-Pittsburgh, PA", "list_subscribe": "ietf-sacred-request@imc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.imc.org/ietf-sacred/mail-archive/", "type": "wg", "name": "Securely Available Credentials"}}, {"pk": 1502, "model": "group.group", "fields": {"charter": "charter-ietf-sin", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "sin", "comments": "1st meeting at 48th IETF-Pittsburgh, PA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "SIP/IN Interworking"}}, {"pk": 1503, "model": "group.group", "fields": {"charter": "charter-ietf-ipobt", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "ipobt", "comments": "1st meeting at 48th IETF-Pittsburgh, PA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IP over Bluetooth"}}, -{"pk": 1504, "model": "group.group", "fields": {"charter": "charter-ietf-rserpool", "unused_states": [], "ad": 17253, "parent": 1324, "list_email": "rserpool@ietf.org", "acronym": "rserpool", "comments": "1st meeting at 48th IETF-Pittsburgh, PA", "list_subscribe": "rserpool-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rserpool/", "type": "wg", "name": "Reliable Server Pooling"}}, +{"pk": 1504, "model": "group.group", "fields": {"charter": "charter-ietf-rserpool", "unused_states": [], "ad": null, "parent": 1324, "list_email": "rserpool@ietf.org", "acronym": "rserpool", "comments": "1st meeting at 48th IETF-Pittsburgh, PA", "list_subscribe": "rserpool-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rserpool/", "type": "wg", "name": "Reliable Server Pooling"}}, {"pk": 1505, "model": "group.group", "fields": {"charter": "charter-ietf-iporpr", "unused_states": [], "ad": null, "parent": 1052, "list_email": "iporpr@ietf.org", "acronym": "iporpr", "comments": "1st meeting at 48th IETF-Pittsburgh, PA\r\nWas known as IPOPTR", "list_subscribe": "iporpr-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/iporpr/", "type": "wg", "name": "IP over Resilient Packet Rings"}}, {"pk": 1506, "model": "group.group", "fields": {"charter": "charter-ietf-ldapbis", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-ldapbis@openldap.org", "acronym": "ldapbis", "comments": "1st meeting at 48th IETF-Pittsburgh, PA; 2nd meeting at 49th IETF-San Diego, CA", "list_subscribe": "ietf-ldapbis-request@openldap.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.openldap.org/lists/ietf-ldapbis/", "type": "wg", "name": "LDAP (v3) Revision"}}, {"pk": 1507, "model": "group.group", "fields": {"charter": "charter-ietf-nim", "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "nim", "comments": "1st meeting at 48th IETF-Pittsburgh, PA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Information Model"}}, {"pk": 1508, "model": "group.group", "fields": {"charter": "charter-ietf-ieps", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "ieps", "comments": "1st meeting at 48th IETF-Pittsburgh, PA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "International Emergency Preparedness Scheme"}}, {"pk": 1509, "model": "group.group", "fields": {"charter": "charter-ietf-cnhhttp", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "cnhhttp", "comments": "1st meeting at 48th IETF-Pittsburgh, PA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Content Negotiation Headers in HTTP"}}, {"pk": 1510, "model": "group.group", "fields": {"charter": "charter-ietf-kink", "unused_states": [], "ad": null, "parent": 1260, "list_email": "ietf-kink@vpnc.org", "acronym": "kink", "comments": "", "list_subscribe": "majordomo@vpnc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.vpnc.org/ietf-kink/", "type": "wg", "name": "Kerberized Internet Negotiation of Keys"}}, -{"pk": 1511, "model": "group.group", "fields": {"charter": "charter-ietf-msec", "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "msec@ietf.org", "acronym": "msec", "comments": "1st meeting at 49th IETF-San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/msec", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/msec/", "type": "wg", "name": "Multicast Security"}}, +{"pk": 1511, "model": "group.group", "fields": {"charter": "charter-ietf-msec", "unused_states": [], "ad": null, "parent": 1260, "list_email": "msec@ietf.org", "acronym": "msec", "comments": "1st meeting at 49th IETF-San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/msec", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/msec/", "type": "wg", "name": "Multicast Security"}}, {"pk": 1512, "model": "group.group", "fields": {"charter": "charter-ietf-sming", "unused_states": [], "ad": null, "parent": 1193, "list_email": "sming@ops.ietf.org", "acronym": "sming", "comments": "1st meeting at 49th IETF-San Diego, CA", "list_subscribe": "sming-request@ops.ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://ops.ietf.org/lists/sming/", "type": "wg", "name": "Next Generation Structure of Management Information"}}, {"pk": 1513, "model": "group.group", "fields": {"charter": "charter-ietf-rtfm2", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "rtfm2", "comments": "1st meeting at 49th IETF-San Diego, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Development of the Realtime Traffic Flow Measurement Architecture"}}, {"pk": 1514, "model": "group.group", "fields": {"charter": "charter-ietf-domreg", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "domreg", "comments": "1st meeting at 49th IETF-San Diego, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Domain Registration Services"}}, {"pk": 1515, "model": "group.group", "fields": {"charter": "charter-ietf-opes", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-openproxy@imc.org", "acronym": "opes", "comments": "1st meeting at 49th IETF - San Diego, CA\r\nas Open Proxy Extended Services Architecture", "list_subscribe": "ietf-openproxy-request@imc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/newtrk", "type": "wg", "name": "Open Pluggable Edge Services"}}, {"pk": 1516, "model": "group.group", "fields": {"charter": "charter-ietf-ceot", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "ceot", "comments": "1st meeting at 49th IETF - San Diego, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Circuit Emulation over Transport"}}, {"pk": 1517, "model": "group.group", "fields": {"charter": "charter-ietf-telsec", "unused_states": [], "ad": null, "parent": 1260, "list_email": "telnet-wg@bsdi.com", "acronym": "telsec", "comments": "1st meeting at 49th IETF - San Diego, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Telnet Security"}}, -{"pk": 1518, "model": "group.group", "fields": {"charter": "charter-ietf-forces", "unused_states": [], "ad": 104198, "parent": 1249, "list_email": "forces@ietf.org", "acronym": "forces", "comments": "1st meeting at 49th IETF - San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/forces", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/forces/", "type": "wg", "name": "Forwarding and Control Element Separation"}}, +{"pk": 1518, "model": "group.group", "fields": {"charter": "charter-ietf-forces", "unused_states": [], "ad": null, "parent": 1249, "list_email": "forces@ietf.org", "acronym": "forces", "comments": "1st meeting at 49th IETF - San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/forces", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/forces/", "type": "wg", "name": "Forwarding and Control Element Separation"}}, {"pk": 1519, "model": "group.group", "fields": {"charter": "charter-ietf-cdi", "unused_states": [], "ad": null, "parent": 934, "list_email": "cdn@ops.ietf.org", "acronym": "cdi", "comments": "1st meeting at 49th IETF-San Diego, CA; 2nd meeting at 50th IETF-Minneapolis, MN;acronym changed from CDNP to CDI for 50th IETF; 52nd IETF, Salt Lake City, Utah", "list_subscribe": "cdn-request@ops.ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ops.ietf.org/pub/lists/cdn.*", "type": "wg", "name": "Content Distribution Internetworking"}}, {"pk": 1520, "model": "group.group", "fields": {"charter": "charter-ietf-sls", "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "sls", "comments": "1st meeting at 49th IETF - San Diego, CA", "list_subscribe": "http://www.ist-tequila.org/sls.html", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Service Level Specification and Usage"}}, {"pk": 1521, "model": "group.group", "fields": {"charter": "charter-ietf-imxpbof", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "imxpbof", "comments": "1st meeting 49th IETF - San Diego, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IMXP"}}, {"pk": 1522, "model": "group.group", "fields": {"charter": "charter-ietf-webi", "unused_states": [], "ad": null, "parent": 934, "list_email": "webi@equinix.com", "acronym": "webi", "comments": "", "list_subscribe": "webi-request@equinix.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.wrec.org/webi-archive/", "type": "wg", "name": "Web Intermediaries"}}, {"pk": 1523, "model": "group.group", "fields": {"charter": "charter-ietf-c15n", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "c15n", "comments": "1st meeting at 49th IETF-San Diego, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Contextualization of Resolution"}}, -{"pk": 1524, "model": "group.group", "fields": {"charter": "charter-ietf-ccamp", "unused_states": [], "ad": 104198, "parent": 1249, "list_email": "ccamp@ietf.org", "acronym": "ccamp", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ccamp", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ccamp/", "type": "wg", "name": "Common Control and Measurement Plane"}}, -{"pk": 1525, "model": "group.group", "fields": {"charter": "charter-ietf-midcom", "unused_states": [], "ad": 17253, "parent": 1324, "list_email": "midcom@ietf.org", "acronym": "midcom", "comments": "1st meeting at 49th IETF-San Diego, CA", "list_subscribe": "midcom-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/midcom/", "type": "wg", "name": "Middlebox Communication"}}, +{"pk": 1524, "model": "group.group", "fields": {"charter": "charter-ietf-ccamp", "unused_states": [], "ad": null, "parent": 1249, "list_email": "ccamp@ietf.org", "acronym": "ccamp", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ccamp", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ccamp/", "type": "wg", "name": "Common Control and Measurement Plane"}}, +{"pk": 1525, "model": "group.group", "fields": {"charter": "charter-ietf-midcom", "unused_states": [], "ad": null, "parent": 1324, "list_email": "midcom@ietf.org", "acronym": "midcom", "comments": "1st meeting at 49th IETF-San Diego, CA", "list_subscribe": "midcom-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/midcom/", "type": "wg", "name": "Middlebox Communication"}}, {"pk": 1526, "model": "group.group", "fields": {"charter": "charter-ietf-multi6", "unused_states": [], "ad": null, "parent": 1193, "list_email": "multi6@ops.ietf.org", "acronym": "multi6", "comments": "1st meeting at 49th IETF-San Diego, CA", "list_subscribe": "majordomo@ops.ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "https://ops.ietf.org/lists/multi6", "type": "wg", "name": "Site Multihoming in IPv6"}}, -{"pk": 1527, "model": "group.group", "fields": {"charter": "charter-ietf-simple", "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "simple@ietf.org", "acronym": "simple", "comments": "1st meeting at 49th IETF-San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/simple", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/simple/", "type": "wg", "name": "SIP for Instant Messaging and Presence Leveraging Extensions"}}, +{"pk": 1527, "model": "group.group", "fields": {"charter": "charter-ietf-simple", "unused_states": [], "ad": null, "parent": 1683, "list_email": "simple@ietf.org", "acronym": "simple", "comments": "1st meeting at 49th IETF-San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/simple", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/simple/", "type": "wg", "name": "SIP for Instant Messaging and Presence Leveraging Extensions"}}, {"pk": 1528, "model": "group.group", "fields": {"charter": "charter-ietf-prim", "unused_states": [], "ad": null, "parent": 934, "list_email": "prim@ml.fujitsulabs.com", "acronym": "prim", "comments": "1st meeting at 49th IETF-San Diego, CA\r\nChaired by Diacakis , Athanassios", "list_subscribe": "majordomo@ml.fujitsulabs.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.imppwg.org/prim/ml-archive/", "type": "wg", "name": "Presence and Instant Messaging Protocol"}}, {"pk": 1529, "model": "group.group", "fields": {"charter": "charter-ietf-eos", "unused_states": [], "ad": null, "parent": 1193, "list_email": "eos@ops.ietf.org", "acronym": "eos", "comments": "", "list_subscribe": "eos-request@ops.ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ops.ietf.org/pub/lists/eos*", "type": "wg", "name": "Evolution of SNMP"}}, {"pk": 1530, "model": "group.group", "fields": {"charter": "charter-ietf-apex", "unused_states": [], "ad": null, "parent": 934, "list_email": "apexwg@lists.beepcore.org", "acronym": "apex", "comments": "", "list_subscribe": "apexwg-request@lists.beepcore.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.beepcore.org/mailman/listinfo/apexwg", "type": "wg", "name": "Application Exchange"}}, {"pk": 1531, "model": "group.group", "fields": {"charter": "charter-ietf-provreg", "unused_states": [], "ad": null, "parent": 934, "list_email": "https://www.ietf.org/mailman/listinfo/provreg", "acronym": "provreg", "comments": "1st meeting at 49th IETF in San Diego, called domreg.", "list_subscribe": "provreg@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/provreg/", "type": "wg", "name": "Provisioning Registry Protocol"}}, -{"pk": 1532, "model": "group.group", "fields": {"charter": "charter-ietf-midtax", "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "midtax", "comments": "1st meeting at 50th IETF - Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Middle box Taxonomy"}}, +{"pk": 1532, "model": "group.group", "fields": {"charter": "charter-ietf-midtax", "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "midtax", "comments": "1st meeting at 50th IETF - Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Middle box Taxonomy"}}, {"pk": 1533, "model": "group.group", "fields": {"charter": "charter-ietf-furi", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "furi", "comments": "1st meeting at 50th IETF - Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Future of Uniform Resource Identifiers"}}, {"pk": 1534, "model": "group.group", "fields": {"charter": "charter-ietf-urp", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "urp", "comments": "1st meeting at 50th IETF - Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "User Registration Protocol"}}, {"pk": 1535, "model": "group.group", "fields": {"charter": "charter-ietf-ipac", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "ipac", "comments": "1st meeting at 50th IETF-Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet Personal Appliance Control"}}, {"pk": 1536, "model": "group.group", "fields": {"charter": "charter-ietf-ptomaine", "unused_states": [], "ad": null, "parent": 1193, "list_email": "ptomaine@shrubbery.net", "acronym": "ptomaine", "comments": "1st meeting at 50th IETF-Minneapolis, MN", "list_subscribe": "majordomo@shrubbery.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.shrubbery.net/ptomaine", "type": "wg", "name": "Prefix Taxonomy Ongoing Measurement & Inter Network Experiment"}}, {"pk": 1537, "model": "group.group", "fields": {"charter": "charter-ietf-nsis", "unused_states": [], "ad": null, "parent": 1324, "list_email": "nsis@ietf.org", "acronym": "nsis", "comments": "1st meeting at 50th IETF-Minneapolis, MN", "list_subscribe": "nsis-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/nsis/", "type": "wg", "name": "Next Steps in Signaling"}}, -{"pk": 1538, "model": "group.group", "fields": {"charter": "charter-ietf-pwe3", "unused_states": [], "ad": 2329, "parent": 1249, "list_email": "pwe3@ietf.org", "acronym": "pwe3", "comments": "1st meeting at 50th IETF-Minneapolis, MN", "list_subscribe": "pwe3-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pwe3/", "type": "wg", "name": "Pseudowire Emulation Edge to Edge"}}, -{"pk": 1539, "model": "group.group", "fields": {"charter": "charter-ietf-ipoib", "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "ipoverib@ietf.org", "acronym": "ipoib", "comments": "1st meeting at 50th IETF-Minneapolis, MN\r\nwith the acronym of infinib (IP over InfiniBand plus MIBS", "list_subscribe": "ipoverib-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipoverib/", "type": "wg", "name": "IP over InfiniBand"}}, +{"pk": 1538, "model": "group.group", "fields": {"charter": "charter-ietf-pwe3", "unused_states": [], "ad": null, "parent": 1249, "list_email": "pwe3@ietf.org", "acronym": "pwe3", "comments": "1st meeting at 50th IETF-Minneapolis, MN", "list_subscribe": "pwe3-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pwe3/", "type": "wg", "name": "Pseudowire Emulation Edge to Edge"}}, +{"pk": 1539, "model": "group.group", "fields": {"charter": "charter-ietf-ipoib", "unused_states": [], "ad": null, "parent": 1052, "list_email": "ipoverib@ietf.org", "acronym": "ipoib", "comments": "1st meeting at 50th IETF-Minneapolis, MN\r\nwith the acronym of infinib (IP over InfiniBand plus MIBS", "list_subscribe": "ipoverib-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipoverib/", "type": "wg", "name": "IP over InfiniBand"}}, {"pk": 1540, "model": "group.group", "fields": {"charter": "charter-ietf-hip_conclded", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "hip_conclded", "comments": "1st meeting 50th IETF-Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Host Identity Payload"}}, -{"pk": 1542, "model": "group.group", "fields": {"charter": "charter-ietf-sipping", "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "sipping@ietf.org", "acronym": "sipping", "comments": "", "list_subscribe": "sipping-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sipping/", "type": "wg", "name": "Session Initiation Proposal Investigation"}}, -{"pk": 1543, "model": "group.group", "fields": {"charter": "charter-ietf-geopriv", "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "geopriv@ietf.org", "acronym": "geopriv", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/geopriv", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/geopriv/", "type": "wg", "name": "Geographic Location/Privacy"}}, -{"pk": 1544, "model": "group.group", "fields": {"charter": "charter-ietf-magma", "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "magma@ietf.org", "acronym": "magma", "comments": "", "list_subscribe": "magma-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/magma/", "type": "wg", "name": "Multicast & Anycast Group Membership"}}, +{"pk": 1542, "model": "group.group", "fields": {"charter": "charter-ietf-sipping", "unused_states": [], "ad": null, "parent": 1683, "list_email": "sipping@ietf.org", "acronym": "sipping", "comments": "", "list_subscribe": "sipping-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sipping/", "type": "wg", "name": "Session Initiation Proposal Investigation"}}, +{"pk": 1543, "model": "group.group", "fields": {"charter": "charter-ietf-geopriv", "unused_states": [], "ad": null, "parent": 1683, "list_email": "geopriv@ietf.org", "acronym": "geopriv", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/geopriv", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/geopriv/", "type": "wg", "name": "Geographic Location/Privacy"}}, +{"pk": 1544, "model": "group.group", "fields": {"charter": "charter-ietf-magma", "unused_states": [], "ad": null, "parent": 1052, "list_email": "magma@ietf.org", "acronym": "magma", "comments": "", "list_subscribe": "magma-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/magma/", "type": "wg", "name": "Multicast & Anycast Group Membership"}}, {"pk": 1545, "model": "group.group", "fields": {"charter": "charter-ietf-sasl", "unused_states": [], "ad": null, "parent": 1260, "list_email": "sasl@ietf.org", "acronym": "sasl", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/sasl", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sasl/", "type": "wg", "name": "Simple Authentication and Security Layer"}}, -{"pk": 1546, "model": "group.group", "fields": {"charter": "charter-ietf-ipfix", "unused_states": [], "ad": 105682, "parent": 1193, "list_email": "ipfix@ietf.org", "acronym": "ipfix", "comments": "", "list_subscribe": "http://www.ietf.org/mailman/listinfo/ipfix", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipfix", "type": "wg", "name": "IP Flow Information Export"}}, -{"pk": 1547, "model": "group.group", "fields": {"charter": "charter-ietf-ipv6", "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "ipv6@ietf.org", "acronym": "ipv6", "comments": "", "list_subscribe": "https://www1.ietf.org/mailman/listinfo/ipv6", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipv6/", "type": "wg", "name": "IP Version 6 Working Group"}}, +{"pk": 1546, "model": "group.group", "fields": {"charter": "charter-ietf-ipfix", "unused_states": [], "ad": null, "parent": 1193, "list_email": "ipfix@ietf.org", "acronym": "ipfix", "comments": "", "list_subscribe": "http://www.ietf.org/mailman/listinfo/ipfix", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipfix", "type": "wg", "name": "IP Flow Information Export"}}, +{"pk": 1547, "model": "group.group", "fields": {"charter": "charter-ietf-ipv6", "unused_states": [], "ad": null, "parent": 1052, "list_email": "ipv6@ietf.org", "acronym": "ipv6", "comments": "", "list_subscribe": "https://www1.ietf.org/mailman/listinfo/ipv6", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipv6/", "type": "wg", "name": "IP Version 6 Working Group"}}, {"pk": 1548, "model": "group.group", "fields": {"charter": "charter-ietf-inch", "unused_states": [], "ad": null, "parent": 1260, "list_email": "inch@nic.surfnet.nl", "acronym": "inch", "comments": "", "list_subscribe": "listserv@nic.surfnet.nl", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://listserv.surfnet.nl/archives/inch.html", "type": "wg", "name": "Extended Incident Handling"}}, {"pk": 1549, "model": "group.group", "fields": {"charter": "charter-ietf-irnss", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "irnss", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet Resource Name Search Service"}}, -{"pk": 1550, "model": "group.group", "fields": {"charter": "charter-ietf-pana", "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "pana@ietf.org", "acronym": "pana", "comments": "52nd IETF, Salt Lake City, Utah", "list_subscribe": "https://www1.ietf.org/mailman/listinfo/pana", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pana/", "type": "wg", "name": "Protocol for carrying Authentication for Network Access"}}, +{"pk": 1550, "model": "group.group", "fields": {"charter": "charter-ietf-pana", "unused_states": [], "ad": null, "parent": 1052, "list_email": "pana@ietf.org", "acronym": "pana", "comments": "52nd IETF, Salt Lake City, Utah", "list_subscribe": "https://www1.ietf.org/mailman/listinfo/pana", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pana/", "type": "wg", "name": "Protocol for carrying Authentication for Network Access"}}, {"pk": 1551, "model": "group.group", "fields": {"charter": "charter-ietf-intloc", "unused_states": [], "ad": null, "parent": 934, "list_email": "intloc@ops.ietf.org", "acronym": "intloc", "comments": "52nd IETF - Salt Lake City, UT", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internationalization and Localization of Internet Protocols"}}, -{"pk": 1553, "model": "group.group", "fields": {"charter": "charter-ietf-mplsoam", "unused_states": [], "ad": 103264, "parent": 1541, "list_email": "", "acronym": "mplsoam", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "MPLS Maintenance Mechanisms"}}, +{"pk": 1553, "model": "group.group", "fields": {"charter": "charter-ietf-mplsoam", "unused_states": [], "ad": null, "parent": 1541, "list_email": "", "acronym": "mplsoam", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "MPLS Maintenance Mechanisms"}}, {"pk": 1554, "model": "group.group", "fields": {"charter": "charter-ietf-ndmp", "unused_states": [], "ad": null, "parent": 934, "list_email": "ndmp-tech@ndmp.org", "acronym": "ndmp", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network Data Management Protocol"}}, {"pk": 1555, "model": "group.group", "fields": {"charter": "charter-ietf-ippt", "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "ippt", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IP Path Tracing"}}, {"pk": 1556, "model": "group.group", "fields": {"charter": "charter-ietf-ieprep", "unused_states": [], "ad": null, "parent": 1683, "list_email": "ieprep@ietf.org", "acronym": "ieprep", "comments": "", "list_subscribe": "ieprep-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ieprep/", "type": "wg", "name": "Internet Emergency Preparedness"}}, @@ -712,289 +712,289 @@ {"pk": 1561, "model": "group.group", "fields": {"charter": "charter-ietf-siked", "unused_states": [], "ad": null, "parent": 1193, "list_email": "keydist@cafax.se", "acronym": "siked", "comments": "1st meeting - 53rd IETF in Minneapolis, MN.", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Secure Internet Key Distribution"}}, {"pk": 1562, "model": "group.group", "fields": {"charter": "charter-ietf-kwns", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "kwns", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Keywords Naming Services"}}, {"pk": 1563, "model": "group.group", "fields": {"charter": "charter-ietf-crisp", "unused_states": [], "ad": null, "parent": 934, "list_email": "crisp@ietf.org", "acronym": "crisp", "comments": "1st meeting at 53rd IETF in Minneapolis, MN", "list_subscribe": "https://www.ietf.org/mailman/listinfo/crisp", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/crisp", "type": "wg", "name": "Cross Registry Information Service Protocol"}}, -{"pk": 1564, "model": "group.group", "fields": {"charter": "charter-ietf-psamp", "unused_states": [], "ad": 6699, "parent": 1193, "list_email": "psamp@ietf.org", "acronym": "psamp", "comments": "1st meeting at 53rd IETF in Minneapolis, MN", "list_subscribe": "psamp-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/psamp/", "type": "wg", "name": "Packet Sampling"}}, +{"pk": 1564, "model": "group.group", "fields": {"charter": "charter-ietf-psamp", "unused_states": [], "ad": null, "parent": 1193, "list_email": "psamp@ietf.org", "acronym": "psamp", "comments": "1st meeting at 53rd IETF in Minneapolis, MN", "list_subscribe": "psamp-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/psamp/", "type": "wg", "name": "Packet Sampling"}}, {"pk": 1565, "model": "group.group", "fields": {"charter": "charter-ietf-monet", "unused_states": [], "ad": null, "parent": 1052, "list_email": "monet@nal.motlabs.com", "acronym": "monet", "comments": "1st meeting at 53rd IETF in Minneapolis, MN", "list_subscribe": "http://www.nal.motlabs.com/mailman/listinfo/monet", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.nal.motlabs.com/mailman/listinfo/monet", "type": "wg", "name": "Mobile Networks"}}, -{"pk": 1566, "model": "group.group", "fields": {"charter": "charter-ietf-speechsc", "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "speechsc@ietf.org", "acronym": "speechsc", "comments": "1st meeting at 53rd IETF in Minneapolis, MN. Was called Control of ASR and TTS Servers (cats)", "list_subscribe": "https://www.ietf.org/mailman/listinfo/speechsc", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/speechsc/", "type": "wg", "name": "Speech Services Control"}}, +{"pk": 1566, "model": "group.group", "fields": {"charter": "charter-ietf-speechsc", "unused_states": [], "ad": null, "parent": 1683, "list_email": "speechsc@ietf.org", "acronym": "speechsc", "comments": "1st meeting at 53rd IETF in Minneapolis, MN. Was called Control of ASR and TTS Servers (cats)", "list_subscribe": "https://www.ietf.org/mailman/listinfo/speechsc", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/speechsc/", "type": "wg", "name": "Speech Services Control"}}, {"pk": 1567, "model": "group.group", "fields": {"charter": "charter-ietf-rpsec", "unused_states": [], "ad": null, "parent": 1249, "list_email": "rpsec@ietf.org", "acronym": "rpsec", "comments": "1st meeting at 53rd IETF in Minneapolis, MN", "list_subscribe": "rpsec-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rpsec/", "type": "wg", "name": "Routing Protocol Security Requirements"}}, -{"pk": 1568, "model": "group.group", "fields": {"charter": "charter-ietf-nomcom", "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "ietf-nomcom@lists.elistx.com", "acronym": "nomcom", "comments": "", "list_subscribe": "ietf-nomcom-request@lists.elistx.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.elistx.com/archives/ietf-nomcom/", "type": "wg", "name": "Operation of the IESG/IAB Nominating and Recall Committees"}}, +{"pk": 1568, "model": "group.group", "fields": {"charter": "charter-ietf-nomcom", "unused_states": [], "ad": null, "parent": 1008, "list_email": "ietf-nomcom@lists.elistx.com", "acronym": "nomcom", "comments": "", "list_subscribe": "ietf-nomcom-request@lists.elistx.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.elistx.com/archives/ietf-nomcom/", "type": "wg", "name": "Operation of the IESG/IAB Nominating and Recall Committees"}}, {"pk": 1569, "model": "group.group", "fields": {"charter": "charter-ietf-xmpp-old", "unused_states": [], "ad": null, "parent": 934, "list_email": "xmppwg@xmpp.org", "acronym": "xmpp-old", "comments": "First meeting at the 54th IETF in Yokohama, Japan.", "list_subscribe": "xmppwg-request@xmpp.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://mail.jabber.org/pipermail/xmppwg/", "type": "wg", "name": "Extensible Messaging and Presence Protocol"}}, {"pk": 1570, "model": "group.group", "fields": {"charter": "charter-ietf-send", "unused_states": [], "ad": null, "parent": 1052, "list_email": "ietf-send@standards.ericsson.net", "acronym": "send", "comments": "First meeting at the 54th IETF in Yokohama, Japan.", "list_subscribe": "Majordomo@standards.ericsson.net", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://standards.ericsson.net/lists/ietf-send/threads.html", "type": "wg", "name": "Securing Neighbor Discovery"}}, -{"pk": 1571, "model": "group.group", "fields": {"charter": "charter-ietf-dccp", "unused_states": [], "ad": 110856, "parent": 1324, "list_email": "dccp@ietf.org", "acronym": "dccp", "comments": "", "list_subscribe": "dccp-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dccp/", "type": "wg", "name": "Datagram Congestion Control Protocol"}}, -{"pk": 1572, "model": "group.group", "fields": {"charter": "charter-ietf-ipr", "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "ipr-wg@ietf.org", "acronym": "ipr", "comments": "", "list_subscribe": "ipr-wg-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipr-wg/", "type": "wg", "name": "Intellectual Property Rights"}}, +{"pk": 1571, "model": "group.group", "fields": {"charter": "charter-ietf-dccp", "unused_states": [], "ad": null, "parent": 1324, "list_email": "dccp@ietf.org", "acronym": "dccp", "comments": "", "list_subscribe": "dccp-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dccp/", "type": "wg", "name": "Datagram Congestion Control Protocol"}}, +{"pk": 1572, "model": "group.group", "fields": {"charter": "charter-ietf-ipr", "unused_states": [], "ad": null, "parent": 1008, "list_email": "ipr-wg@ietf.org", "acronym": "ipr", "comments": "", "list_subscribe": "ipr-wg-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipr-wg/", "type": "wg", "name": "Intellectual Property Rights"}}, {"pk": 1573, "model": "group.group", "fields": {"charter": "charter-ietf-rddp", "unused_states": [], "ad": null, "parent": 1324, "list_email": "rddp@ietf.org", "acronym": "rddp", "comments": "1st Meeting at the 54th IETF in Yokohama, Japan", "list_subscribe": "rddp-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rddp/", "type": "wg", "name": "Remote Direct Data Placement"}}, {"pk": 1574, "model": "group.group", "fields": {"charter": "charter-ietf-tist", "unused_states": [], "ad": null, "parent": 1324, "list_email": "tist@cisco.com", "acronym": "tist", "comments": "1st Meeting at the 54th IETF in Yokohama, Japan", "list_subscribe": "mailer@cisco.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.mail-archive.com/tist%40external.cisco.com/", "type": "wg", "name": "Topology-Insensitive Service Traversal"}}, -{"pk": 1575, "model": "group.group", "fields": {"charter": "charter-ietf-netconf", "unused_states": [], "ad": 105682, "parent": 1193, "list_email": "netconf@ietf.org", "acronym": "netconf", "comments": "1st meeting at the 54th IETF in Yokohama, Japan", "list_subscribe": "https://www.ietf.org/mailman/listinfo/netconf", "state": "active", "time": "2012-09-20 09:57:02", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/netconf/", "type": "wg", "name": "Network Configuration"}}, -{"pk": 1576, "model": "group.group", "fields": {"charter": "charter-ietf-nemo", "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "nemo@ietf.org", "acronym": "nemo", "comments": "1st meeting at the 54 IETF in Yokohama, Japan", "list_subscribe": "nemo-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/nemo/", "type": "wg", "name": "Network Mobility"}}, -{"pk": 1578, "model": "group.group", "fields": {"charter": "charter-ietf-v6ops", "unused_states": [], "ad": 101568, "parent": 1193, "list_email": "v6ops@ietf.org", "acronym": "v6ops", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/v6ops", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/v6ops/", "type": "wg", "name": "IPv6 Operations"}}, +{"pk": 1575, "model": "group.group", "fields": {"charter": "charter-ietf-netconf", "unused_states": [], "ad": null, "parent": 1193, "list_email": "netconf@ietf.org", "acronym": "netconf", "comments": "1st meeting at the 54th IETF in Yokohama, Japan", "list_subscribe": "https://www.ietf.org/mailman/listinfo/netconf", "state": "active", "time": "2012-09-20 09:57:02", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/netconf/", "type": "wg", "name": "Network Configuration"}}, +{"pk": 1576, "model": "group.group", "fields": {"charter": "charter-ietf-nemo", "unused_states": [], "ad": null, "parent": 1052, "list_email": "nemo@ietf.org", "acronym": "nemo", "comments": "1st meeting at the 54 IETF in Yokohama, Japan", "list_subscribe": "nemo-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/nemo/", "type": "wg", "name": "Network Mobility"}}, +{"pk": 1578, "model": "group.group", "fields": {"charter": "charter-ietf-v6ops", "unused_states": [], "ad": null, "parent": 1193, "list_email": "v6ops@ietf.org", "acronym": "v6ops", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/v6ops", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/v6ops/", "type": "wg", "name": "IPv6 Operations"}}, {"pk": 1579, "model": "group.group", "fields": {"charter": "charter-ietf-jxta", "unused_states": [], "ad": null, "parent": 934, "list_email": "discuss@jxta.org mailing", "acronym": "jxta", "comments": "1st meeting at 55th IETF in Atlanta, GA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "JXTA"}}, {"pk": 1580, "model": "group.group", "fields": {"charter": "charter-ietf-ipseckey", "unused_states": [], "ad": null, "parent": 1260, "list_email": "ipseckey@ietf.org", "acronym": "ipseckey", "comments": "1st meeting at the 55th IETF in Atlanta, GA", "list_subscribe": "ipseckey-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipseckey/", "type": "wg", "name": "IPSEC KEYing information resource record"}}, {"pk": 1581, "model": "group.group", "fields": {"charter": "charter-ietf-lemonade", "unused_states": [], "ad": null, "parent": 934, "list_email": "lemonade@ietf.org", "acronym": "lemonade", "comments": "1st meeting at the 54th IETF in Yokohama, Japan", "list_subscribe": "lemonade-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/lemonade/", "type": "wg", "name": "Enhancements to Internet email to Support Diverse Service Environments"}}, {"pk": 1582, "model": "group.group", "fields": {"charter": "charter-ietf-zerouter", "unused_states": [], "ad": null, "parent": 1052, "list_email": "zerouter@internet.motlabs.com", "acronym": "zerouter", "comments": "1st Meeting at 55th IETF in Atlanta, GA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://internet.motlabs.com/mailman/listinfo/zerouter", "type": "wg", "name": "Zeroconf Router"}}, {"pk": 1583, "model": "group.group", "fields": {"charter": "charter-ietf-trigtran", "unused_states": [], "ad": null, "parent": 1324, "list_email": "trigtran@ietf.org", "acronym": "trigtran", "comments": "1st meeting at 55th IETF in Atlanta, GA", "list_subscribe": "trigtran-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/trigtran/", "type": "wg", "name": "Triggers for Transport"}}, -{"pk": 1584, "model": "group.group", "fields": {"charter": "charter-ietf-grow", "unused_states": [], "ad": 101568, "parent": 1193, "list_email": "grow@ietf.org", "acronym": "grow", "comments": "1st meeting at the 56th IETF in San Francisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/grow", "state": "active", "time": "2012-02-01 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/grow", "type": "wg", "name": "Global Routing Operations"}}, -{"pk": 1585, "model": "group.group", "fields": {"charter": "charter-ietf-problem", "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "problem-statement@alvestrand.no", "acronym": "problem", "comments": "1st meeting at the 56th IETF in San Francisco, CA", "list_subscribe": "problem-statement-request@alvestrand.no", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.alvestrand.no/pipermail/problem-statement/", "type": "wg", "name": "Problem Statement"}}, +{"pk": 1584, "model": "group.group", "fields": {"charter": "charter-ietf-grow", "unused_states": [], "ad": null, "parent": 1193, "list_email": "grow@ietf.org", "acronym": "grow", "comments": "1st meeting at the 56th IETF in San Francisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/grow", "state": "active", "time": "2012-02-01 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/grow", "type": "wg", "name": "Global Routing Operations"}}, +{"pk": 1585, "model": "group.group", "fields": {"charter": "charter-ietf-problem", "unused_states": [], "ad": null, "parent": 1008, "list_email": "problem-statement@alvestrand.no", "acronym": "problem", "comments": "1st meeting at the 56th IETF in San Francisco, CA", "list_subscribe": "problem-statement-request@alvestrand.no", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.alvestrand.no/pipermail/problem-statement/", "type": "wg", "name": "Problem Statement"}}, {"pk": 1586, "model": "group.group", "fields": {"charter": "charter-ietf-pads", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "pads", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Path-Decoupled Signaling"}}, {"pk": 1587, "model": "group.group", "fields": {"charter": "charter-ietf-intersec", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "intersec", "comments": "1st meeting at 56th IETF in San Francisco, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Transport Service at Intermediary"}}, {"pk": 1588, "model": "group.group", "fields": {"charter": "charter-ietf-plpmtud", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "plpmtud", "comments": "1st meeting at 56th IETF in San Francisco, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Packetization Layer Path MTU Discovery"}}, {"pk": 1589, "model": "group.group", "fields": {"charter": "charter-ietf-nsiim", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "nsiim", "comments": "1st meeting at th 56th IETF in San Francisco, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Next Steps in IP Mobility"}}, {"pk": 1590, "model": "group.group", "fields": {"charter": "charter-ietf-enroll", "unused_states": [], "ad": null, "parent": 1260, "list_email": "ietf-enroll@mit.edu", "acronym": "enroll", "comments": "1st meeting at 57th IETF in Vienna, Austria; 2nd meeting at 58th IETF, Minneapolis, MN", "list_subscribe": "ietf-enroll-request@mit.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://mailman.mit.edu/pipermail/ietf-enroll/", "type": "wg", "name": "Credential and Provisioning"}}, -{"pk": 1591, "model": "group.group", "fields": {"charter": "charter-ietf-edu", "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "wgchairs-training@ops.ietf.org", "acronym": "edu", "comments": "1st meeting at 57th IETF-Vienna, Austria; 2nd meeting at 64th IETF-Vancouver, BC", "list_subscribe": "majordomo@ops.ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://ops.ietf.org/lists/wgchairs-training/", "type": "team", "name": "Education"}}, +{"pk": 1591, "model": "group.group", "fields": {"charter": "charter-ietf-edu", "unused_states": [], "ad": null, "parent": 1008, "list_email": "wgchairs-training@ops.ietf.org", "acronym": "edu", "comments": "1st meeting at 57th IETF-Vienna, Austria; 2nd meeting at 64th IETF-Vancouver, BC", "list_subscribe": "majordomo@ops.ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://ops.ietf.org/lists/wgchairs-training/", "type": "team", "name": "Education"}}, {"pk": 1592, "model": "group.group", "fields": {"charter": "charter-ietf-pmutd", "unused_states": [], "ad": null, "parent": 1324, "list_email": "mtu@psc.edu", "acronym": "pmutd", "comments": "", "list_subscribe": "majordomo@psc.edu with", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.psc.edu/~mathis/MTU/mbox.txt", "type": "wg", "name": "Path Maximum Transmission Unit Discovery"}}, -{"pk": 1593, "model": "group.group", "fields": {"charter": "charter-ietf-l2vpn", "unused_states": [], "ad": 2329, "parent": 1249, "list_email": "l2vpn@ietf.org", "acronym": "l2vpn", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/l2vpn", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/l2vpn/", "type": "wg", "name": "Layer 2 Virtual Private Networks"}}, -{"pk": 1594, "model": "group.group", "fields": {"charter": "charter-ietf-l3vpn", "unused_states": [], "ad": 2329, "parent": 1249, "list_email": "l3vpn@ietf.org", "acronym": "l3vpn", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/l3vpn", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/l3vpn/", "type": "wg", "name": "Layer 3 Virtual Private Networks"}}, -{"pk": 1595, "model": "group.group", "fields": {"charter": "charter-ietf-coach", "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "ietf-quality@bogus.com", "acronym": "coach", "comments": "1st meeting at the 57th IETF in Vienna, Austria", "list_subscribe": "majordomo@psg.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://psg.com/lists/ietf-quality", "type": "wg", "name": "Comprehensive apprOACH to quality"}}, -{"pk": 1596, "model": "group.group", "fields": {"charter": "charter-ietf-mip4", "unused_states": [], "ad": 100664, "parent": 1052, "list_email": "mip4@ietf.org", "acronym": "mip4", "comments": "1st meeting at the 57th IETF in Vienna, Austria", "list_subscribe": "mip4-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mip4/", "type": "wg", "name": "Mobility for IPv4"}}, -{"pk": 1597, "model": "group.group", "fields": {"charter": "charter-ietf-mip6", "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "mip6@ietf.org", "acronym": "mip6", "comments": "1st meeting at the 57th IETF in Vienna, Austria", "list_subscribe": "https://www.ietf.org/mailman/listinfo/mip6", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mip6/", "type": "wg", "name": "Mobility for IPv6"}}, -{"pk": 1598, "model": "group.group", "fields": {"charter": "charter-ietf-mipshop", "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "mipshop@ietf.org", "acronym": "mipshop", "comments": "1st meeting at the 57th IETF in Vienna, Austria", "list_subscribe": "mipshop-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mipshop/", "type": "wg", "name": "Mobility for IP: Performance, Signaling and Handoff Optimization"}}, -{"pk": 1599, "model": "group.group", "fields": {"charter": "charter-ietf-opsec", "unused_states": [], "ad": 101568, "parent": 1193, "list_email": "opsec@ietf.org", "acronym": "opsec", "comments": "email archives 2007 and prior: http://ops.ietf.org/lists/opsec/\r\n\r\n1st meeting at the 57th IETF in Vienna, Austria; 2nd meeting at 59th IETF-Seoul, Korea; 3rd meeting at 60th IETF - San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/opsec", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/opsec/", "type": "wg", "name": "Operational Security Capabilities for IP Network Infrastructure"}}, -{"pk": 1600, "model": "group.group", "fields": {"charter": "charter-ietf-capwap", "unused_states": [], "ad": 6699, "parent": 1193, "list_email": "capwap@frascone.com", "acronym": "capwap", "comments": "1st meeting at the 57th IETF in Vienna, Austria", "list_subscribe": "http://lists.frascone.com/mailman/listinfo/capwap", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.frascone.com/pipermail/capwap", "type": "wg", "name": "Control And Provisioning of Wireless Access Points"}}, -{"pk": 1601, "model": "group.group", "fields": {"charter": "charter-ietf-xcon", "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "xcon@ietf.org", "acronym": "xcon", "comments": "1st meeting at the 57th IETF in Vienna, Austria", "list_subscribe": "https://www.ietf.org/mailman/listinfo/xcon", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/xcon/", "type": "wg", "name": "Centralized Conferencing"}}, +{"pk": 1593, "model": "group.group", "fields": {"charter": "charter-ietf-l2vpn", "unused_states": [], "ad": null, "parent": 1249, "list_email": "l2vpn@ietf.org", "acronym": "l2vpn", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/l2vpn", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/l2vpn/", "type": "wg", "name": "Layer 2 Virtual Private Networks"}}, +{"pk": 1594, "model": "group.group", "fields": {"charter": "charter-ietf-l3vpn", "unused_states": [], "ad": null, "parent": 1249, "list_email": "l3vpn@ietf.org", "acronym": "l3vpn", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/l3vpn", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/l3vpn/", "type": "wg", "name": "Layer 3 Virtual Private Networks"}}, +{"pk": 1595, "model": "group.group", "fields": {"charter": "charter-ietf-coach", "unused_states": [], "ad": null, "parent": 1008, "list_email": "ietf-quality@bogus.com", "acronym": "coach", "comments": "1st meeting at the 57th IETF in Vienna, Austria", "list_subscribe": "majordomo@psg.com", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://psg.com/lists/ietf-quality", "type": "wg", "name": "Comprehensive apprOACH to quality"}}, +{"pk": 1596, "model": "group.group", "fields": {"charter": "charter-ietf-mip4", "unused_states": [], "ad": null, "parent": 1052, "list_email": "mip4@ietf.org", "acronym": "mip4", "comments": "1st meeting at the 57th IETF in Vienna, Austria", "list_subscribe": "mip4-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mip4/", "type": "wg", "name": "Mobility for IPv4"}}, +{"pk": 1597, "model": "group.group", "fields": {"charter": "charter-ietf-mip6", "unused_states": [], "ad": null, "parent": 1052, "list_email": "mip6@ietf.org", "acronym": "mip6", "comments": "1st meeting at the 57th IETF in Vienna, Austria", "list_subscribe": "https://www.ietf.org/mailman/listinfo/mip6", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mip6/", "type": "wg", "name": "Mobility for IPv6"}}, +{"pk": 1598, "model": "group.group", "fields": {"charter": "charter-ietf-mipshop", "unused_states": [], "ad": null, "parent": 1052, "list_email": "mipshop@ietf.org", "acronym": "mipshop", "comments": "1st meeting at the 57th IETF in Vienna, Austria", "list_subscribe": "mipshop-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mipshop/", "type": "wg", "name": "Mobility for IP: Performance, Signaling and Handoff Optimization"}}, +{"pk": 1599, "model": "group.group", "fields": {"charter": "charter-ietf-opsec", "unused_states": [], "ad": null, "parent": 1193, "list_email": "opsec@ietf.org", "acronym": "opsec", "comments": "email archives 2007 and prior: http://ops.ietf.org/lists/opsec/\r\n\r\n1st meeting at the 57th IETF in Vienna, Austria; 2nd meeting at 59th IETF-Seoul, Korea; 3rd meeting at 60th IETF - San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/opsec", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/opsec/", "type": "wg", "name": "Operational Security Capabilities for IP Network Infrastructure"}}, +{"pk": 1600, "model": "group.group", "fields": {"charter": "charter-ietf-capwap", "unused_states": [], "ad": null, "parent": 1193, "list_email": "capwap@frascone.com", "acronym": "capwap", "comments": "1st meeting at the 57th IETF in Vienna, Austria", "list_subscribe": "http://lists.frascone.com/mailman/listinfo/capwap", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.frascone.com/pipermail/capwap", "type": "wg", "name": "Control And Provisioning of Wireless Access Points"}}, +{"pk": 1601, "model": "group.group", "fields": {"charter": "charter-ietf-xcon", "unused_states": [], "ad": null, "parent": 1683, "list_email": "xcon@ietf.org", "acronym": "xcon", "comments": "1st meeting at the 57th IETF in Vienna, Austria", "list_subscribe": "https://www.ietf.org/mailman/listinfo/xcon", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/xcon/", "type": "wg", "name": "Centralized Conferencing"}}, {"pk": 1602, "model": "group.group", "fields": {"charter": "charter-ietf-ispmon", "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "ispmon", "comments": "1st meeting at 57th IETF in Vienna, Austria", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Monitoring Infrastructure Deployment"}}, {"pk": 1603, "model": "group.group", "fields": {"charter": "charter-ietf-ddbof", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "ddbof", "comments": "1st meeting at the 57th IETF in Vienna, Austria", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Device Discovery"}}, -{"pk": 1604, "model": "group.group", "fields": {"charter": "charter-ietf-ipdvb", "unused_states": [], "ad": 21072, "parent": 934, "list_email": "ipdvb@erg.abdn.ac.uk", "acronym": "ipdvb", "comments": "1st meeting at 57th IETF in Vienna, Austria", "list_subscribe": "majordomo@erg.abdn.ac.uk", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.erg.abdn.ac.uk/ipdvb/archive/", "type": "wg", "name": "IP over DVB"}}, +{"pk": 1604, "model": "group.group", "fields": {"charter": "charter-ietf-ipdvb", "unused_states": [], "ad": null, "parent": 934, "list_email": "ipdvb@erg.abdn.ac.uk", "acronym": "ipdvb", "comments": "1st meeting at 57th IETF in Vienna, Austria", "list_subscribe": "majordomo@erg.abdn.ac.uk", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.erg.abdn.ac.uk/ipdvb/archive/", "type": "wg", "name": "IP over DVB"}}, {"pk": 1605, "model": "group.group", "fields": {"charter": "charter-ietf-mlm", "unused_states": [], "ad": null, "parent": 1249, "list_email": "mtp@shepfarm.com", "acronym": "mlm", "comments": "1st meeting at 57th IETF in Vienna, Austria", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.shepfarm.com/mailman/listinfo/mtp", "type": "wg", "name": "Multicast Last Mile"}}, {"pk": 1606, "model": "group.group", "fields": {"charter": "charter-ietf-alias", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "alias", "comments": "1st meeting at 57th IETF in Vienna, Austria", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Access Link Intermediaries Assisting Services"}}, -{"pk": 1607, "model": "group.group", "fields": {"charter": "charter-ietf-dna", "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "dna@eng.monash.edu.au", "acronym": "dna", "comments": "1st meeting at th 57th IETF in Vienna, Austria", "list_subscribe": "majordomo@ecselists.eng.monash.edu.au", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://ecselists.eng.monash.edu.au/~warchive/dna/", "type": "wg", "name": "Detecting Network Attachment"}}, +{"pk": 1607, "model": "group.group", "fields": {"charter": "charter-ietf-dna", "unused_states": [], "ad": null, "parent": 1052, "list_email": "dna@eng.monash.edu.au", "acronym": "dna", "comments": "1st meeting at th 57th IETF in Vienna, Austria", "list_subscribe": "majordomo@ecselists.eng.monash.edu.au", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://ecselists.eng.monash.edu.au/~warchive/dna/", "type": "wg", "name": "Detecting Network Attachment"}}, {"pk": 1608, "model": "group.group", "fields": {"charter": "charter-ietf-pmtud", "unused_states": [], "ad": null, "parent": 1324, "list_email": "pmtud@ietf.org", "acronym": "pmtud", "comments": "", "list_subscribe": "pmtud-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pmtud/", "type": "wg", "name": "Path MTU Discovery"}}, -{"pk": 1609, "model": "group.group", "fields": {"charter": "charter-ietf-imss", "unused_states": [], "ad": 6699, "parent": 1193, "list_email": "imss@ietf.org", "acronym": "imss", "comments": "", "list_subscribe": "https://www1.ietf.org/mailman/listinfo/imss", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/imss/", "type": "wg", "name": "Internet and Management Support for Storage"}}, -{"pk": 1610, "model": "group.group", "fields": {"charter": "charter-ietf-saad", "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "saad@ietf.org", "acronym": "saad", "comments": "", "list_subscribe": "http://www.ietf.org/mail-archive/web/saad/index.html", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.ietf.org/ietf-mail-archive/saad", "type": "wg", "name": "Scope Addressing Architecture Discussion"}}, -{"pk": 1611, "model": "group.group", "fields": {"charter": "charter-ietf-ltans", "unused_states": [], "ad": 19483, "parent": 934, "list_email": "ltans@ietf.org", "acronym": "ltans", "comments": "", "list_subscribe": "http://www.ietf.org/mailman/listinfo/ltans", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ltans/", "type": "wg", "name": "Long-Term Archive and Notary Services"}}, -{"pk": 1612, "model": "group.group", "fields": {"charter": "charter-ietf-radext", "unused_states": [], "ad": 105682, "parent": 1193, "list_email": "radext@ietf.org", "acronym": "radext", "comments": "1st meeting at the 58th IETF in Minneapolis, MN; 2nd meeting at 60th IETF - San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/radext", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/radext/", "type": "wg", "name": "RADIUS EXTensions"}}, +{"pk": 1609, "model": "group.group", "fields": {"charter": "charter-ietf-imss", "unused_states": [], "ad": null, "parent": 1193, "list_email": "imss@ietf.org", "acronym": "imss", "comments": "", "list_subscribe": "https://www1.ietf.org/mailman/listinfo/imss", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/imss/", "type": "wg", "name": "Internet and Management Support for Storage"}}, +{"pk": 1610, "model": "group.group", "fields": {"charter": "charter-ietf-saad", "unused_states": [], "ad": null, "parent": 1008, "list_email": "saad@ietf.org", "acronym": "saad", "comments": "", "list_subscribe": "http://www.ietf.org/mail-archive/web/saad/index.html", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "ftp://ftp.ietf.org/ietf-mail-archive/saad", "type": "wg", "name": "Scope Addressing Architecture Discussion"}}, +{"pk": 1611, "model": "group.group", "fields": {"charter": "charter-ietf-ltans", "unused_states": [], "ad": null, "parent": 934, "list_email": "ltans@ietf.org", "acronym": "ltans", "comments": "", "list_subscribe": "http://www.ietf.org/mailman/listinfo/ltans", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ltans/", "type": "wg", "name": "Long-Term Archive and Notary Services"}}, +{"pk": 1612, "model": "group.group", "fields": {"charter": "charter-ietf-radext", "unused_states": [], "ad": null, "parent": 1193, "list_email": "radext@ietf.org", "acronym": "radext", "comments": "1st meeting at the 58th IETF in Minneapolis, MN; 2nd meeting at 60th IETF - San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/radext", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/radext/", "type": "wg", "name": "RADIUS EXTensions"}}, {"pk": 1613, "model": "group.group", "fields": {"charter": "charter-ietf-pki4ipsec", "unused_states": [], "ad": null, "parent": 1260, "list_email": "pki4ipsec@icsalabs.com", "acronym": "pki4ipsec", "comments": "1st meeting at 58th IETF-Minneapolis, MN", "list_subscribe": "http://honor.icsalabs.com/mailman/listinfo/pki4ipsec", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://honor.icsalabs.com/mailman/listinfo/pki4ipsec", "type": "wg", "name": "Profiling Use of PKI in IPSEC"}}, -{"pk": 1614, "model": "group.group", "fields": {"charter": "charter-ietf-newtrk", "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "newtrk@lists.uoregon.edu", "acronym": "newtrk", "comments": "1st meeting at 58th IETF-Minneapolis, MN; 2nd meeting at 59th IETF-Seoul, Korea", "list_subscribe": "newtrk-request@lists.uoregon.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/newtrk", "type": "wg", "name": "New IETF Standards Track Discussion"}}, +{"pk": 1614, "model": "group.group", "fields": {"charter": "charter-ietf-newtrk", "unused_states": [], "ad": null, "parent": 1008, "list_email": "newtrk@lists.uoregon.edu", "acronym": "newtrk", "comments": "1st meeting at 58th IETF-Minneapolis, MN; 2nd meeting at 59th IETF-Seoul, Korea", "list_subscribe": "newtrk-request@lists.uoregon.edu", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/newtrk", "type": "wg", "name": "New IETF Standards Track Discussion"}}, {"pk": 1615, "model": "group.group", "fields": {"charter": "charter-ietf-iea", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "iea", "comments": "1st meeting at 58th IETF-Minneapolis, MN; 2nd meeting at 59th IETF-Seoul, Korea", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internationalizing Email Address"}}, {"pk": 1616, "model": "group.group", "fields": {"charter": "charter-ietf-hipbof", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "hipbof", "comments": "1st meeting at 58th IETF-Minneapolis, MN; 2nd meeting at 59th IETF-Seoul, Korea", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Host Identity Protocol BOF"}}, {"pk": 1617, "model": "group.group", "fields": {"charter": "charter-ietf-mobike", "unused_states": [], "ad": null, "parent": 1260, "list_email": "mobike@machshav.com", "acronym": "mobike", "comments": "1st meeting at 58th IETF-Minneapolis, MN;2nd meeting at 59th IETF-Seoul, Korea", "list_subscribe": "https://www.machshav.com/mailman/listinfo.cgi/mobike", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "https://www.machshav.com/pipermail/mobike/", "type": "wg", "name": "IKEv2 Mobility and Multihoming"}}, {"pk": 1618, "model": "group.group", "fields": {"charter": "charter-ietf-sbsm", "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "sbsm", "comments": "1st meeting 58th IETF-Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Session Based Security Model for SNMPv3"}}, -{"pk": 1619, "model": "group.group", "fields": {"charter": "charter-ietf-rtgwg", "unused_states": [], "ad": 2329, "parent": 1249, "list_email": "rtgwg@ietf.org", "acronym": "rtgwg", "comments": "", "list_subscribe": "rtgwg-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rtgwg/", "type": "wg", "name": "Routing Area Working Group"}}, -{"pk": 1620, "model": "group.group", "fields": {"charter": "charter-ietf-tcpm", "unused_states": [], "ad": 110856, "parent": 1324, "list_email": "tcpm@ietf.org", "acronym": "tcpm", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/tcpm", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/tcpm/", "type": "wg", "name": "TCP Maintenance and Minor Extensions"}}, -{"pk": 1621, "model": "group.group", "fields": {"charter": "charter-ietf-icar", "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "icar@ietf.org", "acronym": "icar", "comments": "1st meeting at 59th IETF-Seoul, Korea", "list_subscribe": "icar-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/icar/", "type": "wg", "name": "Improved Cross-Area Review"}}, +{"pk": 1619, "model": "group.group", "fields": {"charter": "charter-ietf-rtgwg", "unused_states": [], "ad": null, "parent": 1249, "list_email": "rtgwg@ietf.org", "acronym": "rtgwg", "comments": "", "list_subscribe": "rtgwg-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rtgwg/", "type": "wg", "name": "Routing Area Working Group"}}, +{"pk": 1620, "model": "group.group", "fields": {"charter": "charter-ietf-tcpm", "unused_states": [], "ad": null, "parent": 1324, "list_email": "tcpm@ietf.org", "acronym": "tcpm", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/tcpm", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/tcpm/", "type": "wg", "name": "TCP Maintenance and Minor Extensions"}}, +{"pk": 1621, "model": "group.group", "fields": {"charter": "charter-ietf-icar", "unused_states": [], "ad": null, "parent": 1008, "list_email": "icar@ietf.org", "acronym": "icar", "comments": "1st meeting at 59th IETF-Seoul, Korea", "list_subscribe": "icar-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/icar/", "type": "wg", "name": "Improved Cross-Area Review"}}, {"pk": 1622, "model": "group.group", "fields": {"charter": "charter-ietf-letic", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "letic", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Link-Enhancing Transport Intermediary Communication"}}, {"pk": 1623, "model": "group.group", "fields": {"charter": "charter-ietf-marid", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-mxcomp@imc.org", "acronym": "marid", "comments": "1st meeting at the 59th IETF-Seoul, Korea", "list_subscribe": "ietf-mxcomp-request@imc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.imc.org/ietf-mxcomp/index.html", "type": "wg", "name": "MTA Authorization Records in DNS"}}, {"pk": 1624, "model": "group.group", "fields": {"charter": "charter-ietf-iiri", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "iiri", "comments": "1st meeting at 59th IETF-Seoul, Korea", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internet Information Retrieval Infrastructure"}}, -{"pk": 1625, "model": "group.group", "fields": {"charter": "charter-ietf-genarea", "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "genarea", "comments": "", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ag", "name": "General Area Open Meeting"}}, -{"pk": 1626, "model": "group.group", "fields": {"charter": "charter-ietf-hip", "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "hipsec@ietf.org", "acronym": "hip", "comments": "hipsec-request@ietf.org (old subscription method)", "list_subscribe": "http://www.ietf.org/mailman/listinfo/hipsec", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/hipsec/", "type": "wg", "name": "Host Identity Protocol"}}, +{"pk": 1625, "model": "group.group", "fields": {"charter": "charter-ietf-genarea", "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "genarea", "comments": "", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ag", "name": "General Area Open Meeting"}}, +{"pk": 1626, "model": "group.group", "fields": {"charter": "charter-ietf-hip", "unused_states": [], "ad": null, "parent": 1052, "list_email": "hipsec@ietf.org", "acronym": "hip", "comments": "hipsec-request@ietf.org (old subscription method)", "list_subscribe": "http://www.ietf.org/mailman/listinfo/hipsec", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/hipsec/", "type": "wg", "name": "Host Identity Protocol"}}, {"pk": 1627, "model": "group.group", "fields": {"charter": "charter-ietf-atompub", "unused_states": [], "ad": null, "parent": 934, "list_email": "atom-syntax@imc.org", "acronym": "atompub", "comments": "", "list_subscribe": "atom-syntax-request@imc.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.imc.org/atom-syntax/mail-archive/", "type": "wg", "name": "Atom Publishing Format and Protocol"}}, -{"pk": 1628, "model": "group.group", "fields": {"charter": "charter-ietf-bfd", "unused_states": [], "ad": 104198, "parent": 1249, "list_email": "rtg-bfd@ietf.org", "acronym": "bfd", "comments": "", "list_subscribe": "rtg-bfd-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rtg-bfd/", "type": "wg", "name": "Bidirectional Forwarding Detection"}}, +{"pk": 1628, "model": "group.group", "fields": {"charter": "charter-ietf-bfd", "unused_states": [], "ad": null, "parent": 1249, "list_email": "rtg-bfd@ietf.org", "acronym": "bfd", "comments": "", "list_subscribe": "rtg-bfd-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rtg-bfd/", "type": "wg", "name": "Bidirectional Forwarding Detection"}}, {"pk": 1629, "model": "group.group", "fields": {"charter": "charter-ietf-perm", "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "perm", "comments": "1st meeting at 60th IETF - San Diego, CA; 2nd meeting at 61st IEFT - Washington, DC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Protected Entertainment Rights Management"}}, -{"pk": 1630, "model": "group.group", "fields": {"charter": "charter-ietf-pce", "unused_states": [], "ad": 104198, "parent": 1249, "list_email": "pce@ietf.org", "acronym": "pce", "comments": "1st meeting at 60th IETF - San Diego, CA; 2nd meeting at 61st IETF - Washington, DC", "list_subscribe": "http://www.ietf.org/mailman/listinfo/pce", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pce/", "type": "wg", "name": "Path Computation Element"}}, +{"pk": 1630, "model": "group.group", "fields": {"charter": "charter-ietf-pce", "unused_states": [], "ad": null, "parent": 1249, "list_email": "pce@ietf.org", "acronym": "pce", "comments": "1st meeting at 60th IETF - San Diego, CA; 2nd meeting at 61st IETF - Washington, DC", "list_subscribe": "http://www.ietf.org/mailman/listinfo/pce", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pce/", "type": "wg", "name": "Path Computation Element"}}, {"pk": 1631, "model": "group.group", "fields": {"charter": "charter-ietf-rbridge", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "rbridge", "comments": "1st meeting at 60th IETF - San Diego, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IP Subnets in Topologies which are Flexible, Universal and Nice"}}, -{"pk": 1632, "model": "group.group", "fields": {"charter": "charter-ietf-behave", "unused_states": [], "ad": 110856, "parent": 1324, "list_email": "behave@ietf.org", "acronym": "behave", "comments": "1st meeting at 60th IETF Meeting - San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/behave", "state": "active", "time": "2012-02-17 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/behave", "type": "wg", "name": "Behavior Engineering for Hindrance Avoidance"}}, -{"pk": 1633, "model": "group.group", "fields": {"charter": "charter-ietf-isms", "unused_states": [], "ad": 19483, "parent": 934, "list_email": "isms@ietf.org", "acronym": "isms", "comments": "First met as SBSM, 2nd meeting at 60th IETF Meeting - San Diego, CA", "list_subscribe": "isms-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/isms/", "type": "wg", "name": "Integrated Security Model for SNMP"}}, -{"pk": 1634, "model": "group.group", "fields": {"charter": "charter-ietf-kitten", "unused_states": [], "ad": 19177, "parent": 1260, "list_email": "kitten@ietf.org", "acronym": "kitten", "comments": "1st meeting at 60th IETF - San Diego, CA; 2nd meeting at 61st IETF - Washington, DC", "list_subscribe": "https://www.ietf.org/mailman/listinfo/kitten", "state": "active", "time": "2012-10-01 09:22:55", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/kitten/", "type": "wg", "name": "Common Authentication Technology Next Generation"}}, +{"pk": 1632, "model": "group.group", "fields": {"charter": "charter-ietf-behave", "unused_states": [], "ad": null, "parent": 1324, "list_email": "behave@ietf.org", "acronym": "behave", "comments": "1st meeting at 60th IETF Meeting - San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/behave", "state": "active", "time": "2012-02-17 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/behave", "type": "wg", "name": "Behavior Engineering for Hindrance Avoidance"}}, +{"pk": 1633, "model": "group.group", "fields": {"charter": "charter-ietf-isms", "unused_states": [], "ad": null, "parent": 934, "list_email": "isms@ietf.org", "acronym": "isms", "comments": "First met as SBSM, 2nd meeting at 60th IETF Meeting - San Diego, CA", "list_subscribe": "isms-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/isms/", "type": "wg", "name": "Integrated Security Model for SNMP"}}, +{"pk": 1634, "model": "group.group", "fields": {"charter": "charter-ietf-kitten", "unused_states": [], "ad": null, "parent": 1260, "list_email": "kitten@ietf.org", "acronym": "kitten", "comments": "1st meeting at 60th IETF - San Diego, CA; 2nd meeting at 61st IETF - Washington, DC", "list_subscribe": "https://www.ietf.org/mailman/listinfo/kitten", "state": "active", "time": "2012-10-01 09:22:55", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/kitten/", "type": "wg", "name": "Common Authentication Technology Next Generation"}}, {"pk": 1635, "model": "group.group", "fields": {"charter": "charter-ietf-urirev04", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "urirev04", "comments": "1st meeting at 60th IETF Meeting - San Diego, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Uniform Resource Identifier Revisions"}}, {"pk": 1636, "model": "group.group", "fields": {"charter": "charter-ietf-ipvlx", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "ipvlx", "comments": "1st meeting at 60th IETF Meeting - San Diego, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IP Virtual Link Extension"}}, {"pk": 1637, "model": "group.group", "fields": {"charter": "charter-ietf-mass", "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "mass", "comments": "1st meeting 60th IETF Meeting - San Diego, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Message Authentication Signature Standards"}}, -{"pk": 1638, "model": "group.group", "fields": {"charter": "charter-ietf-netmod", "unused_states": [], "ad": 105682, "parent": 1193, "list_email": "netmod@ietf.org", "acronym": "netmod", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/netmod", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/netmod/", "type": "wg", "name": "NETCONF Data Modeling Language"}}, -{"pk": 1639, "model": "group.group", "fields": {"charter": "charter-ietf-6lowpan", "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "6lowpan@lists.ietf.org", "acronym": "6lowpan", "comments": "1st meeting at the 61st IETF - Washington, DC", "list_subscribe": "6lowpan-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/6lowpan/", "type": "wg", "name": "IPv6 over Low power WPAN"}}, -{"pk": 1640, "model": "group.group", "fields": {"charter": "charter-ietf-ietf-tv", "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "ietf-tv", "comments": "1st meeting at 61st IETF Meeting - Washington, DC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "The Future of IETF Multicast/Unicast Service"}}, +{"pk": 1638, "model": "group.group", "fields": {"charter": "charter-ietf-netmod", "unused_states": [], "ad": null, "parent": 1193, "list_email": "netmod@ietf.org", "acronym": "netmod", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/netmod", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/netmod/", "type": "wg", "name": "NETCONF Data Modeling Language"}}, +{"pk": 1639, "model": "group.group", "fields": {"charter": "charter-ietf-6lowpan", "unused_states": [], "ad": null, "parent": 1052, "list_email": "6lowpan@lists.ietf.org", "acronym": "6lowpan", "comments": "1st meeting at the 61st IETF - Washington, DC", "list_subscribe": "6lowpan-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/6lowpan/", "type": "wg", "name": "IPv6 over Low power WPAN"}}, +{"pk": 1640, "model": "group.group", "fields": {"charter": "charter-ietf-ietf-tv", "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "ietf-tv", "comments": "1st meeting at 61st IETF Meeting - Washington, DC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "The Future of IETF Multicast/Unicast Service"}}, {"pk": 1641, "model": "group.group", "fields": {"charter": "charter-ietf-btns", "unused_states": [], "ad": null, "parent": 1260, "list_email": "btns@ietf.org", "acronym": "btns", "comments": "1st meeting at 61st IETF-Washington, DC; 2nd meeting at 62nd IETF-Minneapolis, MN", "list_subscribe": "https://www.ietf.org/mailman/listinfo/btns", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/btns/", "type": "wg", "name": "Better-Than-Nothing Security"}}, -{"pk": 1642, "model": "group.group", "fields": {"charter": "charter-ietf-ntp", "unused_states": [], "ad": 100664, "parent": 1052, "list_email": "ntpwg@lists.ntp.org", "acronym": "ntp", "comments": "1st meeting at 61st IETF-Washington, DC; 2nd meeting at 62nd IETF-Minneapolis, MN", "list_subscribe": "https://lists.ntp.org/listinfo/ntpwg", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.ntp.org/pipermail/ntpwg/", "type": "wg", "name": "Network Time Protocol"}}, -{"pk": 1643, "model": "group.group", "fields": {"charter": "charter-ietf-ecrit", "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "ecrit@ietf.org", "acronym": "ecrit", "comments": "1st meeting at 61st IETF - Washington, DC", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ecrit", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ecrit/", "type": "wg", "name": "Emergency Context Resolution with Internet Technologies"}}, +{"pk": 1642, "model": "group.group", "fields": {"charter": "charter-ietf-ntp", "unused_states": [], "ad": null, "parent": 1052, "list_email": "ntpwg@lists.ntp.org", "acronym": "ntp", "comments": "1st meeting at 61st IETF-Washington, DC; 2nd meeting at 62nd IETF-Minneapolis, MN", "list_subscribe": "https://lists.ntp.org/listinfo/ntpwg", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.ntp.org/pipermail/ntpwg/", "type": "wg", "name": "Network Time Protocol"}}, +{"pk": 1643, "model": "group.group", "fields": {"charter": "charter-ietf-ecrit", "unused_states": [], "ad": null, "parent": 1683, "list_email": "ecrit@ietf.org", "acronym": "ecrit", "comments": "1st meeting at 61st IETF - Washington, DC", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ecrit", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ecrit/", "type": "wg", "name": "Emergency Context Resolution with Internet Technologies"}}, {"pk": 1644, "model": "group.group", "fields": {"charter": "charter-ietf-easycert", "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "easycert", "comments": "1st meeting at 61st IETF - Washington, DC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Easy-to-Use Certificates"}}, {"pk": 1645, "model": "group.group", "fields": {"charter": "charter-ietf-idnprov", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "idnprov", "comments": "1st meeting at 61st IETF - Washington, DC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IDN over EPP"}}, -{"pk": 1646, "model": "group.group", "fields": {"charter": "charter-ietf-shim6", "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "shim6@ietf.org", "acronym": "shim6", "comments": "1st meeting at 62nd IETF - Minneapolis, MN", "list_subscribe": "https://www.ietf.org/mailman/listinfo/shim6", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/shim6/", "type": "wg", "name": "Site Multihoming by IPv6 Intermediation"}}, -{"pk": 1647, "model": "group.group", "fields": {"charter": "charter-ietf-lowpan", "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "", "acronym": "lowpan", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPv6 over IEEE 802.15.4"}}, -{"pk": 1648, "model": "group.group", "fields": {"charter": "charter-ietf-calsify", "unused_states": [], "ad": 105907, "parent": 934, "list_email": "ietf-calsify@osafoundation.org", "acronym": "calsify", "comments": "1st meeting at 62nd IETF-Minneapolis, MN; 2nd meeting at 63rd IETF-Paris, France", "list_subscribe": "http://lists.osafoundation.org/mailman/listinfo/ietf-calsify", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.osafoundation.org/pipermail/ietf-calsify/", "type": "wg", "name": "Calendaring and Scheduling Standards Simplification"}}, +{"pk": 1646, "model": "group.group", "fields": {"charter": "charter-ietf-shim6", "unused_states": [], "ad": null, "parent": 1052, "list_email": "shim6@ietf.org", "acronym": "shim6", "comments": "1st meeting at 62nd IETF - Minneapolis, MN", "list_subscribe": "https://www.ietf.org/mailman/listinfo/shim6", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/shim6/", "type": "wg", "name": "Site Multihoming by IPv6 Intermediation"}}, +{"pk": 1647, "model": "group.group", "fields": {"charter": "charter-ietf-lowpan", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "lowpan", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPv6 over IEEE 802.15.4"}}, +{"pk": 1648, "model": "group.group", "fields": {"charter": "charter-ietf-calsify", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-calsify@osafoundation.org", "acronym": "calsify", "comments": "1st meeting at 62nd IETF-Minneapolis, MN; 2nd meeting at 63rd IETF-Paris, France", "list_subscribe": "http://lists.osafoundation.org/mailman/listinfo/ietf-calsify", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.osafoundation.org/pipermail/ietf-calsify/", "type": "wg", "name": "Calendaring and Scheduling Standards Simplification"}}, {"pk": 1649, "model": "group.group", "fields": {"charter": "charter-ietf-slrrp", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "slrrp", "comments": "1st meeting at the 62nd IETF-Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Simple Lightweight RFID Reader Protocol"}}, -{"pk": 1650, "model": "group.group", "fields": {"charter": "charter-ietf-trill", "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "trill@ietf.org", "acronym": "trill", "comments": "1st meeting at 62nd IETF-Minneapolis, MN", "list_subscribe": "https://www.ietf.org/mailman/listinfo/trill", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/trill/current/maillist.html", "type": "wg", "name": "Transparent Interconnection of Lots of Links"}}, +{"pk": 1650, "model": "group.group", "fields": {"charter": "charter-ietf-trill", "unused_states": [], "ad": null, "parent": 1052, "list_email": "trill@ietf.org", "acronym": "trill", "comments": "1st meeting at 62nd IETF-Minneapolis, MN", "list_subscribe": "https://www.ietf.org/mailman/listinfo/trill", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/trill/current/maillist.html", "type": "wg", "name": "Transparent Interconnection of Lots of Links"}}, {"pk": 1651, "model": "group.group", "fields": {"charter": "charter-ietf-icos", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "icos", "comments": "1st meeting at 62nd IETF-Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IP Configuration Security"}}, {"pk": 1652, "model": "group.group", "fields": {"charter": "charter-ietf-tc", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "tc", "comments": "1st meeting at 62nd IETF-Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Tunneling Configuration"}}, -{"pk": 1653, "model": "group.group", "fields": {"charter": "charter-ietf-autoconf", "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "autoconf@ietf.org", "acronym": "autoconf", "comments": "1st meeting at 62nd IETF-Minneapolis, MN; 2nd meeting at 64th IETF-Vancouver, BC", "list_subscribe": "https://www.ietf.org/mailman/listinfo/autoconf", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/autoconf/", "type": "wg", "name": "Ad-Hoc Network Autoconfiguration"}}, -{"pk": 1654, "model": "group.group", "fields": {"charter": "charter-ietf-liaison", "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "liaison", "comments": "1st meeting at 62nd IETF-Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Liaison Relationships"}}, +{"pk": 1653, "model": "group.group", "fields": {"charter": "charter-ietf-autoconf", "unused_states": [], "ad": null, "parent": 1052, "list_email": "autoconf@ietf.org", "acronym": "autoconf", "comments": "1st meeting at 62nd IETF-Minneapolis, MN; 2nd meeting at 64th IETF-Vancouver, BC", "list_subscribe": "https://www.ietf.org/mailman/listinfo/autoconf", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/autoconf/", "type": "wg", "name": "Ad-Hoc Network Autoconfiguration"}}, +{"pk": 1654, "model": "group.group", "fields": {"charter": "charter-ietf-liaison", "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "liaison", "comments": "1st meeting at 62nd IETF-Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Liaison Relationships"}}, {"pk": 1655, "model": "group.group", "fields": {"charter": "charter-ietf-ltru", "unused_states": [], "ad": null, "parent": 934, "list_email": "ltru@ietf.org", "acronym": "ltru", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ltru", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ltru/", "type": "wg", "name": "Language Tag Registry Update"}}, {"pk": 1656, "model": "group.group", "fields": {"charter": "charter-ietf-l1vpn", "unused_states": [], "ad": null, "parent": 1249, "list_email": "l1vpn@ietf.org", "acronym": "l1vpn", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/l1vpn", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/l1vpn/", "type": "wg", "name": "Layer 1 Virtual Private Networks"}}, {"pk": 1657, "model": "group.group", "fields": {"charter": "charter-ietf-secmech", "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "secmech", "comments": "1st meeting at the 63rd IETF - Paris, France", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Security Mechanisms"}}, {"pk": 1658, "model": "group.group", "fields": {"charter": "charter-ietf-hash", "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "hash", "comments": "1st meeting at 63rd IETF-Paris, France", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "One-way Hash Function"}}, {"pk": 1659, "model": "group.group", "fields": {"charter": "charter-ietf-imad", "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "imad", "comments": "1st meeting at 63rd IETF-Paris, France", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPv4 Multicast Address Architecture"}}, -{"pk": 1660, "model": "group.group", "fields": {"charter": "charter-ietf-techspec", "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "techspec", "comments": "1st meeting at 64th IETF-Vancouver, BC; 2nd meeting 65th IETF-Dallas, TX", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Requirements for IETF Technical Specificaiton Publication"}}, +{"pk": 1660, "model": "group.group", "fields": {"charter": "charter-ietf-techspec", "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "techspec", "comments": "1st meeting at 64th IETF-Vancouver, BC; 2nd meeting 65th IETF-Dallas, TX", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Requirements for IETF Technical Specificaiton Publication"}}, {"pk": 1661, "model": "group.group", "fields": {"charter": "charter-ietf-alien", "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "alien", "comments": "1st meeting at 63rd IETF-Paris, France", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Anonymous Identifiers"}}, {"pk": 1662, "model": "group.group", "fields": {"charter": "charter-ietf-rui", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "rui", "comments": "1st meeting at 63rd IETF-Paris, France; 2nd meeting at 64th IETF-Vancouver, BC; this BOF was changed to the WIDEX WG just before the Vancouver meeting.", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Remote UI"}}, {"pk": 1663, "model": "group.group", "fields": {"charter": "charter-ietf-voipeer", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "voipeer", "comments": "1st meeting at 63rd IETF-Paris, France; 2nd meeting at 64th IETF-Vancouver, BC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "VoIP Peering and Interconnect"}}, -{"pk": 1664, "model": "group.group", "fields": {"charter": "charter-ietf-netlmm", "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "netlmm@ietf.org", "acronym": "netlmm", "comments": "1st meeting at 63rd IETF-Paris, France; 2nd meeting at 64th IETF-Vancouver, BC", "list_subscribe": "http://www.ietf.org/mailman/listinfo/netlmm", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/netlmm", "type": "wg", "name": "Network-based Localized Mobility Management"}}, -{"pk": 1665, "model": "group.group", "fields": {"charter": "charter-ietf-intarea", "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "int-area@ietf.org", "acronym": "intarea", "comments": "1st meeting at 63rd IETF-Paris, France", "list_subscribe": "https://www.ietf.org/mailman/listinfo/int-area", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/int-area/", "type": "wg", "name": "Internet Area Working Group"}}, -{"pk": 1666, "model": "group.group", "fields": {"charter": "charter-ietf-lrw", "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "", "acronym": "lrw", "comments": "1st meeting at 63rd IETF-Paris, France", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Lightweight Reachability softWires"}}, -{"pk": 1667, "model": "group.group", "fields": {"charter": "charter-ietf-monami6", "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "monami6@ietf.org", "acronym": "monami6", "comments": "1st meeting at 63rd IETF-Paris, France; 2nd meeting at 64th IETF-Vancouver, BC", "list_subscribe": "https://www1.ietf.org/mailman/listinfo/monami6", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/monami6/", "type": "wg", "name": "Mobile Nodes and Multiple Interfaces in IPv6"}}, +{"pk": 1664, "model": "group.group", "fields": {"charter": "charter-ietf-netlmm", "unused_states": [], "ad": null, "parent": 1052, "list_email": "netlmm@ietf.org", "acronym": "netlmm", "comments": "1st meeting at 63rd IETF-Paris, France; 2nd meeting at 64th IETF-Vancouver, BC", "list_subscribe": "http://www.ietf.org/mailman/listinfo/netlmm", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/netlmm", "type": "wg", "name": "Network-based Localized Mobility Management"}}, +{"pk": 1665, "model": "group.group", "fields": {"charter": "charter-ietf-intarea", "unused_states": [], "ad": null, "parent": 1052, "list_email": "int-area@ietf.org", "acronym": "intarea", "comments": "1st meeting at 63rd IETF-Paris, France", "list_subscribe": "https://www.ietf.org/mailman/listinfo/int-area", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/int-area/", "type": "wg", "name": "Internet Area Working Group"}}, +{"pk": 1666, "model": "group.group", "fields": {"charter": "charter-ietf-lrw", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "lrw", "comments": "1st meeting at 63rd IETF-Paris, France", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Lightweight Reachability softWires"}}, +{"pk": 1667, "model": "group.group", "fields": {"charter": "charter-ietf-monami6", "unused_states": [], "ad": null, "parent": 1052, "list_email": "monami6@ietf.org", "acronym": "monami6", "comments": "1st meeting at 63rd IETF-Paris, France; 2nd meeting at 64th IETF-Vancouver, BC", "list_subscribe": "https://www1.ietf.org/mailman/listinfo/monami6", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/monami6/", "type": "wg", "name": "Mobile Nodes and Multiple Interfaces in IPv6"}}, {"pk": 1669, "model": "group.group", "fields": {"charter": "charter-ietf-widex", "unused_states": [], "ad": null, "parent": 934, "list_email": "widex@ietf.org", "acronym": "widex", "comments": "Suplemental Website: http://www.softarmor.com/rui\r\n1st meeting as WIDEX at 64th IETF-Vancouver, BC; was previously known as RUI", "list_subscribe": "https://www1.ietf.org/mailman/listinfo/widex", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/widex/", "type": "wg", "name": "Widget Description Exchange Service"}}, {"pk": 1670, "model": "group.group", "fields": {"charter": "charter-ietf-gels", "unused_states": [], "ad": null, "parent": 1249, "list_email": "", "acronym": "gels", "comments": "1st meeting at 64th IETF-Vancouver, BC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "GMPLS Controlled Ethernet Label Switching"}}, -{"pk": 1671, "model": "group.group", "fields": {"charter": "charter-ietf-dkim", "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "ietf-dkim@mipassoc.org", "acronym": "dkim", "comments": "1st meeting at 64th IETF-Vancouver, BC", "list_subscribe": "http://mipassoc.org/mailman/listinfo/ietf-dkim", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://mipassoc.org/pipermail/ietf-dkim/", "type": "wg", "name": "Domain Keys Identified Mail"}}, -{"pk": 1672, "model": "group.group", "fields": {"charter": "charter-ietf-pesci", "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "pesci", "comments": "1st meeting at 64th IETF-Vancouver, BC; Bert Wijnen and Sam Hartman will host this BOF, Brian will be chair.", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Process Evolution Consideration for the IETF"}}, -{"pk": 1673, "model": "group.group", "fields": {"charter": "charter-ietf-fecframe", "unused_states": [], "ad": 105519, "parent": 1324, "list_email": "fecframe@ietf.org", "acronym": "fecframe", "comments": "1st meeting at 64th IETF-Vancouver, BC", "list_subscribe": "https://www.ietf.org/mailman/listinfo/fecframe", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/fecframe", "type": "wg", "name": "FEC Framework"}}, -{"pk": 1674, "model": "group.group", "fields": {"charter": "charter-ietf-emu", "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "emu@ietf.org", "acronym": "emu", "comments": "1st meeting at 64th IETF-Vancouver, BC", "list_subscribe": "https://www.ietf.org/mailman/listinfo/emu", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/emu/", "type": "wg", "name": "EAP Method Update"}}, -{"pk": 1675, "model": "group.group", "fields": {"charter": "charter-ietf-16ng", "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "16ng@ietf.org", "acronym": "16ng", "comments": "1st meeting at 64th IETF-Vancouver, BC. 2nd meeting 65th IETF-Dallas, TX; 34rd meeting at 66th IETF-Montreal, Canada", "list_subscribe": "https://www.ietf.org/mailman/listinfo/16ng", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/16ng", "type": "wg", "name": "IP over IEEE 802.16 Networks"}}, +{"pk": 1671, "model": "group.group", "fields": {"charter": "charter-ietf-dkim", "unused_states": [], "ad": null, "parent": 1260, "list_email": "ietf-dkim@mipassoc.org", "acronym": "dkim", "comments": "1st meeting at 64th IETF-Vancouver, BC", "list_subscribe": "http://mipassoc.org/mailman/listinfo/ietf-dkim", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://mipassoc.org/pipermail/ietf-dkim/", "type": "wg", "name": "Domain Keys Identified Mail"}}, +{"pk": 1672, "model": "group.group", "fields": {"charter": "charter-ietf-pesci", "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "pesci", "comments": "1st meeting at 64th IETF-Vancouver, BC; Bert Wijnen and Sam Hartman will host this BOF, Brian will be chair.", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Process Evolution Consideration for the IETF"}}, +{"pk": 1673, "model": "group.group", "fields": {"charter": "charter-ietf-fecframe", "unused_states": [], "ad": null, "parent": 1324, "list_email": "fecframe@ietf.org", "acronym": "fecframe", "comments": "1st meeting at 64th IETF-Vancouver, BC", "list_subscribe": "https://www.ietf.org/mailman/listinfo/fecframe", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/fecframe", "type": "wg", "name": "FEC Framework"}}, +{"pk": 1674, "model": "group.group", "fields": {"charter": "charter-ietf-emu", "unused_states": [], "ad": null, "parent": 1260, "list_email": "emu@ietf.org", "acronym": "emu", "comments": "1st meeting at 64th IETF-Vancouver, BC", "list_subscribe": "https://www.ietf.org/mailman/listinfo/emu", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/emu/", "type": "wg", "name": "EAP Method Update"}}, +{"pk": 1675, "model": "group.group", "fields": {"charter": "charter-ietf-16ng", "unused_states": [], "ad": null, "parent": 1052, "list_email": "16ng@ietf.org", "acronym": "16ng", "comments": "1st meeting at 64th IETF-Vancouver, BC. 2nd meeting 65th IETF-Dallas, TX; 34rd meeting at 66th IETF-Montreal, Canada", "list_subscribe": "https://www.ietf.org/mailman/listinfo/16ng", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/16ng", "type": "wg", "name": "IP over IEEE 802.16 Networks"}}, {"pk": 1676, "model": "group.group", "fields": {"charter": "charter-ietf-xmlpatch", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "xmlpatch", "comments": "1st meeting at 64th IETF-Vancouver, BC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "XML-Patch-Ops"}}, {"pk": 1677, "model": "group.group", "fields": {"charter": "charter-ietf-iee", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "iee", "comments": "1st meeting at 64th IETF-Vancouver, BC", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Internationalized Email and Extensions"}}, -{"pk": 1678, "model": "group.group", "fields": {"charter": "charter-ietf-softwire", "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "softwires@ietf.org", "acronym": "softwire", "comments": "1st meeting at 64th IETF-Vancouver, BC", "list_subscribe": "softwires-request@ietf.org", "state": "active", "time": "2012-06-20 08:03:29", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/softwires/", "type": "wg", "name": "Softwires"}}, +{"pk": 1678, "model": "group.group", "fields": {"charter": "charter-ietf-softwire", "unused_states": [], "ad": null, "parent": 1052, "list_email": "softwires@ietf.org", "acronym": "softwire", "comments": "1st meeting at 64th IETF-Vancouver, BC", "list_subscribe": "softwires-request@ietf.org", "state": "active", "time": "2012-06-20 08:03:29", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/softwires/", "type": "wg", "name": "Softwires"}}, {"pk": 1679, "model": "group.group", "fields": {"charter": "charter-ietf-tsvarea", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "tsvarea", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-02-23 12:00:00", "unused_tags": [], "list_archive": "", "type": "ag", "name": "Transport Area Open Meeting"}}, -{"pk": 1680, "model": "group.group", "fields": {"charter": "charter-ietf-sidr", "unused_states": [], "ad": 2329, "parent": 1249, "list_email": "sidr@ietf.org", "acronym": "sidr", "comments": "1st meeting at 64th IETF-Vancouver, BC", "list_subscribe": "sidr-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sidr/", "type": "wg", "name": "Secure Inter-Domain Routing"}}, +{"pk": 1680, "model": "group.group", "fields": {"charter": "charter-ietf-sidr", "unused_states": [], "ad": null, "parent": 1249, "list_email": "sidr@ietf.org", "acronym": "sidr", "comments": "1st meeting at 64th IETF-Vancouver, BC", "list_subscribe": "sidr-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sidr/", "type": "wg", "name": "Secure Inter-Domain Routing"}}, {"pk": 1681, "model": "group.group", "fields": {"charter": "charter-ietf-callhome", "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "callhome", "comments": "1st meeting at 64th IETF-Vancouver, BC, CANADA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Reversing Traditional Client/Server Connection Model"}}, -{"pk": 1682, "model": "group.group", "fields": {"charter": "charter-ietf-dime", "unused_states": [], "ad": 105682, "parent": 1193, "list_email": "dime@ietf.org", "acronym": "dime", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/dime", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dime/", "type": "wg", "name": "Diameter Maintenance and Extensions"}}, +{"pk": 1682, "model": "group.group", "fields": {"charter": "charter-ietf-dime", "unused_states": [], "ad": null, "parent": 1193, "list_email": "dime@ietf.org", "acronym": "dime", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/dime", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dime/", "type": "wg", "name": "Diameter Maintenance and Extensions"}}, {"pk": 1684, "model": "group.group", "fields": {"charter": "charter-ietf-raiarea", "unused_states": [], "ad": null, "parent": 1683, "list_email": "", "acronym": "raiarea", "comments": "", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "ag", "name": "Real-time Applications and Infrastructure Area Open Meeting"}}, -{"pk": 1685, "model": "group.group", "fields": {"charter": "charter-ietf-speermint", "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "speermint@ietf.org", "acronym": "speermint", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/speermint", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/speermint/", "type": "wg", "name": "Session PEERing for Multimedia INTerconnect"}}, -{"pk": 1686, "model": "group.group", "fields": {"charter": "charter-ietf-eai", "unused_states": [], "ad": 18321, "parent": 934, "list_email": "ima@ietf.org", "acronym": "eai", "comments": "1st meeting at 65th IETF-Dallas, TX", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ima", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ima", "type": "wg", "name": "Email Address Internationalization"}}, -{"pk": 1688, "model": "group.group", "fields": {"charter": "charter-ietf-nea", "unused_states": [], "ad": 19177, "parent": 1260, "list_email": "nea@ietf.org", "acronym": "nea", "comments": "1st meeting at 65th IETF-Dallas, TX; 2nd meeting at 66th IETF-Montreal, Canada; 3rd meeting at 67th IETF-San Diego, CA", "list_subscribe": "http://www.ietf.org/mailman/listinfo/nea", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/nea", "type": "wg", "name": "Network Endpoint Assessment"}}, +{"pk": 1685, "model": "group.group", "fields": {"charter": "charter-ietf-speermint", "unused_states": [], "ad": null, "parent": 1683, "list_email": "speermint@ietf.org", "acronym": "speermint", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/speermint", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/speermint/", "type": "wg", "name": "Session PEERing for Multimedia INTerconnect"}}, +{"pk": 1686, "model": "group.group", "fields": {"charter": "charter-ietf-eai", "unused_states": [], "ad": null, "parent": 934, "list_email": "ima@ietf.org", "acronym": "eai", "comments": "1st meeting at 65th IETF-Dallas, TX", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ima", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ima", "type": "wg", "name": "Email Address Internationalization"}}, +{"pk": 1688, "model": "group.group", "fields": {"charter": "charter-ietf-nea", "unused_states": [], "ad": null, "parent": 1260, "list_email": "nea@ietf.org", "acronym": "nea", "comments": "1st meeting at 65th IETF-Dallas, TX; 2nd meeting at 66th IETF-Montreal, Canada; 3rd meeting at 67th IETF-San Diego, CA", "list_subscribe": "http://www.ietf.org/mailman/listinfo/nea", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/nea", "type": "wg", "name": "Network Endpoint Assessment"}}, {"pk": 1689, "model": "group.group", "fields": {"charter": "charter-ietf-dix", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "dix", "comments": "1st meeting at 65th IETF-Dallas, TX", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Digital Identity Exchange Protocol"}}, {"pk": 1690, "model": "group.group", "fields": {"charter": "charter-ietf-p2p-sip", "unused_states": [], "ad": null, "parent": 1683, "list_email": "p2psip@ietf.org", "acronym": "p2p-sip", "comments": "1st meeting at 65th IETF-Dallas, TX; 2nd meeting at 67th IETF-San Diego", "list_subscribe": "https://www.ietf.org/mailman/listinfo/p2psip", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/p2psip", "type": "wg", "name": "Peer to Peer Support for Session Initiation Protocol"}}, {"pk": 1691, "model": "group.group", "fields": {"charter": "charter-ietf-l2cp", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "l2cp", "comments": "1st meeting at 65th IETF-Dallas, TX", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Layer 2 Control Protocol"}}, {"pk": 1692, "model": "group.group", "fields": {"charter": "charter-ietf-hoakey", "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "hoakey", "comments": "1st meeting at 65th IETF-Dallas, TX; 2nd meeting at 66th IETF-Montreal, Canada; 3rd meeting at 67th IETF-San Diego, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Handover and Application Keying and Pre-authentication"}}, -{"pk": 1693, "model": "group.group", "fields": {"charter": "charter-ietf-ancp", "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "ancp@ietf.org", "acronym": "ancp", "comments": "", "list_subscribe": "ancp-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ancp/", "type": "wg", "name": "Access Node Control Protocol"}}, +{"pk": 1693, "model": "group.group", "fields": {"charter": "charter-ietf-ancp", "unused_states": [], "ad": null, "parent": 1052, "list_email": "ancp@ietf.org", "acronym": "ancp", "comments": "", "list_subscribe": "ancp-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ancp/", "type": "wg", "name": "Access Node Control Protocol"}}, {"pk": 1694, "model": "group.group", "fields": {"charter": "charter-ietf-dmsp", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "dmsp", "comments": "1st meeting at 66th IETF-Montreal, Canada", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Distributed Multimodal Synchronization Protocol"}}, {"pk": 1695, "model": "group.group", "fields": {"charter": "charter-ietf-offpath", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "offpath", "comments": "1st meeting at 66th IETF-Monteral, Canada", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Path-decoupled Signaling for Data"}}, {"pk": 1696, "model": "group.group", "fields": {"charter": "charter-ietf-ternli", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "ternli", "comments": "1st meeting at 66th IETF-Montreal, Canada", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Transport-Enhancing Refinements to the Network Layer"}}, {"pk": 1697, "model": "group.group", "fields": {"charter": "charter-ietf-rtpsec", "unused_states": [], "ad": null, "parent": 1683, "list_email": "", "acronym": "rtpsec", "comments": "1st meeting at 66th IETF-Montreal, Canada", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "RTP Secure Keying"}}, {"pk": 1698, "model": "group.group", "fields": {"charter": "charter-ietf-wae", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "wae", "comments": "1st meeting at 66yth EITF-Montreal, Canada", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Web Authentication Enhancement"}}, -{"pk": 1699, "model": "group.group", "fields": {"charter": "charter-ietf-sava", "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "", "acronym": "sava", "comments": "1st meeting 68th IETF - Prague, Czech Republic", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Source Address Validation Architecture"}}, -{"pk": 1700, "model": "group.group", "fields": {"charter": "charter-ietf-hokey", "unused_states": [], "ad": 19177, "parent": 1260, "list_email": "hokey@ietf.org", "acronym": "hokey", "comments": "Was call HOAKEY as a BOF. 1st meeting at 65th IETF-Dallas, TX; 2nd meeting at 66th IETF-Montreal, Canada; 3rd meeting at 67th IETF-San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/hokey", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/hokey/", "type": "wg", "name": "Handover Keying"}}, -{"pk": 1701, "model": "group.group", "fields": {"charter": "charter-ietf-pcn", "unused_states": [], "ad": 105519, "parent": 1324, "list_email": "pcn@ietf.org", "acronym": "pcn", "comments": "1st meeting at 67th IETF-San Diego, CA", "list_subscribe": "pcn-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pcn/", "type": "wg", "name": "Congestion and Pre-Congestion Notification"}}, -{"pk": 1702, "model": "group.group", "fields": {"charter": "charter-ietf-mediactrl", "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "mediactrl@ietf.org", "acronym": "mediactrl", "comments": "1st meeting at 67th IETF-San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/mediactrl", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mediactrl", "type": "wg", "name": "Media Server Control"}}, +{"pk": 1699, "model": "group.group", "fields": {"charter": "charter-ietf-sava", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "sava", "comments": "1st meeting 68th IETF - Prague, Czech Republic", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Source Address Validation Architecture"}}, +{"pk": 1700, "model": "group.group", "fields": {"charter": "charter-ietf-hokey", "unused_states": [], "ad": null, "parent": 1260, "list_email": "hokey@ietf.org", "acronym": "hokey", "comments": "Was call HOAKEY as a BOF. 1st meeting at 65th IETF-Dallas, TX; 2nd meeting at 66th IETF-Montreal, Canada; 3rd meeting at 67th IETF-San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/hokey", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/hokey/", "type": "wg", "name": "Handover Keying"}}, +{"pk": 1701, "model": "group.group", "fields": {"charter": "charter-ietf-pcn", "unused_states": [], "ad": null, "parent": 1324, "list_email": "pcn@ietf.org", "acronym": "pcn", "comments": "1st meeting at 67th IETF-San Diego, CA", "list_subscribe": "pcn-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pcn/", "type": "wg", "name": "Congestion and Pre-Congestion Notification"}}, +{"pk": 1702, "model": "group.group", "fields": {"charter": "charter-ietf-mediactrl", "unused_states": [], "ad": null, "parent": 1683, "list_email": "mediactrl@ietf.org", "acronym": "mediactrl", "comments": "1st meeting at 67th IETF-San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/mediactrl", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mediactrl", "type": "wg", "name": "Media Server Control"}}, {"pk": 1703, "model": "group.group", "fields": {"charter": "charter-ietf-spkm", "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "spkm", "comments": "1st meeting 67th IETF-San Diego, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "NFSv4 and Low Infrastructure Public Key Based GSS Security Mechanisms"}}, {"pk": 1704, "model": "group.group", "fields": {"charter": "charter-ietf-keyprov", "unused_states": [], "ad": null, "parent": 1260, "list_email": "keyprov@ietf.org", "acronym": "keyprov", "comments": "1st meeting at 67th IETF-San Diego, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/keyprov", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/keyprov", "type": "wg", "name": "Provisioning of Symmetric Keys"}}, -{"pk": 1705, "model": "group.group", "fields": {"charter": "charter-ietf-p2psip", "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "p2psip@ietf.org", "acronym": "p2psip", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/p2psip", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/p2psip", "type": "wg", "name": "Peer-to-Peer Session Initiation Protocol"}}, +{"pk": 1705, "model": "group.group", "fields": {"charter": "charter-ietf-p2psip", "unused_states": [], "ad": null, "parent": 1683, "list_email": "p2psip@ietf.org", "acronym": "p2psip", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/p2psip", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/p2psip", "type": "wg", "name": "Peer-to-Peer Session Initiation Protocol"}}, {"pk": 1706, "model": "group.group", "fields": {"charter": "charter-ietf-ifare", "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "ifare", "comments": "1st meeting in Prague, IETF-68;", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPsec FAilover and REdundancy"}}, {"pk": 1707, "model": "group.group", "fields": {"charter": "charter-ietf-peppermint", "unused_states": [], "ad": null, "parent": 1683, "list_email": "", "acronym": "peppermint", "comments": "1st meeting at IETF-70 in Vancouver, Canada; 2nd meeting at 71st IETF - Philadelphia, PA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Provisioning Extensions in Peering Registries for Multimedia INTerconnection"}}, -{"pk": 1708, "model": "group.group", "fields": {"charter": "charter-ietf-bliss", "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "bliss@ietf.org", "acronym": "bliss", "comments": "1st meeting at ietf-68, prague", "list_subscribe": "https://www.ietf.org/mailman/listinfo/bliss", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/bliss", "type": "wg", "name": "Basic Level of Interoperability for SIP Services"}}, -{"pk": 1709, "model": "group.group", "fields": {"charter": "charter-ietf-tictoc", "unused_states": [], "ad": 100664, "parent": 1052, "list_email": "tictoc@ietf.org", "acronym": "tictoc", "comments": "1st meeting 68th IETF - Prague, Czech Republic", "list_subscribe": "TICTOC-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/tictoc", "type": "wg", "name": "Timing over IP Connection and Transfer of Clock"}}, -{"pk": 1710, "model": "group.group", "fields": {"charter": "charter-ietf-hiccup", "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "", "acronym": "hiccup", "comments": "1st meeting at IETF-68", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Harnessing IP for Critical Communications Using Precedence"}}, +{"pk": 1708, "model": "group.group", "fields": {"charter": "charter-ietf-bliss", "unused_states": [], "ad": null, "parent": 1683, "list_email": "bliss@ietf.org", "acronym": "bliss", "comments": "1st meeting at ietf-68, prague", "list_subscribe": "https://www.ietf.org/mailman/listinfo/bliss", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/bliss", "type": "wg", "name": "Basic Level of Interoperability for SIP Services"}}, +{"pk": 1709, "model": "group.group", "fields": {"charter": "charter-ietf-tictoc", "unused_states": [], "ad": null, "parent": 1052, "list_email": "tictoc@ietf.org", "acronym": "tictoc", "comments": "1st meeting 68th IETF - Prague, Czech Republic", "list_subscribe": "TICTOC-request@ietf.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/tictoc", "type": "wg", "name": "Timing over IP Connection and Transfer of Clock"}}, +{"pk": 1710, "model": "group.group", "fields": {"charter": "charter-ietf-hiccup", "unused_states": [], "ad": null, "parent": 1683, "list_email": "", "acronym": "hiccup", "comments": "1st meeting at IETF-68", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Harnessing IP for Critical Communications Using Precedence"}}, {"pk": 1711, "model": "group.group", "fields": {"charter": "charter-ietf-fsm", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "fsm", "comments": "1st meetings at IETF-68", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Formal State Machines"}}, {"pk": 1712, "model": "group.group", "fields": {"charter": "charter-ietf-tools", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "tools", "comments": "", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "team", "name": "The Tools Team"}}, {"pk": 1713, "model": "group.group", "fields": {"charter": "charter-ietf-proto", "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "proto", "comments": "", "list_subscribe": "", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "team", "name": "The Process and Tools Team"}}, -{"pk": 1714, "model": "group.group", "fields": {"charter": "charter-ietf-opsawg", "unused_states": [], "ad": 101568, "parent": 1193, "list_email": "opsawg@ietf.org", "acronym": "opsawg", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/opsawg", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/opsawg", "type": "wg", "name": "Operations and Management Area Working Group"}}, -{"pk": 1715, "model": "group.group", "fields": {"charter": "charter-ietf-apm", "unused_states": [], "ad": 6699, "parent": 1193, "list_email": "", "acronym": "apm", "comments": "1st meeting at IETF-69, Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Application Performance Metrics"}}, -{"pk": 1716, "model": "group.group", "fields": {"charter": "charter-ietf-nee", "unused_states": [], "ad": 6699, "parent": 1193, "list_email": "", "acronym": "nee", "comments": "1st meeting at IETF-69, Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Netconf Extensions and Evolution"}}, -{"pk": 1717, "model": "group.group", "fields": {"charter": "charter-ietf-xsdmi", "unused_states": [], "ad": 6699, "parent": 1193, "list_email": "", "acronym": "xsdmi", "comments": "1st meeting at IETF-69, Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "XSD for accessing SMIv2 data models"}}, -{"pk": 1718, "model": "group.group", "fields": {"charter": "charter-ietf-httpbis", "unused_states": [], "ad": 21684, "parent": 934, "list_email": "ietf-http-wg@w3.org", "acronym": "httpbis", "comments": "1st meeting at IETF-69, Chicago, IL", "list_subscribe": "ietf-http-wg-request@w3.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.w3.org/Archives/Public/ietf-http-wg/", "type": "wg", "name": "Hypertext Transfer Protocol Bis"}}, +{"pk": 1714, "model": "group.group", "fields": {"charter": "charter-ietf-opsawg", "unused_states": [], "ad": null, "parent": 1193, "list_email": "opsawg@ietf.org", "acronym": "opsawg", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/opsawg", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/opsawg", "type": "wg", "name": "Operations and Management Area Working Group"}}, +{"pk": 1715, "model": "group.group", "fields": {"charter": "charter-ietf-apm", "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "apm", "comments": "1st meeting at IETF-69, Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Application Performance Metrics"}}, +{"pk": 1716, "model": "group.group", "fields": {"charter": "charter-ietf-nee", "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "nee", "comments": "1st meeting at IETF-69, Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Netconf Extensions and Evolution"}}, +{"pk": 1717, "model": "group.group", "fields": {"charter": "charter-ietf-xsdmi", "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "xsdmi", "comments": "1st meeting at IETF-69, Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "XSD for accessing SMIv2 data models"}}, +{"pk": 1718, "model": "group.group", "fields": {"charter": "charter-ietf-httpbis", "unused_states": [], "ad": null, "parent": 934, "list_email": "ietf-http-wg@w3.org", "acronym": "httpbis", "comments": "1st meeting at IETF-69, Chicago, IL", "list_subscribe": "ietf-http-wg-request@w3.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.w3.org/Archives/Public/ietf-http-wg/", "type": "wg", "name": "Hypertext Transfer Protocol Bis"}}, {"pk": 1719, "model": "group.group", "fields": {"charter": "charter-ietf-tam", "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "tam", "comments": "1st meeting at IETF-69, Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Trust Anchor Management"}}, {"pk": 1720, "model": "group.group", "fields": {"charter": "charter-ietf-mext", "unused_states": [], "ad": null, "parent": 1052, "list_email": "mext@ietf.org", "acronym": "mext", "comments": "Renamed to Distributed Mobility Management (dmm) in January 2012\r\n", "list_subscribe": "https://www.ietf.org/mailman/listinfo/mext", "state": "conclude", "time": "2012-01-10 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mext", "type": "wg", "name": "Mobility EXTensions for IPv6"}}, -{"pk": 1721, "model": "group.group", "fields": {"charter": "charter-ietf-vcarddav", "unused_states": [], "ad": 18321, "parent": 934, "list_email": "vcarddav@ietf.org", "acronym": "vcarddav", "comments": "1st Meeting at IETF-69, Chicago, IL", "list_subscribe": "https://www.ietf.org/mailman/listinfo/vcarddav", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/vcarddav", "type": "wg", "name": "vCard and CardDAV"}}, +{"pk": 1721, "model": "group.group", "fields": {"charter": "charter-ietf-vcarddav", "unused_states": [], "ad": null, "parent": 934, "list_email": "vcarddav@ietf.org", "acronym": "vcarddav", "comments": "1st Meeting at IETF-69, Chicago, IL", "list_subscribe": "https://www.ietf.org/mailman/listinfo/vcarddav", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/vcarddav", "type": "wg", "name": "vCard and CardDAV"}}, {"pk": 1722, "model": "group.group", "fields": {"charter": "charter-ietf-biff", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "biff", "comments": "1st meeting at IETF-69, Chicago, IL", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Notifications from Mail Stores"}}, -{"pk": 1723, "model": "group.group", "fields": {"charter": "charter-ietf-6man", "unused_states": [], "ad": 100664, "parent": 1052, "list_email": "ipv6@ietf.org", "acronym": "6man", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ipv6", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipv6", "type": "wg", "name": "IPv6 Maintenance"}}, -{"pk": 1725, "model": "group.group", "fields": {"charter": "charter-ietf-pmol", "unused_states": [], "ad": 6699, "parent": 1193, "list_email": "pmol@ietf.org", "acronym": "pmol", "comments": "", "list_subscribe": "https://www1.ietf.org/mailman/listinfo/pmol", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pmol/", "type": "wg", "name": "Performance Metrics for Other Layers"}}, -{"pk": 1726, "model": "group.group", "fields": {"charter": "charter-ietf-csi", "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "cga-ext@ietf.org", "acronym": "csi", "comments": "1st meeting at IETF-70 in Vancouver, Canada", "list_subscribe": "http://www.ietf.org/mailman/listinfo/cga-ext", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/cga-ext/", "type": "wg", "name": "Cga & Send maIntenance"}}, -{"pk": 1727, "model": "group.group", "fields": {"charter": "charter-ietf-safe", "unused_states": [], "ad": 17253, "parent": 1324, "list_email": "", "acronym": "safe", "comments": "1st meeting at IETF-70, Vancouver, Canada", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Self-Address Fixing Evolution"}}, -{"pk": 1728, "model": "group.group", "fields": {"charter": "charter-ietf-savi", "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "savi@ietf.org", "acronym": "savi", "comments": "1st meeting at IETF-60, Vancouver, Canada; 2nd meeting at 71st IETF, Philadelphia, PA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/savi", "state": "active", "time": "2012-08-29 08:42:05", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/savi/", "type": "wg", "name": "Source Address Validation Improvements"}}, +{"pk": 1723, "model": "group.group", "fields": {"charter": "charter-ietf-6man", "unused_states": [], "ad": null, "parent": 1052, "list_email": "ipv6@ietf.org", "acronym": "6man", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ipv6", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipv6", "type": "wg", "name": "IPv6 Maintenance"}}, +{"pk": 1725, "model": "group.group", "fields": {"charter": "charter-ietf-pmol", "unused_states": [], "ad": null, "parent": 1193, "list_email": "pmol@ietf.org", "acronym": "pmol", "comments": "", "list_subscribe": "https://www1.ietf.org/mailman/listinfo/pmol", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pmol/", "type": "wg", "name": "Performance Metrics for Other Layers"}}, +{"pk": 1726, "model": "group.group", "fields": {"charter": "charter-ietf-csi", "unused_states": [], "ad": null, "parent": 1052, "list_email": "cga-ext@ietf.org", "acronym": "csi", "comments": "1st meeting at IETF-70 in Vancouver, Canada", "list_subscribe": "http://www.ietf.org/mailman/listinfo/cga-ext", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/cga-ext/", "type": "wg", "name": "Cga & Send maIntenance"}}, +{"pk": 1727, "model": "group.group", "fields": {"charter": "charter-ietf-safe", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "safe", "comments": "1st meeting at IETF-70, Vancouver, Canada", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Self-Address Fixing Evolution"}}, +{"pk": 1728, "model": "group.group", "fields": {"charter": "charter-ietf-savi", "unused_states": [], "ad": null, "parent": 1052, "list_email": "savi@ietf.org", "acronym": "savi", "comments": "1st meeting at IETF-60, Vancouver, Canada; 2nd meeting at 71st IETF, Philadelphia, PA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/savi", "state": "active", "time": "2012-08-29 08:42:05", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/savi/", "type": "wg", "name": "Source Address Validation Improvements"}}, {"pk": 1729, "model": "group.group", "fields": {"charter": "charter-ietf-rl2n", "unused_states": [], "ad": null, "parent": 1249, "list_email": "", "acronym": "rl2n", "comments": "1st meeting at IETF-70, Vancouver, Canada", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Routing For Low Power and Lossy Networks"}}, -{"pk": 1730, "model": "group.group", "fields": {"charter": "charter-ietf-roll", "unused_states": [], "ad": 104198, "parent": 1249, "list_email": "roll@ietf.org", "acronym": "roll", "comments": "", "list_subscribe": "http://www.ietf.org/mailman/listinfo/roll", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/roll/", "type": "wg", "name": "Routing Over Low power and Lossy networks"}}, -{"pk": 1731, "model": "group.group", "fields": {"charter": "charter-ietf-fun", "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "fun@ietf.org", "acronym": "fun", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/fun", "state": "bof", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/fun/", "type": "wg", "name": "FUture home Networks"}}, +{"pk": 1730, "model": "group.group", "fields": {"charter": "charter-ietf-roll", "unused_states": [], "ad": null, "parent": 1249, "list_email": "roll@ietf.org", "acronym": "roll", "comments": "", "list_subscribe": "http://www.ietf.org/mailman/listinfo/roll", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/roll/", "type": "wg", "name": "Routing Over Low power and Lossy networks"}}, +{"pk": 1731, "model": "group.group", "fields": {"charter": "charter-ietf-fun", "unused_states": [], "ad": null, "parent": 1052, "list_email": "fun@ietf.org", "acronym": "fun", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/fun", "state": "bof", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/fun/", "type": "wg", "name": "FUture home Networks"}}, {"pk": 1732, "model": "group.group", "fields": {"charter": "charter-ietf-rucus", "unused_states": [], "ad": null, "parent": 1683, "list_email": "", "acronym": "rucus", "comments": "1st meeting at 71st IETF - Philadelphia, PA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Ruducing Unwanted Communications using SIP"}}, {"pk": 1733, "model": "group.group", "fields": {"charter": "charter-ietf-esds", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "esds", "comments": "1st Meeting 71st IETF Meeting - Philadelphia, PA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Extensible Supply-chain Discovery Service"}}, -{"pk": 1734, "model": "group.group", "fields": {"charter": "charter-ietf-tf", "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "testlist@mail.ietf.org", "acronym": "tf", "comments": "", "list_subscribe": "testlist-request@mail.ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/tf", "type": "wg", "name": "Testing Fun"}}, -{"pk": 1735, "model": "group.group", "fields": {"charter": "charter-ietf-pufi", "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "pufi", "comments": "1st meeting at 71st IETF - Philadelphia, PA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Procedures Update for IETF"}}, -{"pk": 1736, "model": "group.group", "fields": {"charter": "charter-ietf-canmod", "unused_states": [], "ad": 6699, "parent": 1193, "list_email": "", "acronym": "canmod", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Comparing Approaches to NETCONF Modeling"}}, -{"pk": 1737, "model": "group.group", "fields": {"charter": "charter-ietf-karp", "unused_states": [], "ad": 2329, "parent": 1249, "list_email": "karp@ietf.org", "acronym": "karp", "comments": "1st meeting at 71st IETF - Philadelphia, PA; 2nd meeting at 76th IETF-Hiroshima, Japan - Changed from Security area to Routing area, changed name and acronym from KMART, Key Management for use with Routing Protocols", "list_subscribe": "https://www.ietf.org/mailman/listinfo/karp", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/karp/", "type": "wg", "name": "Keying and Authentication for Routing Protocols"}}, +{"pk": 1734, "model": "group.group", "fields": {"charter": "charter-ietf-tf", "unused_states": [], "ad": null, "parent": 1008, "list_email": "testlist@mail.ietf.org", "acronym": "tf", "comments": "", "list_subscribe": "testlist-request@mail.ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/tf", "type": "wg", "name": "Testing Fun"}}, +{"pk": 1735, "model": "group.group", "fields": {"charter": "charter-ietf-pufi", "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "pufi", "comments": "1st meeting at 71st IETF - Philadelphia, PA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Procedures Update for IETF"}}, +{"pk": 1736, "model": "group.group", "fields": {"charter": "charter-ietf-canmod", "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "canmod", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Comparing Approaches to NETCONF Modeling"}}, +{"pk": 1737, "model": "group.group", "fields": {"charter": "charter-ietf-karp", "unused_states": [], "ad": null, "parent": 1249, "list_email": "karp@ietf.org", "acronym": "karp", "comments": "1st meeting at 71st IETF - Philadelphia, PA; 2nd meeting at 76th IETF-Hiroshima, Japan - Changed from Security area to Routing area, changed name and acronym from KMART, Key Management for use with Routing Protocols", "list_subscribe": "https://www.ietf.org/mailman/listinfo/karp", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/karp/", "type": "wg", "name": "Keying and Authentication for Routing Protocols"}}, {"pk": 1738, "model": "group.group", "fields": {"charter": "charter-ietf-idnabis", "unused_states": [], "ad": null, "parent": 934, "list_email": "idna-update@alvestrand.no", "acronym": "idnabis", "comments": "Chairperson(s): Vinton Cerf", "list_subscribe": "http://www.alvestrand.no/mailman/listinfo/idna-update", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.alvestrand.no/pipermail/idna-update/", "type": "wg", "name": "Internationalized Domain Names in Applications, Revised"}}, -{"pk": 1739, "model": "group.group", "fields": {"charter": "charter-ietf-drinks", "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "drinks@ietf.org", "acronym": "drinks", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/drinks", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/drinks/", "type": "wg", "name": "Data for Reachability of Inter/tra-NetworK SIP"}}, -{"pk": 1740, "model": "group.group", "fields": {"charter": "charter-ietf-ipsecme", "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "ipsec@ietf.org", "acronym": "ipsecme", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ipsec", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipsec/", "type": "wg", "name": "IP Security Maintenance and Extensions"}}, +{"pk": 1739, "model": "group.group", "fields": {"charter": "charter-ietf-drinks", "unused_states": [], "ad": null, "parent": 1683, "list_email": "drinks@ietf.org", "acronym": "drinks", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/drinks", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/drinks/", "type": "wg", "name": "Data for Reachability of Inter/tra-NetworK SIP"}}, +{"pk": 1740, "model": "group.group", "fields": {"charter": "charter-ietf-ipsecme", "unused_states": [], "ad": null, "parent": 1260, "list_email": "ipsec@ietf.org", "acronym": "ipsecme", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ipsec", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ipsec/", "type": "wg", "name": "IP Security Maintenance and Extensions"}}, {"pk": 1741, "model": "group.group", "fields": {"charter": "charter-ietf-morg", "unused_states": [], "ad": null, "parent": 934, "list_email": "morg@ietf.org", "acronym": "morg", "comments": "1st meeting at 72nd IETF - Dublin, Ireland", "list_subscribe": "https://www.ietf.org/mailman/listinfo/morg", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/morg/", "type": "wg", "name": "Message Organization"}}, -{"pk": 1742, "model": "group.group", "fields": {"charter": "charter-ietf-explisp", "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "", "acronym": "explisp", "comments": "1st meeting at 72nd IETF - Dublin, Ireland", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Experimentation in LISP"}}, +{"pk": 1742, "model": "group.group", "fields": {"charter": "charter-ietf-explisp", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "explisp", "comments": "1st meeting at 72nd IETF - Dublin, Ireland", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Experimentation in LISP"}}, {"pk": 1743, "model": "group.group", "fields": {"charter": "charter-ietf-tana", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "tana", "comments": "1st meeting at 72nd IETF - Dublin, Ireland; 2nd meeting at 73rd IETF - Minneapolis, MN", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Techniques for Advanced Networking Applications"}}, -{"pk": 1744, "model": "group.group", "fields": {"charter": "charter-ietf-alto", "unused_states": [], "ad": 105519, "parent": 1324, "list_email": "alto@ietf.org", "acronym": "alto", "comments": "1st meeting at 72nd IETF-Dublin, Ireland; 2nd meeting at 73rd IETF-Minneapolis, MN", "list_subscribe": "https://www.ietf.org/mailman/listinfo/alto", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/alto/", "type": "wg", "name": "Application-Layer Traffic Optimization"}}, +{"pk": 1744, "model": "group.group", "fields": {"charter": "charter-ietf-alto", "unused_states": [], "ad": null, "parent": 1324, "list_email": "alto@ietf.org", "acronym": "alto", "comments": "1st meeting at 72nd IETF-Dublin, Ireland; 2nd meeting at 73rd IETF-Minneapolis, MN", "list_subscribe": "https://www.ietf.org/mailman/listinfo/alto", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/alto/", "type": "wg", "name": "Application-Layer Traffic Optimization"}}, {"pk": 1745, "model": "group.group", "fields": {"charter": "charter-ietf-ippm++", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "ippmxx", "comments": "1st meeting at 72nd IETF-Dublin, Ireland\r\n\r\nWas called ippm++, changed to ippm to avoid undesirable characters, this record changed to ippmxx to\r\navoid further undesirable effects on the website.", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IP Performance Metrics, Next Steps"}}, -{"pk": 1747, "model": "group.group", "fields": {"charter": "charter-ietf-multimob", "unused_states": [], "ad": 100664, "parent": 1052, "list_email": "multimob@ietf.org", "acronym": "multimob", "comments": "1st meeting at 73rd IETF - Minneapolis, MN, 2nd meeting at 75th IETF-Stockholm, Sweden", "list_subscribe": "https://www.ietf.org/mailman/listinfo/multimob", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/multimob/", "type": "wg", "name": "Multicast Mobility"}}, -{"pk": 1748, "model": "group.group", "fields": {"charter": "charter-ietf-oauth", "unused_states": [], "ad": 19177, "parent": 1260, "list_email": "oauth@ietf.org", "acronym": "oauth", "comments": "1st meeting at 73rd IETF-Minneapolis, MN; 2nd meeting at 74th IETF-San Francisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/oauth", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/oauth/", "type": "wg", "name": "Web Authorization Protocol"}}, -{"pk": 1749, "model": "group.group", "fields": {"charter": "charter-ietf-ledbat", "unused_states": [], "ad": 110856, "parent": 1324, "list_email": "ledbat@ietf.org", "acronym": "ledbat", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ledbat", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ledbat", "type": "wg", "name": "Low Extra Delay Background Transport"}}, -{"pk": 1751, "model": "group.group", "fields": {"charter": "charter-ietf-lisp", "unused_states": [], "ad": 100664, "parent": 1052, "list_email": "lisp@ietf.org", "acronym": "lisp", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/lisp", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/lisp/", "type": "wg", "name": "Locator/ID Separation Protocol"}}, -{"pk": 1752, "model": "group.group", "fields": {"charter": "charter-ietf-6ai", "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "", "acronym": "6ai", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPv6 Address Independence"}}, -{"pk": 1753, "model": "group.group", "fields": {"charter": "charter-ietf-shara", "unused_states": [], "ad": 17253, "parent": 1324, "list_email": "", "acronym": "shara", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Sharing of an IPv4 Address"}}, -{"pk": 1754, "model": "group.group", "fields": {"charter": "charter-ietf-pre8prob", "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "pre8prob", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Pre-5378 Problem"}}, -{"pk": 1755, "model": "group.group", "fields": {"charter": "charter-ietf-mif", "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "mif@ietf.org", "acronym": "mif", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/mif", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mif", "type": "wg", "name": "Multiple Interfaces"}}, -{"pk": 1756, "model": "group.group", "fields": {"charter": "charter-ietf-netext", "unused_states": [], "ad": 100664, "parent": 1052, "list_email": "netext@ietf.org", "acronym": "netext", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/netext", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/netext/", "type": "wg", "name": "Network-Based Mobility Extensions"}}, -{"pk": 1757, "model": "group.group", "fields": {"charter": "charter-ietf-storm", "unused_states": [], "ad": 105519, "parent": 1324, "list_email": "storm@ietf.org", "acronym": "storm", "comments": "1st meeting 74th IETF-San Francisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/storm", "state": "active", "time": "2012-02-03 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/storm/", "type": "wg", "name": "STORage Maintenance"}}, +{"pk": 1747, "model": "group.group", "fields": {"charter": "charter-ietf-multimob", "unused_states": [], "ad": null, "parent": 1052, "list_email": "multimob@ietf.org", "acronym": "multimob", "comments": "1st meeting at 73rd IETF - Minneapolis, MN, 2nd meeting at 75th IETF-Stockholm, Sweden", "list_subscribe": "https://www.ietf.org/mailman/listinfo/multimob", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/multimob/", "type": "wg", "name": "Multicast Mobility"}}, +{"pk": 1748, "model": "group.group", "fields": {"charter": "charter-ietf-oauth", "unused_states": [], "ad": null, "parent": 1260, "list_email": "oauth@ietf.org", "acronym": "oauth", "comments": "1st meeting at 73rd IETF-Minneapolis, MN; 2nd meeting at 74th IETF-San Francisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/oauth", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/oauth/", "type": "wg", "name": "Web Authorization Protocol"}}, +{"pk": 1749, "model": "group.group", "fields": {"charter": "charter-ietf-ledbat", "unused_states": [], "ad": null, "parent": 1324, "list_email": "ledbat@ietf.org", "acronym": "ledbat", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ledbat", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ledbat", "type": "wg", "name": "Low Extra Delay Background Transport"}}, +{"pk": 1751, "model": "group.group", "fields": {"charter": "charter-ietf-lisp", "unused_states": [], "ad": null, "parent": 1052, "list_email": "lisp@ietf.org", "acronym": "lisp", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/lisp", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/lisp/", "type": "wg", "name": "Locator/ID Separation Protocol"}}, +{"pk": 1752, "model": "group.group", "fields": {"charter": "charter-ietf-6ai", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "6ai", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPv6 Address Independence"}}, +{"pk": 1753, "model": "group.group", "fields": {"charter": "charter-ietf-shara", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "shara", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Sharing of an IPv4 Address"}}, +{"pk": 1754, "model": "group.group", "fields": {"charter": "charter-ietf-pre8prob", "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "pre8prob", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Pre-5378 Problem"}}, +{"pk": 1755, "model": "group.group", "fields": {"charter": "charter-ietf-mif", "unused_states": [], "ad": null, "parent": 1052, "list_email": "mif@ietf.org", "acronym": "mif", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/mif", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mif", "type": "wg", "name": "Multiple Interfaces"}}, +{"pk": 1756, "model": "group.group", "fields": {"charter": "charter-ietf-netext", "unused_states": [], "ad": null, "parent": 1052, "list_email": "netext@ietf.org", "acronym": "netext", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/netext", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/netext/", "type": "wg", "name": "Network-Based Mobility Extensions"}}, +{"pk": 1757, "model": "group.group", "fields": {"charter": "charter-ietf-storm", "unused_states": [], "ad": null, "parent": 1324, "list_email": "storm@ietf.org", "acronym": "storm", "comments": "1st meeting 74th IETF-San Francisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/storm", "state": "active", "time": "2012-02-03 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/storm/", "type": "wg", "name": "STORage Maintenance"}}, {"pk": 1758, "model": "group.group", "fields": {"charter": "charter-ietf-mmox", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "mmox", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Massively Multi-Player Games and Applications"}}, -{"pk": 1759, "model": "group.group", "fields": {"charter": "charter-ietf-yam", "unused_states": [], "ad": 18321, "parent": 934, "list_email": "yam@ietf.org", "acronym": "yam", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "yam-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/yam/", "type": "wg", "name": "Yet Another Mail"}}, -{"pk": 1760, "model": "group.group", "fields": {"charter": "charter-ietf-atoca", "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "atoca@ietf.org", "acronym": "atoca", "comments": "1st meeting at 74th IETF-San Fancisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/atoca", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/atoca", "type": "wg", "name": "Authority-to-Citizen Alert"}}, -{"pk": 1761, "model": "group.group", "fields": {"charter": "charter-ietf-xmpp", "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "xmpp@ietf.org", "acronym": "xmpp", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/xmpp", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/xmpp/", "type": "wg", "name": "Extensible Messaging and Presence Protocol"}}, -{"pk": 1762, "model": "group.group", "fields": {"charter": "charter-ietf-sipcore", "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "sipcore@ietf.org", "acronym": "sipcore", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/sipcore", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sipcore/", "type": "wg", "name": "Session Initiation Protocol Core"}}, -{"pk": 1763, "model": "group.group", "fields": {"charter": "charter-ietf-dispatch", "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "dispatch@ietf.org", "acronym": "dispatch", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/dispatch", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dispatch/", "type": "wg", "name": "Dispatch"}}, -{"pk": 1764, "model": "group.group", "fields": {"charter": "charter-ietf-mptcp", "unused_states": [], "ad": 110856, "parent": 1324, "list_email": "multipathtcp@ietf.org", "acronym": "mptcp", "comments": "1st meeting at 75th IETF-Stockholm, Sweden; 2nd meeting at 76th IETF-Hiroshima, Japan", "list_subscribe": "https://www.ietf.org/mailman/listinfo/multipathtcp", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/multipathtcp/", "type": "wg", "name": "Multipath TCP"}}, -{"pk": 1765, "model": "group.group", "fields": {"charter": "charter-ietf-codec", "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "codec@ietf.org", "acronym": "codec", "comments": "1st meeting at 75th IETF-Stockholm, Sweden; 2nd meeting at 76th IETF-Hiroshima, Japan", "list_subscribe": "https://www.ietf.org/mailman/listinfo/codec", "state": "active", "time": "2012-09-17 08:28:30", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/codec/", "type": "wg", "name": "Internet Wideband Audio Codec"}}, -{"pk": 1766, "model": "group.group", "fields": {"charter": "charter-ietf-netext2", "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "", "acronym": "netext2", "comments": "1st meeting at 75th IETF-Stockholm, Sweden", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network-Based Mobilty Extension, 2nd Stage"}}, +{"pk": 1759, "model": "group.group", "fields": {"charter": "charter-ietf-yam", "unused_states": [], "ad": null, "parent": 934, "list_email": "yam@ietf.org", "acronym": "yam", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "yam-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/yam/", "type": "wg", "name": "Yet Another Mail"}}, +{"pk": 1760, "model": "group.group", "fields": {"charter": "charter-ietf-atoca", "unused_states": [], "ad": null, "parent": 1683, "list_email": "atoca@ietf.org", "acronym": "atoca", "comments": "1st meeting at 74th IETF-San Fancisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/atoca", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/atoca", "type": "wg", "name": "Authority-to-Citizen Alert"}}, +{"pk": 1761, "model": "group.group", "fields": {"charter": "charter-ietf-xmpp", "unused_states": [], "ad": null, "parent": 1683, "list_email": "xmpp@ietf.org", "acronym": "xmpp", "comments": "1st meeting at 74th IETF-San Francisco, CA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/xmpp", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/xmpp/", "type": "wg", "name": "Extensible Messaging and Presence Protocol"}}, +{"pk": 1762, "model": "group.group", "fields": {"charter": "charter-ietf-sipcore", "unused_states": [], "ad": null, "parent": 1683, "list_email": "sipcore@ietf.org", "acronym": "sipcore", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/sipcore", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sipcore/", "type": "wg", "name": "Session Initiation Protocol Core"}}, +{"pk": 1763, "model": "group.group", "fields": {"charter": "charter-ietf-dispatch", "unused_states": [], "ad": null, "parent": 1683, "list_email": "dispatch@ietf.org", "acronym": "dispatch", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/dispatch", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dispatch/", "type": "wg", "name": "Dispatch"}}, +{"pk": 1764, "model": "group.group", "fields": {"charter": "charter-ietf-mptcp", "unused_states": [], "ad": null, "parent": 1324, "list_email": "multipathtcp@ietf.org", "acronym": "mptcp", "comments": "1st meeting at 75th IETF-Stockholm, Sweden; 2nd meeting at 76th IETF-Hiroshima, Japan", "list_subscribe": "https://www.ietf.org/mailman/listinfo/multipathtcp", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/multipathtcp/", "type": "wg", "name": "Multipath TCP"}}, +{"pk": 1765, "model": "group.group", "fields": {"charter": "charter-ietf-codec", "unused_states": [], "ad": null, "parent": 1683, "list_email": "codec@ietf.org", "acronym": "codec", "comments": "1st meeting at 75th IETF-Stockholm, Sweden; 2nd meeting at 76th IETF-Hiroshima, Japan", "list_subscribe": "https://www.ietf.org/mailman/listinfo/codec", "state": "active", "time": "2012-09-17 08:28:30", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/codec/", "type": "wg", "name": "Internet Wideband Audio Codec"}}, +{"pk": 1766, "model": "group.group", "fields": {"charter": "charter-ietf-netext2", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "netext2", "comments": "1st meeting at 75th IETF-Stockholm, Sweden", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Network-Based Mobilty Extension, 2nd Stage"}}, {"pk": 1767, "model": "group.group", "fields": {"charter": "charter-ietf-ogpx", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "ogpx", "comments": "1st meeting at 75th IETF-Stockholm, Sweden", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Open Grid Protocol"}}, -{"pk": 1768, "model": "group.group", "fields": {"charter": "charter-ietf-sipclf", "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "sip-clf@ietf.org", "acronym": "sipclf", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/sip-clf", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sip-clf/", "type": "wg", "name": "SIP Common Log Format"}}, -{"pk": 1769, "model": "group.group", "fields": {"charter": "charter-ietf-vwrap", "unused_states": [], "ad": 105907, "parent": 934, "list_email": "vwrap@ietf.org", "acronym": "vwrap", "comments": "", "list_subscribe": "vwrap-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/vwrap/", "type": "wg", "name": "Virtual World Region Agent Protocol"}}, +{"pk": 1768, "model": "group.group", "fields": {"charter": "charter-ietf-sipclf", "unused_states": [], "ad": null, "parent": 1683, "list_email": "sip-clf@ietf.org", "acronym": "sipclf", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/sip-clf", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sip-clf/", "type": "wg", "name": "SIP Common Log Format"}}, +{"pk": 1769, "model": "group.group", "fields": {"charter": "charter-ietf-vwrap", "unused_states": [], "ad": null, "parent": 934, "list_email": "vwrap@ietf.org", "acronym": "vwrap", "comments": "", "list_subscribe": "vwrap-request@ietf.org", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/vwrap/", "type": "wg", "name": "Virtual World Region Agent Protocol"}}, {"pk": 1770, "model": "group.group", "fields": {"charter": "charter-ietf-grobj", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "grobj", "comments": "1st meeting at 76th IETF-Hiroshima, Japan", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Generic Referral Object"}}, -{"pk": 1771, "model": "group.group", "fields": {"charter": "charter-ietf-ppsp", "unused_states": [], "ad": 105519, "parent": 1324, "list_email": "ppsp@ietf.org", "acronym": "ppsp", "comments": "1st meeting 76th IETF-Hiroshima, Japan", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ppsp", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ppsp/", "type": "wg", "name": "Peer to Peer Streaming Protocol"}}, +{"pk": 1771, "model": "group.group", "fields": {"charter": "charter-ietf-ppsp", "unused_states": [], "ad": null, "parent": 1324, "list_email": "ppsp@ietf.org", "acronym": "ppsp", "comments": "1st meeting 76th IETF-Hiroshima, Japan", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ppsp", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ppsp/", "type": "wg", "name": "Peer to Peer Streaming Protocol"}}, {"pk": 1772, "model": "group.group", "fields": {"charter": "charter-ietf-homegate", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "homegate", "comments": "1st meeting at 76th IETF-Hiroshima, Japan; 2nd meeting at 78th IETF-Maastricht, Netherlands", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Broadband Home Gateway"}}, -{"pk": 1773, "model": "group.group", "fields": {"charter": "charter-ietf-aplusp", "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "", "acronym": "aplusp", "comments": "1st meeting - 76th IETF-Hiroshima, Japan", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Address Plus Port"}}, +{"pk": 1773, "model": "group.group", "fields": {"charter": "charter-ietf-aplusp", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "aplusp", "comments": "1st meeting - 76th IETF-Hiroshima, Japan", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Address Plus Port"}}, {"pk": 1774, "model": "group.group", "fields": {"charter": "charter-ietf-6lowapp", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "6lowapp", "comments": "1st meeting at 76th IETF-Hiroshima, Japan; 2nd meeting at 77th IETF-Anaheim, CA, USA; Become a WG on 3-9-10 and name changed to Constrained RESTful Environments (core)", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Application Protocols for Low-power V6 Networks"}}, -{"pk": 1775, "model": "group.group", "fields": {"charter": "charter-ietf-conex", "unused_states": [], "ad": 110856, "parent": 1324, "list_email": "conex@ietf.org", "acronym": "conex", "comments": "1st meeting at 76th IETF-Hiroshima, Japan", "list_subscribe": "https://www.ietf.org/mailman/listinfo/conex", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/conex/", "type": "wg", "name": "Congestion Exposure"}}, -{"pk": 1776, "model": "group.group", "fields": {"charter": "charter-ietf-nat66", "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "", "acronym": "nat66", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPv6-to-IPv6 Network Address Translation"}}, -{"pk": 1777, "model": "group.group", "fields": {"charter": "charter-ietf-hybi", "unused_states": [], "ad": 21684, "parent": 934, "list_email": "hybi@ietf.org", "acronym": "hybi", "comments": "1st meeting at 76th IETF-Hiroshima, Japan", "list_subscribe": "https://www.ietf.org/mailman/listinfo/hybi", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/hybi/", "type": "wg", "name": "BiDirectional or Server-Initiated HTTP"}}, -{"pk": 1778, "model": "group.group", "fields": {"charter": "charter-ietf-iri", "unused_states": [], "ad": 18321, "parent": 934, "list_email": "public-iri@w3.org", "acronym": "iri", "comments": "1st meeting at 76th IETF-Hiroshima, Japan", "list_subscribe": "public-iri-request@w3.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.w3.org/Archives/Public/public-iri/", "type": "wg", "name": "Internationalized Resource Identifiers"}}, -{"pk": 1779, "model": "group.group", "fields": {"charter": "charter-ietf-intareawg", "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "int-area@ietf.org", "acronym": "intareawg", "comments": "See", "list_subscribe": "https://www.ietf.org/mailman/listinfo/int-area", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/int-area/", "type": "wg", "name": "Internet Area Proposed Working Group"}}, -{"pk": 1780, "model": "group.group", "fields": {"charter": "charter-ietf-decade", "unused_states": [], "ad": 105519, "parent": 1324, "list_email": "decade@ietf.org", "acronym": "decade", "comments": "1st meeting at 76th IETF-Hiroshima, Japan; 2nd meeting at 77th IETF-Anaheim, CA, USA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/decade", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/decade/", "type": "wg", "name": "Decoupled Application Data Enroute"}}, -{"pk": 1781, "model": "group.group", "fields": {"charter": "charter-ietf-httpstate", "unused_states": [], "ad": 105907, "parent": 934, "list_email": "http-state@ietf.org", "acronym": "httpstate", "comments": "Alternative Archive: http://groups.google.com/group/http-state", "list_subscribe": "https://www.ietf.org/mailman/listinfo/http-state", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/http-state/", "type": "wg", "name": "HTTP State Management Mechanism"}}, -{"pk": 1782, "model": "group.group", "fields": {"charter": "charter-ietf-martini", "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "martini@ietf.org", "acronym": "martini", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/martini", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/martini/", "type": "wg", "name": "Multiple AoR reachabiliTy InformatioN Indication"}}, -{"pk": 1783, "model": "group.group", "fields": {"charter": "charter-ietf-marf", "unused_states": [], "ad": 21684, "parent": 934, "list_email": "marf@ietf.org", "acronym": "marf", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/marf", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/marf/", "type": "wg", "name": "Messaging Abuse Reporting Format"}}, -{"pk": 1784, "model": "group.group", "fields": {"charter": "charter-ietf-newprep", "unused_states": [], "ad": 105907, "parent": 934, "list_email": "", "acronym": "newprep", "comments": "1st meeting at 77th IETF-Anaheim, CA, USA;\r\nBecame PRECIS working group 2010-06-11", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Stringprep after IDNA2008"}}, +{"pk": 1775, "model": "group.group", "fields": {"charter": "charter-ietf-conex", "unused_states": [], "ad": null, "parent": 1324, "list_email": "conex@ietf.org", "acronym": "conex", "comments": "1st meeting at 76th IETF-Hiroshima, Japan", "list_subscribe": "https://www.ietf.org/mailman/listinfo/conex", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/conex/", "type": "wg", "name": "Congestion Exposure"}}, +{"pk": 1776, "model": "group.group", "fields": {"charter": "charter-ietf-nat66", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "nat66", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "IPv6-to-IPv6 Network Address Translation"}}, +{"pk": 1777, "model": "group.group", "fields": {"charter": "charter-ietf-hybi", "unused_states": [], "ad": null, "parent": 934, "list_email": "hybi@ietf.org", "acronym": "hybi", "comments": "1st meeting at 76th IETF-Hiroshima, Japan", "list_subscribe": "https://www.ietf.org/mailman/listinfo/hybi", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/hybi/", "type": "wg", "name": "BiDirectional or Server-Initiated HTTP"}}, +{"pk": 1778, "model": "group.group", "fields": {"charter": "charter-ietf-iri", "unused_states": [], "ad": null, "parent": 934, "list_email": "public-iri@w3.org", "acronym": "iri", "comments": "1st meeting at 76th IETF-Hiroshima, Japan", "list_subscribe": "public-iri-request@w3.org", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://lists.w3.org/Archives/Public/public-iri/", "type": "wg", "name": "Internationalized Resource Identifiers"}}, +{"pk": 1779, "model": "group.group", "fields": {"charter": "charter-ietf-intareawg", "unused_states": [], "ad": null, "parent": 1052, "list_email": "int-area@ietf.org", "acronym": "intareawg", "comments": "See", "list_subscribe": "https://www.ietf.org/mailman/listinfo/int-area", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/int-area/", "type": "wg", "name": "Internet Area Proposed Working Group"}}, +{"pk": 1780, "model": "group.group", "fields": {"charter": "charter-ietf-decade", "unused_states": [], "ad": null, "parent": 1324, "list_email": "decade@ietf.org", "acronym": "decade", "comments": "1st meeting at 76th IETF-Hiroshima, Japan; 2nd meeting at 77th IETF-Anaheim, CA, USA", "list_subscribe": "https://www.ietf.org/mailman/listinfo/decade", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/decade/", "type": "wg", "name": "Decoupled Application Data Enroute"}}, +{"pk": 1781, "model": "group.group", "fields": {"charter": "charter-ietf-httpstate", "unused_states": [], "ad": null, "parent": 934, "list_email": "http-state@ietf.org", "acronym": "httpstate", "comments": "Alternative Archive: http://groups.google.com/group/http-state", "list_subscribe": "https://www.ietf.org/mailman/listinfo/http-state", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/http-state/", "type": "wg", "name": "HTTP State Management Mechanism"}}, +{"pk": 1782, "model": "group.group", "fields": {"charter": "charter-ietf-martini", "unused_states": [], "ad": null, "parent": 1683, "list_email": "martini@ietf.org", "acronym": "martini", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/martini", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/martini/", "type": "wg", "name": "Multiple AoR reachabiliTy InformatioN Indication"}}, +{"pk": 1783, "model": "group.group", "fields": {"charter": "charter-ietf-marf", "unused_states": [], "ad": null, "parent": 934, "list_email": "marf@ietf.org", "acronym": "marf", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/marf", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/marf/", "type": "wg", "name": "Messaging Abuse Reporting Format"}}, +{"pk": 1784, "model": "group.group", "fields": {"charter": "charter-ietf-newprep", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "newprep", "comments": "1st meeting at 77th IETF-Anaheim, CA, USA;\r\nBecame PRECIS working group 2010-06-11", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Stringprep after IDNA2008"}}, {"pk": 1785, "model": "group.group", "fields": {"charter": "charter-ietf-rydeirde", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "rydeirde", "comments": "1st meeting at 77th IETF-Anaheim, CA, USA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Registry Data Escrow/Internet Registration Escrow"}}, -{"pk": 1786, "model": "group.group", "fields": {"charter": "charter-ietf-wgdtspec", "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "wgdtspec", "comments": "1st meeting at 77th IETF-Anaheim, CA, USA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Review of Datatracker Specifications to Support"}}, +{"pk": 1786, "model": "group.group", "fields": {"charter": "charter-ietf-wgdtspec", "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "wgdtspec", "comments": "1st meeting at 77th IETF-Anaheim, CA, USA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Review of Datatracker Specifications to Support"}}, {"pk": 1787, "model": "group.group", "fields": {"charter": "charter-ietf-e2md", "unused_states": [], "ad": null, "parent": 1683, "list_email": "", "acronym": "e2md", "comments": "1st meeting at 77th IETF-Anaheim, CA, USA", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "E. 164 to Metadata"}}, -{"pk": 1788, "model": "group.group", "fields": {"charter": "charter-ietf-siprec", "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "siprec@ietf.org", "acronym": "siprec", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/siprec", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/siprec/", "type": "wg", "name": "SIP Recording"}}, -{"pk": 1789, "model": "group.group", "fields": {"charter": "charter-ietf-core", "unused_states": [], "ad": 21684, "parent": 934, "list_email": "core@ietf.org", "acronym": "core", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/core", "state": "active", "time": "2012-09-10 16:56:30", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/core/", "type": "wg", "name": "Constrained RESTful Environments"}}, -{"pk": 1791, "model": "group.group", "fields": {"charter": "charter-ietf-soc", "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "sip-overload@ietf.org", "acronym": "soc", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/sip-overload", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sip-overload/", "type": "wg", "name": "SIP Overload Control"}}, -{"pk": 1792, "model": "group.group", "fields": {"charter": "charter-ietf-urnbis", "unused_states": [], "ad": 21684, "parent": 934, "list_email": "urn@ietf.org", "acronym": "urnbis", "comments": "1st meeting at 78th IETF-Maastricht, Netherlands", "list_subscribe": "https://www.ietf.org/mailman/listinfo/urn", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/urn/", "type": "wg", "name": "Uniform Resource Names, Revised"}}, -{"pk": 1793, "model": "group.group", "fields": {"charter": "charter-ietf-fedauth", "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "", "acronym": "fedauth", "comments": "1st meeting at IETF 78-Maastricht, Netherlands", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Federated Authentication Beyond the Web"}}, -{"pk": 1794, "model": "group.group", "fields": {"charter": "charter-ietf-hasmat", "unused_states": [], "ad": 105907, "parent": 934, "list_email": "", "acronym": "hasmat", "comments": "1st meeting at IETF 78-Maastricht, Netherlands", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "HTTP Application Security Minus Authentication and Transport"}}, -{"pk": 1795, "model": "group.group", "fields": {"charter": "charter-ietf-salud", "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "salud@ietf.org", "acronym": "salud", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/salud", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/salud/", "type": "wg", "name": "Sip ALerting for User Devices"}}, -{"pk": 1796, "model": "group.group", "fields": {"charter": "charter-ietf-cuss", "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "cuss@ietf.org", "acronym": "cuss", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/cuss", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/cuss/", "type": "wg", "name": "Call Control UUI Service for SIP"}}, -{"pk": 1797, "model": "group.group", "fields": {"charter": "charter-ietf-splices", "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "splices@ietf.org", "acronym": "splices", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/splices", "state": "conclude", "time": "2012-01-25 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/splices/", "type": "wg", "name": "looSely-couPLed sIp deviCES"}}, -{"pk": 1798, "model": "group.group", "fields": {"charter": "charter-ietf-precis", "unused_states": [], "ad": 18321, "parent": 934, "list_email": "precis@ietf.org", "acronym": "precis", "comments": "was NEWPREP BOF", "list_subscribe": "https://www.ietf.org/mailman/listinfo/precis", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/precis/", "type": "wg", "name": "Preparation and Comparison of Internationalized Strings"}}, -{"pk": 1799, "model": "group.group", "fields": {"charter": "charter-ietf-ftpext2", "unused_states": [], "ad": 18321, "parent": 934, "list_email": "ftpext@ietf.org", "acronym": "ftpext2", "comments": "1st meeting at IETF 78 - Maastricht, Netherlands", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ftpext", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ftpext/", "type": "wg", "name": "FTP Extensions, 2nd edition"}}, -{"pk": 1800, "model": "group.group", "fields": {"charter": "charter-ietf-pcp", "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "pcp@ietf.org", "acronym": "pcp", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/pcp", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pcp/", "type": "wg", "name": "Port Control Protocol"}}, -{"pk": 1801, "model": "group.group", "fields": {"charter": "charter-ietf-eman", "unused_states": [], "ad": 105682, "parent": 1193, "list_email": "eman@ietf.org", "acronym": "eman", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/eman", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/eman", "type": "wg", "name": "Energy Management"}}, -{"pk": 1802, "model": "group.group", "fields": {"charter": "charter-ietf-websec", "unused_states": [], "ad": 21684, "parent": 934, "list_email": "websec@ietf.org", "acronym": "websec", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/websec", "state": "active", "time": "2012-07-30 13:20:27", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/websec/", "type": "wg", "name": "Web Security"}}, -{"pk": 1803, "model": "group.group", "fields": {"charter": "charter-ietf-homenet", "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "homenet@ietf.org", "acronym": "homenet", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/homenet", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/homenet/", "type": "wg", "name": "Home Networking"}}, -{"pk": 1804, "model": "group.group", "fields": {"charter": "charter-ietf-abfab", "unused_states": [], "ad": 19177, "parent": 1260, "list_email": "abfab@ietf.org", "acronym": "abfab", "comments": "Note that this proposed WG emerged from the FEDAUTH BoF held\r\nat IETF 78.", "list_subscribe": "https://www.ietf.org/mailman/listinfo/abfab", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/abfab/", "type": "wg", "name": "Application Bridging for Federated Access Beyond web"}}, -{"pk": 1805, "model": "group.group", "fields": {"charter": "charter-ietf-appsawg", "unused_states": [], "ad": 21684, "parent": 934, "list_email": "apps-discuss@ietf.org", "acronym": "appsawg", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/apps-discuss", "state": "active", "time": "2012-07-03 07:35:06", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/apps-discuss/", "type": "wg", "name": "Applications Area Working Group"}}, -{"pk": 1806, "model": "group.group", "fields": {"charter": "charter-ietf-iddtspec", "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "iddtspec", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Review of Datatracker Specifications to Follow Internet-Draft Activities"}}, -{"pk": 1807, "model": "group.group", "fields": {"charter": "charter-ietf-armd", "unused_states": [], "ad": 101568, "parent": 1193, "list_email": "armd@ietf.org", "acronym": "armd", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/armd", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/armd/", "type": "wg", "name": "Address Resolution for Massive numbers of hosts in the Data center"}}, -{"pk": 1808, "model": "group.group", "fields": {"charter": "charter-ietf-nbs", "unused_states": [], "ad": 17253, "parent": 1324, "list_email": "", "acronym": "nbs", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Name-Based Sockets"}}, -{"pk": 1809, "model": "group.group", "fields": {"charter": "charter-ietf-lwip", "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "", "acronym": "lwip", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Light-Weight IP Protocol Design"}}, -{"pk": 1810, "model": "group.group", "fields": {"charter": "charter-ietf-dane", "unused_states": [], "ad": 19177, "parent": 1260, "list_email": "dane@ietf.org", "acronym": "dane", "comments": "Previously was 'kidns' BOF.", "list_subscribe": "https://www.ietf.org/mailman/listinfo/dane", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dane/", "type": "wg", "name": "DNS-based Authentication of Named Entities"}}, -{"pk": 1811, "model": "group.group", "fields": {"charter": "charter-ietf-scap", "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "", "acronym": "scap", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Synergy of SCAP Program and IETF Activities"}}, -{"pk": 1812, "model": "group.group", "fields": {"charter": "charter-ietf-avtcore", "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "avt@ietf.org", "acronym": "avtcore", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/avt", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/avt/", "type": "wg", "name": "Audio/Video Transport Core Maintenance"}}, -{"pk": 1813, "model": "group.group", "fields": {"charter": "charter-ietf-avtext", "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "avtext@ietf.org", "acronym": "avtext", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/avtext", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/avtext/", "type": "wg", "name": "Audio/Video Transport Extensions"}}, -{"pk": 1814, "model": "group.group", "fields": {"charter": "charter-ietf-payload", "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "payload@ietf.org", "acronym": "payload", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/payload", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/payload/", "type": "wg", "name": "Audio/Video Transport Payloads"}}, -{"pk": 1815, "model": "group.group", "fields": {"charter": "charter-ietf-xrblock", "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "xrblock@ietf.org", "acronym": "xrblock", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/xrblock", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/xrblock/", "type": "wg", "name": "Metric Blocks for use with RTCP's Extended Report Framework"}}, -{"pk": 1816, "model": "group.group", "fields": {"charter": "charter-ietf-clue", "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "clue@ietf.org", "acronym": "clue", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/clue", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/clue/", "type": "wg", "name": "ControLling mUltiple streams for tElepresence"}}, -{"pk": 1817, "model": "group.group", "fields": {"charter": "charter-ietf-lwig", "unused_states": [], "ad": 100664, "parent": 1052, "list_email": "lwip@ietf.org", "acronym": "lwig", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/lwip", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/lwip", "type": "wg", "name": "Light-Weight Implementation Guidance"}}, -{"pk": 1818, "model": "group.group", "fields": {"charter": "charter-ietf-renum", "unused_states": [], "ad": 101568, "parent": 1193, "list_email": "", "acronym": "renum", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Site Renumbering"}}, -{"pk": 1819, "model": "group.group", "fields": {"charter": "charter-ietf-paws", "unused_states": [], "ad": 18321, "parent": 934, "list_email": "paws@ietf.org", "acronym": "paws", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/paws", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/paws/", "type": "wg", "name": "Protocol to Access WS database"}}, -{"pk": 1820, "model": "group.group", "fields": {"charter": "charter-ietf-rtcweb", "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "rtcweb@ietf.org", "acronym": "rtcweb", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/rtcweb", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rtcweb/", "type": "wg", "name": "Real-Time Communication in WEB-browsers"}}, -{"pk": 1821, "model": "group.group", "fields": {"charter": "charter-ietf-plasma", "unused_states": [], "ad": 19177, "parent": 1260, "list_email": "", "acronym": "plasma", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Policy Augmented S/Mime"}}, -{"pk": 1822, "model": "group.group", "fields": {"charter": "charter-ietf-cdni", "unused_states": [], "ad": 105519, "parent": 1324, "list_email": "cdni@ietf.org", "acronym": "cdni", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/cdni", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/cdni/", "type": "wg", "name": "Content Delivery Networks Interconnection"}}, -{"pk": 1823, "model": "group.group", "fields": {"charter": "charter-ietf-vipr", "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "vipr@ietf.org", "acronym": "vipr", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/vipr", "state": "active", "time": "2012-02-10 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/vipr/", "type": "wg", "name": "Verification Involving PSTN Reachability"}}, -{"pk": 1824, "model": "group.group", "fields": {"charter": "charter-ietf-6renum", "unused_states": [], "ad": 101568, "parent": 1193, "list_email": "renum@ietf.org", "acronym": "6renum", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/renum", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/renum/", "type": "wg", "name": "IPv6 Site Renumbering"}}, -{"pk": 1825, "model": "group.group", "fields": {"charter": "charter-ietf-multrans", "unused_states": [], "ad": 101568, "parent": 1193, "list_email": "multrans@ietf.org", "acronym": "multrans", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/multrans", "state": "bof", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Multicast Transition "}}, -{"pk": 1826, "model": "group.group", "fields": {"charter": "charter-ietf-httpauth", "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "http-auth@ietf.org", "acronym": "httpauth", "comments": "BOF at IETF 85", "list_subscribe": "https://www.ietf.org/mailman/listinfo/http-auth", "state": "bof", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/http-auth/", "type": "wg", "name": "HTTP Authentication Mechanisms"}}, -{"pk": 1827, "model": "group.group", "fields": {"charter": "charter-ietf-repute", "unused_states": [], "ad": 18321, "parent": 934, "list_email": "domainrep@ietf.org", "acronym": "repute", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/domainrep/", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/domainrep/", "type": "wg", "name": "Reputation Services"}}, -{"pk": 1828, "model": "group.group", "fields": {"charter": "charter-ietf-cicm", "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "cicm@ietf.org", "acronym": "cicm", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/cicm", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/cicm/", "type": "wg", "name": "Common Interface to Cryptographic Modules"}}, -{"pk": 1829, "model": "group.group", "fields": {"charter": "charter-ietf-woes", "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "woes@ietf.org", "acronym": "woes", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/woes", "state": "bof", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/woes/", "type": "wg", "name": "Web Object Encryption and Signing"}}, -{"pk": 1830, "model": "group.group", "fields": {"charter": "charter-ietf-jose", "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "jose@ietf.org", "acronym": "jose", "comments": "Originally WOES BOF at IETF 81", "list_subscribe": "https://www.ietf.org/mailman/listinfo/jose", "state": "active", "time": "2012-08-01 14:21:17", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/jose/", "type": "wg", "name": "Javascript Object Signing and Encryption"}}, -{"pk": 1831, "model": "group.group", "fields": {"charter": "charter-ietf-mile", "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "mile@ietf.org", "acronym": "mile", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/mile", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mile/", "type": "wg", "name": "Managed Incident Lightweight Exchange"}}, -{"pk": 1832, "model": "group.group", "fields": {"charter": "charter-ietf-bfcpbis", "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "bfcpbis@ietf.org", "acronym": "bfcpbis", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/bfcpbis", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/bfcpbis/", "type": "wg", "name": "Binary Floor Control Protocol Bis "}}, -{"pk": 1833, "model": "group.group", "fields": {"charter": "charter-ietf-dcon", "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "", "acronym": "dcon", "comments": "", "list_subscribe": "", "state": "bof", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Distributed Conferencing"}}, -{"pk": 1834, "model": "group.group", "fields": {"charter": "charter-ietf-weirds", "unused_states": [], "ad": 18321, "parent": 934, "list_email": "weirds@ietf.org", "acronym": "weirds", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/weirds", "state": "active", "time": "2012-02-23 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/weirds/", "type": "wg", "name": "Web Extensible Internet Registration Data Service"}}, -{"pk": 1835, "model": "group.group", "fields": {"charter": "charter-ietf-sdn", "unused_states": [], "ad": 104198, "parent": 1249, "list_email": "", "acronym": "sdn", "comments": "", "list_subscribe": "", "state": "bof", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Software Driven Networks "}}, -{"pk": 1836, "model": "group.group", "fields": {"charter": "charter-ietf-spfbis", "unused_states": [], "ad": 18321, "parent": 934, "list_email": "spfbis@ietf.org", "acronym": "spfbis", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/spfbis", "state": "active", "time": "2012-02-07 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/spfbis/", "type": "wg", "name": "SPF Update"}}, -{"pk": 1837, "model": "group.group", "fields": {"charter": "charter-ietf-dmm-proposed", "unused_states": [], "ad": 21072, "parent": 1052, "list_email": "", "acronym": "dmm-proposed", "comments": "Proposed re-naming of MEXT WG", "list_subscribe": "", "state": "conclude", "time": "2012-01-10 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Distributed Mobility Management (formerly MEXT)"}}, -{"pk": 1838, "model": "group.group", "fields": {"charter": "charter-ietf-rmcat", "unused_states": [], "ad": 110856, "parent": 1324, "list_email": "rmcat@ietf.org", "acronym": "rmcat", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/rmcat", "state": "active", "time": "2012-09-21 09:53:53", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rmcat/", "type": "wg", "name": "RTP Media Congestion Avoidance Techniques"}}, -{"pk": 1839, "model": "group.group", "fields": {"charter": "charter-ietf-sessionid", "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "insipid@ietf.org", "acronym": "insipid", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/insipid", "state": "active", "time": "2012-02-23 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/insipid/", "type": "wg", "name": "INtermediary-safe SIP session ID"}}, -{"pk": 1840, "model": "group.group", "fields": {"charter": "charter-ietf-nvo3", "unused_states": [], "ad": 2329, "parent": 1249, "list_email": "nvo3@ietf.org", "acronym": "nvo3", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/nvo3", "state": "active", "time": "2012-02-23 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/nvo3/", "type": "wg", "name": "Network Virtualization Overlays"}}, -{"pk": 1841, "model": "group.group", "fields": {"charter": "charter-ietf-altoext", "unused_states": [], "ad": 17253, "parent": 1324, "list_email": "", "acronym": "i2aex", "comments": "Originally ALTOEXT; was changed before the 1st BOF.", "list_subscribe": "", "state": "bof", "time": "2012-02-23 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Infrastructure-to-Application Information Exposure"}}, -{"pk": 1842, "model": "group.group", "fields": {"charter": "charter-ietf-scim", "unused_states": [], "ad": 21684, "parent": 934, "list_email": "scim@ietf.org", "acronym": "scim", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/scim", "state": "active", "time": "2012-02-23 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/scim/", "type": "wg", "name": "System for Cross-domain Identity Management"}}, -{"pk": 1843, "model": "group.group", "fields": {"charter": "charter-ietf-rpsreqs", "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "rpsreqs", "comments": "", "list_subscribe": "", "state": "bof", "time": "2012-02-23 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Remote Participation System Requirements"}}, -{"pk": 1844, "model": "group.group", "fields": {"charter": "charter-ietf-antitrust", "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "antitrust", "comments": "", "list_subscribe": "", "state": "bof", "time": "2012-02-23 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Does the IETF Need an Anti-Trust Policy"}}, -{"pk": 1845, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 5376, "parent": 1008, "list_email": "", "acronym": "rfcform", "comments": "", "list_subscribe": "", "state": "bof", "time": "2012-02-27 13:37:14", "unused_tags": [], "list_archive": "", "type": "wg", "name": "RFC Format"}}, +{"pk": 1788, "model": "group.group", "fields": {"charter": "charter-ietf-siprec", "unused_states": [], "ad": null, "parent": 1683, "list_email": "siprec@ietf.org", "acronym": "siprec", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/siprec", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/siprec/", "type": "wg", "name": "SIP Recording"}}, +{"pk": 1789, "model": "group.group", "fields": {"charter": "charter-ietf-core", "unused_states": [], "ad": null, "parent": 934, "list_email": "core@ietf.org", "acronym": "core", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/core", "state": "active", "time": "2012-09-10 16:56:30", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/core/", "type": "wg", "name": "Constrained RESTful Environments"}}, +{"pk": 1791, "model": "group.group", "fields": {"charter": "charter-ietf-soc", "unused_states": [], "ad": null, "parent": 1683, "list_email": "sip-overload@ietf.org", "acronym": "soc", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/sip-overload", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sip-overload/", "type": "wg", "name": "SIP Overload Control"}}, +{"pk": 1792, "model": "group.group", "fields": {"charter": "charter-ietf-urnbis", "unused_states": [], "ad": null, "parent": 934, "list_email": "urn@ietf.org", "acronym": "urnbis", "comments": "1st meeting at 78th IETF-Maastricht, Netherlands", "list_subscribe": "https://www.ietf.org/mailman/listinfo/urn", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/urn/", "type": "wg", "name": "Uniform Resource Names, Revised"}}, +{"pk": 1793, "model": "group.group", "fields": {"charter": "charter-ietf-fedauth", "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "fedauth", "comments": "1st meeting at IETF 78-Maastricht, Netherlands", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Federated Authentication Beyond the Web"}}, +{"pk": 1794, "model": "group.group", "fields": {"charter": "charter-ietf-hasmat", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "hasmat", "comments": "1st meeting at IETF 78-Maastricht, Netherlands", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "HTTP Application Security Minus Authentication and Transport"}}, +{"pk": 1795, "model": "group.group", "fields": {"charter": "charter-ietf-salud", "unused_states": [], "ad": null, "parent": 1683, "list_email": "salud@ietf.org", "acronym": "salud", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/salud", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/salud/", "type": "wg", "name": "Sip ALerting for User Devices"}}, +{"pk": 1796, "model": "group.group", "fields": {"charter": "charter-ietf-cuss", "unused_states": [], "ad": null, "parent": 1683, "list_email": "cuss@ietf.org", "acronym": "cuss", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/cuss", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/cuss/", "type": "wg", "name": "Call Control UUI Service for SIP"}}, +{"pk": 1797, "model": "group.group", "fields": {"charter": "charter-ietf-splices", "unused_states": [], "ad": null, "parent": 1683, "list_email": "splices@ietf.org", "acronym": "splices", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/splices", "state": "conclude", "time": "2012-01-25 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/splices/", "type": "wg", "name": "looSely-couPLed sIp deviCES"}}, +{"pk": 1798, "model": "group.group", "fields": {"charter": "charter-ietf-precis", "unused_states": [], "ad": null, "parent": 934, "list_email": "precis@ietf.org", "acronym": "precis", "comments": "was NEWPREP BOF", "list_subscribe": "https://www.ietf.org/mailman/listinfo/precis", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/precis/", "type": "wg", "name": "Preparation and Comparison of Internationalized Strings"}}, +{"pk": 1799, "model": "group.group", "fields": {"charter": "charter-ietf-ftpext2", "unused_states": [], "ad": null, "parent": 934, "list_email": "ftpext@ietf.org", "acronym": "ftpext2", "comments": "1st meeting at IETF 78 - Maastricht, Netherlands", "list_subscribe": "https://www.ietf.org/mailman/listinfo/ftpext", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/ftpext/", "type": "wg", "name": "FTP Extensions, 2nd edition"}}, +{"pk": 1800, "model": "group.group", "fields": {"charter": "charter-ietf-pcp", "unused_states": [], "ad": null, "parent": 1052, "list_email": "pcp@ietf.org", "acronym": "pcp", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/pcp", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/pcp/", "type": "wg", "name": "Port Control Protocol"}}, +{"pk": 1801, "model": "group.group", "fields": {"charter": "charter-ietf-eman", "unused_states": [], "ad": null, "parent": 1193, "list_email": "eman@ietf.org", "acronym": "eman", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/eman", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/eman", "type": "wg", "name": "Energy Management"}}, +{"pk": 1802, "model": "group.group", "fields": {"charter": "charter-ietf-websec", "unused_states": [], "ad": null, "parent": 934, "list_email": "websec@ietf.org", "acronym": "websec", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/websec", "state": "active", "time": "2012-07-30 13:20:27", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/websec/", "type": "wg", "name": "Web Security"}}, +{"pk": 1803, "model": "group.group", "fields": {"charter": "charter-ietf-homenet", "unused_states": [], "ad": null, "parent": 1052, "list_email": "homenet@ietf.org", "acronym": "homenet", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/homenet", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/homenet/", "type": "wg", "name": "Home Networking"}}, +{"pk": 1804, "model": "group.group", "fields": {"charter": "charter-ietf-abfab", "unused_states": [], "ad": null, "parent": 1260, "list_email": "abfab@ietf.org", "acronym": "abfab", "comments": "Note that this proposed WG emerged from the FEDAUTH BoF held\r\nat IETF 78.", "list_subscribe": "https://www.ietf.org/mailman/listinfo/abfab", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/abfab/", "type": "wg", "name": "Application Bridging for Federated Access Beyond web"}}, +{"pk": 1805, "model": "group.group", "fields": {"charter": "charter-ietf-appsawg", "unused_states": [], "ad": null, "parent": 934, "list_email": "apps-discuss@ietf.org", "acronym": "appsawg", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/apps-discuss", "state": "active", "time": "2012-07-03 07:35:06", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/apps-discuss/", "type": "wg", "name": "Applications Area Working Group"}}, +{"pk": 1806, "model": "group.group", "fields": {"charter": "charter-ietf-iddtspec", "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "iddtspec", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Review of Datatracker Specifications to Follow Internet-Draft Activities"}}, +{"pk": 1807, "model": "group.group", "fields": {"charter": "charter-ietf-armd", "unused_states": [], "ad": null, "parent": 1193, "list_email": "armd@ietf.org", "acronym": "armd", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/armd", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/armd/", "type": "wg", "name": "Address Resolution for Massive numbers of hosts in the Data center"}}, +{"pk": 1808, "model": "group.group", "fields": {"charter": "charter-ietf-nbs", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "nbs", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Name-Based Sockets"}}, +{"pk": 1809, "model": "group.group", "fields": {"charter": "charter-ietf-lwip", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "lwip", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Light-Weight IP Protocol Design"}}, +{"pk": 1810, "model": "group.group", "fields": {"charter": "charter-ietf-dane", "unused_states": [], "ad": null, "parent": 1260, "list_email": "dane@ietf.org", "acronym": "dane", "comments": "Previously was 'kidns' BOF.", "list_subscribe": "https://www.ietf.org/mailman/listinfo/dane", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dane/", "type": "wg", "name": "DNS-based Authentication of Named Entities"}}, +{"pk": 1811, "model": "group.group", "fields": {"charter": "charter-ietf-scap", "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "scap", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Synergy of SCAP Program and IETF Activities"}}, +{"pk": 1812, "model": "group.group", "fields": {"charter": "charter-ietf-avtcore", "unused_states": [], "ad": null, "parent": 1683, "list_email": "avt@ietf.org", "acronym": "avtcore", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/avt", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/avt/", "type": "wg", "name": "Audio/Video Transport Core Maintenance"}}, +{"pk": 1813, "model": "group.group", "fields": {"charter": "charter-ietf-avtext", "unused_states": [], "ad": null, "parent": 1683, "list_email": "avtext@ietf.org", "acronym": "avtext", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/avtext", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/avtext/", "type": "wg", "name": "Audio/Video Transport Extensions"}}, +{"pk": 1814, "model": "group.group", "fields": {"charter": "charter-ietf-payload", "unused_states": [], "ad": null, "parent": 1683, "list_email": "payload@ietf.org", "acronym": "payload", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/payload", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/payload/", "type": "wg", "name": "Audio/Video Transport Payloads"}}, +{"pk": 1815, "model": "group.group", "fields": {"charter": "charter-ietf-xrblock", "unused_states": [], "ad": null, "parent": 1683, "list_email": "xrblock@ietf.org", "acronym": "xrblock", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/xrblock", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/xrblock/", "type": "wg", "name": "Metric Blocks for use with RTCP's Extended Report Framework"}}, +{"pk": 1816, "model": "group.group", "fields": {"charter": "charter-ietf-clue", "unused_states": [], "ad": null, "parent": 1683, "list_email": "clue@ietf.org", "acronym": "clue", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/clue", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/clue/", "type": "wg", "name": "ControLling mUltiple streams for tElepresence"}}, +{"pk": 1817, "model": "group.group", "fields": {"charter": "charter-ietf-lwig", "unused_states": [], "ad": null, "parent": 1052, "list_email": "lwip@ietf.org", "acronym": "lwig", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/lwip", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/lwip", "type": "wg", "name": "Light-Weight Implementation Guidance"}}, +{"pk": 1818, "model": "group.group", "fields": {"charter": "charter-ietf-renum", "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "renum", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Site Renumbering"}}, +{"pk": 1819, "model": "group.group", "fields": {"charter": "charter-ietf-paws", "unused_states": [], "ad": null, "parent": 934, "list_email": "paws@ietf.org", "acronym": "paws", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/paws", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/paws/", "type": "wg", "name": "Protocol to Access WS database"}}, +{"pk": 1820, "model": "group.group", "fields": {"charter": "charter-ietf-rtcweb", "unused_states": [], "ad": null, "parent": 1683, "list_email": "rtcweb@ietf.org", "acronym": "rtcweb", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/rtcweb", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rtcweb/", "type": "wg", "name": "Real-Time Communication in WEB-browsers"}}, +{"pk": 1821, "model": "group.group", "fields": {"charter": "charter-ietf-plasma", "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "plasma", "comments": "", "list_subscribe": "", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Policy Augmented S/Mime"}}, +{"pk": 1822, "model": "group.group", "fields": {"charter": "charter-ietf-cdni", "unused_states": [], "ad": null, "parent": 1324, "list_email": "cdni@ietf.org", "acronym": "cdni", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/cdni", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/cdni/", "type": "wg", "name": "Content Delivery Networks Interconnection"}}, +{"pk": 1823, "model": "group.group", "fields": {"charter": "charter-ietf-vipr", "unused_states": [], "ad": null, "parent": 1683, "list_email": "vipr@ietf.org", "acronym": "vipr", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/vipr", "state": "active", "time": "2012-02-10 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/vipr/", "type": "wg", "name": "Verification Involving PSTN Reachability"}}, +{"pk": 1824, "model": "group.group", "fields": {"charter": "charter-ietf-6renum", "unused_states": [], "ad": null, "parent": 1193, "list_email": "renum@ietf.org", "acronym": "6renum", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/renum", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/renum/", "type": "wg", "name": "IPv6 Site Renumbering"}}, +{"pk": 1825, "model": "group.group", "fields": {"charter": "charter-ietf-multrans", "unused_states": [], "ad": null, "parent": 1193, "list_email": "multrans@ietf.org", "acronym": "multrans", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/multrans", "state": "bof", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Multicast Transition "}}, +{"pk": 1826, "model": "group.group", "fields": {"charter": "charter-ietf-httpauth", "unused_states": [], "ad": null, "parent": 1260, "list_email": "http-auth@ietf.org", "acronym": "httpauth", "comments": "BOF at IETF 85", "list_subscribe": "https://www.ietf.org/mailman/listinfo/http-auth", "state": "bof", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/http-auth/", "type": "wg", "name": "HTTP Authentication Mechanisms"}}, +{"pk": 1827, "model": "group.group", "fields": {"charter": "charter-ietf-repute", "unused_states": [], "ad": null, "parent": 934, "list_email": "domainrep@ietf.org", "acronym": "repute", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/domainrep/", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/domainrep/", "type": "wg", "name": "Reputation Services"}}, +{"pk": 1828, "model": "group.group", "fields": {"charter": "charter-ietf-cicm", "unused_states": [], "ad": null, "parent": 1260, "list_email": "cicm@ietf.org", "acronym": "cicm", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/cicm", "state": "conclude", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/cicm/", "type": "wg", "name": "Common Interface to Cryptographic Modules"}}, +{"pk": 1829, "model": "group.group", "fields": {"charter": "charter-ietf-woes", "unused_states": [], "ad": null, "parent": 1260, "list_email": "woes@ietf.org", "acronym": "woes", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/woes", "state": "bof", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/woes/", "type": "wg", "name": "Web Object Encryption and Signing"}}, +{"pk": 1830, "model": "group.group", "fields": {"charter": "charter-ietf-jose", "unused_states": [], "ad": null, "parent": 1260, "list_email": "jose@ietf.org", "acronym": "jose", "comments": "Originally WOES BOF at IETF 81", "list_subscribe": "https://www.ietf.org/mailman/listinfo/jose", "state": "active", "time": "2012-08-01 14:21:17", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/jose/", "type": "wg", "name": "Javascript Object Signing and Encryption"}}, +{"pk": 1831, "model": "group.group", "fields": {"charter": "charter-ietf-mile", "unused_states": [], "ad": null, "parent": 1260, "list_email": "mile@ietf.org", "acronym": "mile", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/mile", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/mile/", "type": "wg", "name": "Managed Incident Lightweight Exchange"}}, +{"pk": 1832, "model": "group.group", "fields": {"charter": "charter-ietf-bfcpbis", "unused_states": [], "ad": null, "parent": 1683, "list_email": "bfcpbis@ietf.org", "acronym": "bfcpbis", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/bfcpbis", "state": "active", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/bfcpbis/", "type": "wg", "name": "Binary Floor Control Protocol Bis "}}, +{"pk": 1833, "model": "group.group", "fields": {"charter": "charter-ietf-dcon", "unused_states": [], "ad": null, "parent": 1683, "list_email": "", "acronym": "dcon", "comments": "", "list_subscribe": "", "state": "bof", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Distributed Conferencing"}}, +{"pk": 1834, "model": "group.group", "fields": {"charter": "charter-ietf-weirds", "unused_states": [], "ad": null, "parent": 934, "list_email": "weirds@ietf.org", "acronym": "weirds", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/weirds", "state": "active", "time": "2012-02-23 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/weirds/", "type": "wg", "name": "Web Extensible Internet Registration Data Service"}}, +{"pk": 1835, "model": "group.group", "fields": {"charter": "charter-ietf-sdn", "unused_states": [], "ad": null, "parent": 1249, "list_email": "", "acronym": "sdn", "comments": "", "list_subscribe": "", "state": "bof", "time": "2011-12-09 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Software Driven Networks "}}, +{"pk": 1836, "model": "group.group", "fields": {"charter": "charter-ietf-spfbis", "unused_states": [], "ad": null, "parent": 934, "list_email": "spfbis@ietf.org", "acronym": "spfbis", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/spfbis", "state": "active", "time": "2012-02-07 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/spfbis/", "type": "wg", "name": "SPF Update"}}, +{"pk": 1837, "model": "group.group", "fields": {"charter": "charter-ietf-dmm-proposed", "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "dmm-proposed", "comments": "Proposed re-naming of MEXT WG", "list_subscribe": "", "state": "conclude", "time": "2012-01-10 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Distributed Mobility Management (formerly MEXT)"}}, +{"pk": 1838, "model": "group.group", "fields": {"charter": "charter-ietf-rmcat", "unused_states": [], "ad": null, "parent": 1324, "list_email": "rmcat@ietf.org", "acronym": "rmcat", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/rmcat", "state": "active", "time": "2012-09-21 09:53:53", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/rmcat/", "type": "wg", "name": "RTP Media Congestion Avoidance Techniques"}}, +{"pk": 1839, "model": "group.group", "fields": {"charter": "charter-ietf-sessionid", "unused_states": [], "ad": null, "parent": 1683, "list_email": "insipid@ietf.org", "acronym": "insipid", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/insipid", "state": "active", "time": "2012-02-23 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/insipid/", "type": "wg", "name": "INtermediary-safe SIP session ID"}}, +{"pk": 1840, "model": "group.group", "fields": {"charter": "charter-ietf-nvo3", "unused_states": [], "ad": null, "parent": 1249, "list_email": "nvo3@ietf.org", "acronym": "nvo3", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/nvo3", "state": "active", "time": "2012-02-23 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/nvo3/", "type": "wg", "name": "Network Virtualization Overlays"}}, +{"pk": 1841, "model": "group.group", "fields": {"charter": "charter-ietf-altoext", "unused_states": [], "ad": null, "parent": 1324, "list_email": "", "acronym": "i2aex", "comments": "Originally ALTOEXT; was changed before the 1st BOF.", "list_subscribe": "", "state": "bof", "time": "2012-02-23 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Infrastructure-to-Application Information Exposure"}}, +{"pk": 1842, "model": "group.group", "fields": {"charter": "charter-ietf-scim", "unused_states": [], "ad": null, "parent": 934, "list_email": "scim@ietf.org", "acronym": "scim", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/scim", "state": "active", "time": "2012-02-23 12:00:00", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/scim/", "type": "wg", "name": "System for Cross-domain Identity Management"}}, +{"pk": 1843, "model": "group.group", "fields": {"charter": "charter-ietf-rpsreqs", "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "rpsreqs", "comments": "", "list_subscribe": "", "state": "bof", "time": "2012-02-23 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Remote Participation System Requirements"}}, +{"pk": 1844, "model": "group.group", "fields": {"charter": "charter-ietf-antitrust", "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "antitrust", "comments": "", "list_subscribe": "", "state": "bof", "time": "2012-02-23 12:00:00", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Does the IETF Need an Anti-Trust Policy"}}, +{"pk": 1845, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1008, "list_email": "", "acronym": "rfcform", "comments": "", "list_subscribe": "", "state": "bof", "time": "2012-02-27 13:37:14", "unused_tags": [], "list_archive": "", "type": "wg", "name": "RFC Format"}}, {"pk": 1846, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 51, "list_email": "", "acronym": "itu-t-wp-5-13", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-02-28 13:45:20", "unused_tags": [], "list_archive": "", "type": "sdo", "name": "ITU-T Working Party 5/13"}}, -{"pk": 1847, "model": "group.group", "fields": {"charter": "charter-ietf-dmm", "unused_states": [], "ad": 100664, "parent": 1052, "list_email": "dmm@ietf.org", "acronym": "dmm", "comments": "Renamed from Mobility EXTensions for IPv6 (mext) in January 2012", "list_subscribe": "https://www.ietf.org/mailman/listinfo/dmm", "state": "active", "time": "2012-03-05 09:38:10", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dmm", "type": "wg", "name": "Distributed Mobility Management"}}, -{"pk": 1848, "model": "group.group", "fields": {"charter": "charter-ietf-sunset4", "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "sunset4@ietf.org", "acronym": "sunset4", "comments": "Originally v4exit, changed before external review.", "list_subscribe": "https://www.ietf.org/mailman/listinfo/sunset4", "state": "active", "time": "2012-04-05 09:20:44", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sunset4/", "type": "wg", "name": "Sunsetting IPv4"}}, +{"pk": 1847, "model": "group.group", "fields": {"charter": "charter-ietf-dmm", "unused_states": [], "ad": null, "parent": 1052, "list_email": "dmm@ietf.org", "acronym": "dmm", "comments": "Renamed from Mobility EXTensions for IPv6 (mext) in January 2012", "list_subscribe": "https://www.ietf.org/mailman/listinfo/dmm", "state": "active", "time": "2012-03-05 09:38:10", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/dmm", "type": "wg", "name": "Distributed Mobility Management"}}, +{"pk": 1848, "model": "group.group", "fields": {"charter": "charter-ietf-sunset4", "unused_states": [], "ad": null, "parent": 1052, "list_email": "sunset4@ietf.org", "acronym": "sunset4", "comments": "Originally v4exit, changed before external review.", "list_subscribe": "https://www.ietf.org/mailman/listinfo/sunset4", "state": "active", "time": "2012-04-05 09:20:44", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/sunset4/", "type": "wg", "name": "Sunsetting IPv4"}}, {"pk": 1849, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 3, "list_email": "icnrg@irtf.org", "acronym": "icnrg", "comments": "", "list_subscribe": "http://irtf.org/mailman/listinfo/icnrg", "state": "active", "time": "2012-04-24 09:47:41", "unused_tags": [], "list_archive": "http://www.irtf.org/mail-archive/web/icnrg/", "type": "rg", "name": "Information-Centric Networking"}}, {"pk": 1850, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "nomcom2012", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-05-03 11:20:20", "unused_tags": [], "list_archive": "", "type": "ietf", "name": "IAB/IESG Nominating Committee 2012/2013"}}, -{"pk": 1851, "model": "group.group", "fields": {"charter": "charter-ietf-imapmove", "unused_states": [], "ad": 21684, "parent": 934, "list_email": "imapext@ietf.org", "acronym": "imapmove", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/imapext", "state": "active", "time": "2012-06-26 09:17:05", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/imapext/", "type": "wg", "name": "IMAP MOVE extension"}}, -{"pk": 1852, "model": "group.group", "fields": {"charter": "charter-ietf-straw", "unused_states": [], "ad": 103539, "parent": 1683, "list_email": "straw@ietf.org", "acronym": "straw", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/straw", "state": "active", "time": "2012-07-10 09:40:03", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/straw/", "type": "wg", "name": "Sip Traversal Required for Applications to Work"}}, +{"pk": 1851, "model": "group.group", "fields": {"charter": "charter-ietf-imapmove", "unused_states": [], "ad": null, "parent": 934, "list_email": "imapext@ietf.org", "acronym": "imapmove", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/imapext", "state": "active", "time": "2012-06-26 09:17:05", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/imapext/", "type": "wg", "name": "IMAP MOVE extension"}}, +{"pk": 1852, "model": "group.group", "fields": {"charter": "charter-ietf-straw", "unused_states": [], "ad": null, "parent": 1683, "list_email": "straw@ietf.org", "acronym": "straw", "comments": "", "list_subscribe": "https://www.ietf.org/mailman/listinfo/straw", "state": "active", "time": "2012-07-10 09:40:03", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/straw/", "type": "wg", "name": "Sip Traversal Required for Applications to Work"}}, {"pk": 1853, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 3, "list_email": "", "acronym": "irtfopen", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-06-06 09:42:20", "unused_tags": [], "list_archive": "", "type": "ag", "name": "IRTF Open Meeting"}}, -{"pk": 1854, "model": "group.group", "fields": {"charter": "charter-ietf-dsii", "unused_states": [], "ad": 18321, "parent": 934, "list_email": "", "acronym": "dsii", "comments": "", "list_subscribe": "", "state": "bof", "time": "2012-06-20 09:30:10", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Data Set Identifier Interoperability"}}, +{"pk": 1854, "model": "group.group", "fields": {"charter": "charter-ietf-dsii", "unused_states": [], "ad": null, "parent": 934, "list_email": "", "acronym": "dsii", "comments": "", "list_subscribe": "", "state": "bof", "time": "2012-06-20 09:30:10", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Data Set Identifier Interoperability"}}, {"pk": 1855, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "stephaniemccammon@gmail.com, smccammon@amsl.com", "acronym": "smcamo", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-06-27 08:44:05", "unused_tags": [], "list_archive": "", "type": "sdo", "name": "smcamo"}}, {"pk": 1857, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 3, "list_email": "", "acronym": "sdnrg", "comments": "", "list_subscribe": "", "state": "proposed", "time": "2012-06-28 09:39:45", "unused_tags": [], "list_archive": "", "type": "rg", "name": "Proposed Software Defined Networking Research Group"}}, {"pk": 1858, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ONF", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-07-03 10:22:12", "unused_tags": [], "list_archive": "", "type": "sdo", "name": "ONF"}}, @@ -1003,13 +1003,13 @@ {"pk": 1861, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 3, "list_email": "irsg@irtf.org", "acronym": "irsg", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-08-02 10:11:25", "unused_tags": [], "list_archive": "", "type": "irtf", "name": "Internet Research Steering Group"}}, {"pk": 1862, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ieee-80211", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-08-28 13:26:59", "unused_tags": [], "list_archive": "", "type": "sdo", "name": "IEEE 802.11"}}, {"pk": 1863, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "rse", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-09-13 08:45:42", "unused_tags": [], "list_archive": "", "type": "ietf", "name": "RFC Series Editor"}}, -{"pk": 1864, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 103961, "parent": 1683, "list_email": "video-codec@ietf.org", "acronym": "videocodec", "comments": "BOF at IETF 85", "list_subscribe": "https://www.ietf.org/mailman/listinfo/video-codec", "state": "bof", "time": "2012-09-26 10:43:01", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/video-codec/", "type": "wg", "name": "Internet Video Codec"}}, -{"pk": 1865, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 104198, "parent": 1249, "list_email": "irs-discuss@ietf.org", "acronym": "irs", "comments": "BOF at IETF 85", "list_subscribe": "http://www.ietf.org/mailman/listinfo/irs-discuss ", "state": "bof", "time": "2012-09-26 10:46:57", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/irs-discuss/", "type": "wg", "name": "Interface to the Routing System"}}, -{"pk": 1866, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "", "acronym": "fmc", "comments": "BOF at IETF 85", "list_subscribe": "", "state": "bof", "time": "2012-09-26 10:51:42", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Fixed Mobile Convergence"}}, -{"pk": 1867, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 2348, "parent": 1052, "list_email": "", "acronym": "mdnsext", "comments": "BOF at IETF 85", "list_subscribe": "", "state": "bof", "time": "2012-09-26 10:54:19", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Extensions to the Bonjour protocol suite"}}, -{"pk": 1868, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 19177, "parent": 1260, "list_email": "", "acronym": "certrans", "comments": "BOF at IETF 85", "list_subscribe": "", "state": "bof", "time": "2012-09-26 10:56:57", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Certificate Transparency"}}, -{"pk": 1869, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 19483, "parent": 1260, "list_email": "", "acronym": "sacm", "comments": "BOF at IETF 85", "list_subscribe": "", "state": "bof", "time": "2012-09-26 11:00:55", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Security Automation and Continuous Monitoring"}}, -{"pk": 1870, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": 101568, "parent": 1193, "list_email": "", "acronym": "wpkops", "comments": "BOF at IETF 85", "list_subscribe": "", "state": "bof", "time": "2012-09-26 11:02:56", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Web PKI operations"}}, +{"pk": 1864, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1683, "list_email": "video-codec@ietf.org", "acronym": "videocodec", "comments": "BOF at IETF 85", "list_subscribe": "https://www.ietf.org/mailman/listinfo/video-codec", "state": "bof", "time": "2012-09-26 10:43:01", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/video-codec/", "type": "wg", "name": "Internet Video Codec"}}, +{"pk": 1865, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1249, "list_email": "irs-discuss@ietf.org", "acronym": "irs", "comments": "BOF at IETF 85", "list_subscribe": "http://www.ietf.org/mailman/listinfo/irs-discuss ", "state": "bof", "time": "2012-09-26 10:46:57", "unused_tags": [], "list_archive": "http://www.ietf.org/mail-archive/web/irs-discuss/", "type": "wg", "name": "Interface to the Routing System"}}, +{"pk": 1866, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "fmc", "comments": "BOF at IETF 85", "list_subscribe": "", "state": "bof", "time": "2012-09-26 10:51:42", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Fixed Mobile Convergence"}}, +{"pk": 1867, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1052, "list_email": "", "acronym": "mdnsext", "comments": "BOF at IETF 85", "list_subscribe": "", "state": "bof", "time": "2012-09-26 10:54:19", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Extensions to the Bonjour protocol suite"}}, +{"pk": 1868, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "certrans", "comments": "BOF at IETF 85", "list_subscribe": "", "state": "bof", "time": "2012-09-26 10:56:57", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Certificate Transparency"}}, +{"pk": 1869, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1260, "list_email": "", "acronym": "sacm", "comments": "BOF at IETF 85", "list_subscribe": "", "state": "bof", "time": "2012-09-26 11:00:55", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Security Automation and Continuous Monitoring"}}, +{"pk": 1870, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": 1193, "list_email": "", "acronym": "wpkops", "comments": "BOF at IETF 85", "list_subscribe": "", "state": "bof", "time": "2012-09-26 11:02:56", "unused_tags": [], "list_archive": "", "type": "wg", "name": "Web PKI operations"}}, {"pk": 1871, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "ieee-80216", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-09-28 10:08:59", "unused_tags": [], "list_archive": "", "type": "sdo", "name": "IEEE 802.16"}}, {"pk": 1872, "model": "group.group", "fields": {"charter": null, "unused_states": [], "ad": null, "parent": null, "list_email": "", "acronym": "itu-t-jca-cloud", "comments": "", "list_subscribe": "", "state": "active", "time": "2012-09-28 13:35:37", "unused_tags": [], "list_archive": "", "type": "sdo", "name": "ITU-T JCA-Cloud"}} -] \ No newline at end of file +] diff --git a/ietf/group/models.py b/ietf/group/models.py index 1f70f2e1c..ae69dc5f9 100644 --- a/ietf/group/models.py +++ b/ietf/group/models.py @@ -58,26 +58,15 @@ class Group(GroupInfo): e = model.objects.filter(group=self).filter(**filter_args).order_by('-time', '-id')[:1] return e[0] if e else None - def is_chair(self, user): - chair = self.get_chair() - if chair: - return self.get_chair().person.user == user - else: - return False - - def is_member(self, user): - members = self.get_members() - users = [member.person.user for member in members] - return user in users + def has_role(self, user, role_names): + if isinstance(role_names, str) or isinstance(role_names, unicode): + role_names = [role_names] + return user.is_authenticated() and self.role_set.filter(name__in=role_names, person__user=user).exists() def get_chair(self): chair = self.role_set.filter(name__slug='chair')[:1] return chair and chair[0] or None - def get_members(self): - members = self.role_set.filter(name__slug__in=["chair", "member", "advisor", "liaison"]) - return members - # these are copied to Group because it is still proxied. @property def upcase_acronym(self): diff --git a/ietf/group/proxy.py b/ietf/group/proxy.py deleted file mode 100644 index c76759524..000000000 --- a/ietf/group/proxy.py +++ /dev/null @@ -1,259 +0,0 @@ -from ietf.utils.proxy import TranslatingManager, proxy_role_email - -from models import * - -class Acronym(Group): - class LazyIndividualSubmitter(object): - def __get__(self, obj, type=None): - return Group.objects.get(acronym="none").id - - INDIVIDUAL_SUBMITTER = LazyIndividualSubmitter() - - def from_object(self, base): - for f in base._meta.fields: - setattr(self, f.name, getattr(base, f.name)) - return self - - #acronym_id = models.AutoField(primary_key=True) - @property - def acronym_id(self): - return self.id - #acronym = models.CharField(max_length=12) # same name - #name = models.CharField(max_length=100) # same name - #name_key = models.CharField(max_length=50, editable=False) - @property - def name_key(self): - return self.name.upper() - - @property - def ietfwg(self): - return IETFWG().from_object(self) - - def __str__(self): - return self.acronym - - def __unicode__(self): - return self.acronym - - class Meta: - proxy = True - -class Area(Group): - objects = TranslatingManager(dict(area_acronym__acronym="acronym", - area_acronym__name="name", - status=lambda v: ("state", {1: "active", 2: "dormant", 3: "conclude"}[v] )), - always_filter=dict(type="area")) - - def from_object(self, base): - for f in base._meta.fields: - setattr(self, f.name, getattr(base, f.name)) - return self - - ACTIVE=1 - #area_acronym = models.OneToOneField(Acronym, primary_key=True) - @property - def area_acronym(self): - return Acronym().from_object(self) - - #start_date = models.DateField(auto_now_add=True) - #concluded_date = models.DateField(null=True, blank=True) - #status = models.ForeignKey(AreaStatus) - @property - def status_id(self): - return { "active": 1, "dormant": 2, "conclude": 3, "proposed": 4 }[self.state_id] - #comments = models.TextField(blank=True) - #last_modified_date = models.DateField(auto_now=True) - @property - def last_modified_date(self): - return self.time.date() - #extra_email_addresses = models.TextField(blank=True,null=True) - - #def additional_urls(self): - # return AreaWGURL.objects.filter(name=self.area_acronym.name) - def active_wgs(self): - return IETFWG.objects.filter(type="wg", state="active", parent=self).select_related('type', 'state', 'parent').order_by("acronym") - - @property - def areadirector_set(self): - return proxied_role_emails(Email.objects.filter(role__group=self, role__name="ad")) - - @staticmethod - def active_areas(): - return Area.objects.filter(type="area", state="active").select_related('type', 'state', 'parent').order_by('acronym') - - def __str__(self): - return self.acronym - def __unicode__(self): - return self.acronym - - class Meta: - proxy = True - -def proxied_role_emails(emails): - for e in emails: - proxy_role_email(e) - return emails - -class IETFWG(Group): - objects = TranslatingManager(dict(group_acronym="id", - group_acronym__acronym="acronym", - group_acronym__acronym__in="acronym__in", - group_acronym__acronym__contains="acronym__contains", - email_archive__startswith="list_archive__startswith", - group_type=lambda v: ("type__in", { 1: ("wg",), 2: ("wg", "rg") }[int(v)]), - status=lambda v: ("state__in", { 1: ("active", "bof") }[int(v)]), - areagroup__area__status=lambda v: ("parent__state", { 1: "active" }[v]), - start_date__isnull=lambda v: None if v else ("groupevent__changestategroupevent__state__slug", "active"), - ), - always_filter=dict(type__in=("wg", "rg", "individ", "area"))) - - def from_object(self, base): - for f in base._meta.fields: - setattr(self, f.name, getattr(base, f.name)) - return self - - ACTIVE=1 - #group_acronym = models.OneToOneField(Acronym, primary_key=True, editable=False) - @property - def group_acronym(self): - return Acronym().from_object(self) - - #group_type = models.ForeignKey(WGType) - #proposed_date = models.DateField(null=True, blank=True) - #start_date = models.DateField(null=True, blank=True) - @property - def start_date(self): - e = GroupEvent.objects.filter(group=self, type="changed_state", changestategroupevent__state="active").order_by('time')[:1] - return e[0].time.date() if e else None - - #dormant_date = models.DateField(null=True, blank=True) - #concluded_date = models.DateField(null=True, blank=True) - #status = models.ForeignKey(WGStatus) - @property - def status_id(self): - return { "active": 1, "dormant": 2, "conclude": 3, "bof-conc": 3, "proposed": 4, "bof": 4, "abandon": 4, "replaced": 4}[self.state_id] - #area_director = models.ForeignKey(AreaDirector, null=True) - #meeting_scheduled = models.CharField(blank=True, max_length=3) - @property - def meeting_scheduled(self): - from ietf.meeting.models import Meeting - latest_meeting = Meeting.objects.order_by('-date')[0] - return "YES" if self.session_set.filter(meeting=latest_meeting) else "NO" - #email_address = models.CharField(blank=True, max_length=60) - @property - def email_address(self): - return self.list_email - #email_subscribe = models.CharField(blank=True, max_length=120) - @property - def email_subscribe(self): - return self.list_subscribe - #email_keyword = models.CharField(blank=True, max_length=50) - #email_archive = models.CharField(blank=True, max_length=95) - @property - def email_archive(self): - return self.list_archive - #comments = models.TextField(blank=True) - #last_modified_date = models.DateField() - @property - def last_modified_date(self): - return self.time.date() - #meeting_scheduled_old = models.CharField(blank=True, max_length=3) - #area = FKAsOneToOne('areagroup', reverse=True) - @property - def area(self): - if self.parent: - areagroup = AreaGroup().from_object(self) - return areagroup - else: - return None - - def __str__(self): - return self.group_acronym.acronym - - def __unicode__(self): - return self.group_acronym.acronym - - def active_drafts(self): - from ietf.doc.proxy import InternetDraft - return InternetDraft.objects.filter(group=self, states__type="draft", states__slug="active") - # def choices(): - # return [(wg.group_acronym_id, wg.group_acronym.acronym) for wg in IETFWG.objects.all().filter(group_type__type='WG').select_related().order_by('acronym.acronym')] - # choices = staticmethod(choices) - def area_acronym(self): - return Area().from_object(self.parent) if self.parent else None - def area_directors(self): - if not self.parent: - return None - return proxied_role_emails(sorted(Email.objects.filter(role__group=self.parent, role__name="ad"), key=lambda e: e.person.name_parts()[3])) - def chairs(self): # return a set of WGChair objects for this work group - return proxied_role_emails(sorted(Email.objects.filter(role__group=self, role__name="chair"), key=lambda e: e.person.name_parts()[3])) - # def secretaries(self): # return a set of WGSecretary objects for this group - # return WGSecretary.objects.filter(group_acronym__exact=self.group_acronym) - # def milestones(self): # return a set of GoalMilestone objects for this group - # return GoalMilestone.objects.filter(group_acronym__exact=self.group_acronym) - # def rfcs(self): # return a set of Rfc objects for this group - # return Rfc.objects.filter(group_acronym__exact=self.group_acronym) - # def drafts(self): # return a set of Rfc objects for this group - # return InternetDraft.objects.filter(group__exact=self.group_acronym) - def charter_text(self): # return string containing WG description read from file - from ietf.group.utils import get_charter_text - return get_charter_text(self) - def additional_urls(self): - return self.groupurl_set.all().order_by("name") - def clean_email_archive(self): - return self.list_archive - @property - def wgchair_set(self): - # gross hack ... - class Dummy: pass - d = Dummy() - d.all = self.chairs - return d - @property - def wgdelegate_set(self): - from ietf.wgchairs.models import WGDelegate - return WGDelegate.objects.filter(group=self, name="delegate") - - class Meta: - proxy = True - -class IRTF(Group): - objects = TranslatingManager(dict(), - always_filter=dict(type="rg")) - - #irtf_id = models.AutoField(primary_key=True) - @property - def irtf_id(self): - return self.pk - #acronym = models.CharField(blank=True, max_length=25, db_column='irtf_acronym') # same name - #name = models.CharField(blank=True, max_length=255, db_column='irtf_name') # same name - #charter_text = models.TextField(blank=True,null=True) - #meeting_scheduled = models.BooleanField(blank=True) - def __str__(self): - return self.acronym - def __unicode__(self): - return self.acronym - #def chairs(self): # return a set of IRTFChair objects for this work group - # return IRTFChair.objects.filter(irtf=self) - class Meta: - proxy = True - -class AreaGroup(Group): - objects = TranslatingManager(dict(group=lambda v: ("pk", v.pk)), - always_filter=dict(type="wg")) - - def from_object(self, base): - for f in base._meta.fields: - setattr(self, f.name, getattr(base, f.name)) - return self - - @property - def area(self): - return Area().from_object(self.parent) - - @property - def group(self): - return self - - class Meta: - proxy = True diff --git a/ietf/group/stream_urls.py b/ietf/group/stream_urls.py index c256c41a7..39fbb7176 100644 --- a/ietf/group/stream_urls.py +++ b/ietf/group/stream_urls.py @@ -2,13 +2,10 @@ from django.conf.urls.defaults import patterns, include -import views +import views_stream urlpatterns = patterns('', - (r'^$', views.streams), - (r'^(?P[a-zA-Z0-9-]+)/$', views.stream_documents, None), -# (r'^(?P[a-zA-Z0-9-]+)/history/$', views.stream_history), -# (r'^(?P[a-zA-Z0-9-]+)/edit/$', views.stream_edit) - (r'^management/', include('ietf.ietfworkflows.urls')), - + (r'^$', views_stream.streams), + (r'^(?P[a-zA-Z0-9-]+)/$', views_stream.stream_documents, None), + (r'^(?P[a-zA-Z0-9-]+)/edit/$', views_stream.stream_edit), ) diff --git a/ietf/group/tests.py b/ietf/group/tests.py new file mode 100644 index 000000000..423d30897 --- /dev/null +++ b/ietf/group/tests.py @@ -0,0 +1,31 @@ +import os, shutil, datetime + +import django.test +from django.core.urlresolvers import reverse as urlreverse + +from pyquery import PyQuery + +from ietf.utils.mail import outbox +from ietf.utils.test_utils import login_testing_unauthorized +from ietf.utils.test_data import make_test_data + +from ietf.name.models import * +from ietf.group.models import * +from ietf.person.models import * + +class StreamTests(TestCase): + def test_stream_edit(self): + make_test_data() + + stream_acronym = "ietf" + + url = urlreverse("ietf.group.views_stream.stream_edit", kwargs=dict(acronym=stream_acronym)) + login_testing_unauthorized(self, "secretary", url) + + # get + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + + r = self.client.post(url, dict(delegates="ad2@ietf.org")) + self.assertEqual(r.status_code, 302) + self.assertTrue(Role.objects.filter(name="delegate", group__acronym=stream_acronym, email__address="ad2@ietf.org")) diff --git a/ietf/group/views.py b/ietf/group/views.py deleted file mode 100644 index 9d7eefbbd..000000000 --- a/ietf/group/views.py +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright The IETF Trust 2008, All Rights Reserved - -from django.shortcuts import render_to_response -from django.template import RequestContext, loader -from django.http import Http404, HttpResponse - -from ietf.group.models import Group -from ietf.doc.models import Document -from ietf.doc.views_search import SearchForm, retrieve_search_results -from ietf.name.models import StreamName - -import debug - -def streams(request): - streams = [ s.slug for s in StreamName.objects.all().exclude(slug__in=['ietf', 'legacy']) ] - streams = Group.objects.filter(acronym__in=streams) - return render_to_response('group/index.html', {'streams':streams}, context_instance=RequestContext(request)) - -def stream_documents(request, acronym): - streams = [ s.slug for s in StreamName.objects.all().exclude(slug__in=['ietf', 'legacy']) ] - if not acronym in streams: - raise Http404("No such stream: %s" % acronym) - stream = StreamName.objects.get(slug=acronym) - form = SearchForm({'by':'stream', 'stream':acronym, - 'rfcs':'on', 'activedrafts':'on'}) - docs, meta = retrieve_search_results(form) - return render_to_response('group/stream_documents.html', {'stream':stream, 'docs':docs, 'meta':meta }, context_instance=RequestContext(request)) - - \ No newline at end of file diff --git a/ietf/group/views_stream.py b/ietf/group/views_stream.py new file mode 100644 index 000000000..8795f2306 --- /dev/null +++ b/ietf/group/views_stream.py @@ -0,0 +1,75 @@ +# Copyright The IETF Trust 2008, All Rights Reserved + +from django.shortcuts import render_to_response, get_object_or_404, redirect +from django.template import RequestContext, loader +from django.http import Http404, HttpResponse, HttpResponseForbidden +from django import forms + +from ietf.group.models import * +from ietf.group.utils import * +from ietf.doc.models import Document +from ietf.doc.views_search import SearchForm, retrieve_search_results +from ietf.name.models import StreamName +from ietf.ietfauth.utils import has_role +from ietf.person.forms import EmailsField + +import debug + +def streams(request): + streams = [ s.slug for s in StreamName.objects.all().exclude(slug__in=['ietf', 'legacy']) ] + streams = Group.objects.filter(acronym__in=streams) + return render_to_response('group/index.html', {'streams':streams}, context_instance=RequestContext(request)) + +def stream_documents(request, acronym): + streams = [ s.slug for s in StreamName.objects.all().exclude(slug__in=['ietf', 'legacy']) ] + if not acronym in streams: + raise Http404("No such stream: %s" % acronym) + stream = StreamName.objects.get(slug=acronym) + form = SearchForm({'by':'stream', 'stream':acronym, + 'rfcs':'on', 'activedrafts':'on'}) + docs, meta = retrieve_search_results(form) + return render_to_response('group/stream_documents.html', {'stream':stream, 'docs':docs, 'meta':meta }, context_instance=RequestContext(request)) + +class StreamEditForm(forms.Form): + delegates = EmailsField(label="Delegates", required=False, help_text=u"Type in name to search for person") + +def stream_edit(request, acronym): + group = get_object_or_404(Group, acronym=acronym) + + if not (has_role(request.user, "Secretariat") or group.has_role(request.user, "chair")): + return HttpResponseForbidden("You don't have permission to access this page.") + + chairs = Email.objects.filter(role__group=group, role__name="chair").select_related("person") + + if request.method == 'POST': + form = StreamEditForm(request.POST) + + if form.is_valid(): + save_group_in_history(group) + + # update roles + attr, slug, title = ('delegates', 'delegate', "Delegates") + + new = form.cleaned_data[attr] + old = Email.objects.filter(role__group=group, role__name=slug).select_related("person") + if set(new) != set(old): + desc = "%s changed to %s from %s" % ( + title, ", ".join(x.get_name() for x in new), ", ".join(x.get_name() for x in old)) + + GroupEvent.objects.create(group=group, by=request.user.get_profile(), type="info_changed", desc=desc) + + group.role_set.filter(name=slug).delete() + for e in new: + Role.objects.get_or_create(name_id=slug, email=e, group=group, person=e.person) + + return redirect("ietf.group.views.streams") + else: + form = StreamEditForm(initial=dict(delegates=Email.objects.filter(role__group=group, role__name="delegate"))) + + return render_to_response('group/stream_edit.html', + {'group': group, + 'chairs': chairs, + 'form': form, + }, + context_instance=RequestContext(request)) + diff --git a/ietf/idindex/tests.py b/ietf/idindex/tests.py index 86ab08169..9e42ef588 100644 --- a/ietf/idindex/tests.py +++ b/ietf/idindex/tests.py @@ -9,10 +9,7 @@ from ietf.doc.models import * from ietf.idindex.index import * -class IndexTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] - +class IndexTests(TestCase): def setUp(self): self.id_dir = os.path.abspath("tmp-id-dir") os.mkdir(self.id_dir) diff --git a/ietf/idrfc/.gitignore b/ietf/idrfc/.gitignore deleted file mode 100644 index a74b07aee..000000000 --- a/ietf/idrfc/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/*.pyc diff --git a/ietf/idrfc/__init__.py b/ietf/idrfc/__init__.py deleted file mode 100644 index 792d60054..000000000 --- a/ietf/idrfc/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# diff --git a/ietf/idrfc/idrfc_wrapper.py b/ietf/idrfc/idrfc_wrapper.py deleted file mode 100644 index feb57d199..000000000 --- a/ietf/idrfc/idrfc_wrapper.py +++ /dev/null @@ -1,967 +0,0 @@ -# Copyright (C) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). -# All rights reserved. Contact: Pasi Eronen -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# -# * Neither the name of the Nokia Corporation and/or its -# subsidiary(-ies) nor the names of its contributors may be used -# to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -from ietf.idtracker.models import InternetDraft, IDInternal, BallotInfo, IESGDiscuss, IESGLogin, DocumentComment, Acronym, IDState -from ietf.idrfc.models import RfcEditorQueue -from ietf.ipr.models import IprRfc, IprDraft, IprDetail -from ietf.doc.models import BallotDocEvent - -import re -from datetime import date -from django.utils import simplejson as json -from django.db.models import Q -from django.db import models -from django.core.urlresolvers import reverse -from django.conf import settings -import types -import debug - -BALLOT_ACTIVE_STATES = ['In Last Call', - 'Waiting for Writeup', - 'Waiting for AD Go-Ahead', - 'IESG Evaluation', - 'IESG Evaluation - Defer'] - -def jsonify_helper(obj, keys): - result = {} - for k in keys: - if hasattr(obj, k): - v = getattr(obj, k) - if callable(v): - v = v() - if v == None: - pass - elif isinstance(v, (types.StringType, types.IntType, types.BooleanType, types.LongType, types.ListType, types.UnicodeType)): - result[k] = v - elif isinstance(v, date): - result[k] = str(v) - else: - result[k] = 'Unknown type '+str(type(v)) - return result - -# Wrappers to make writing templates less painful - -# --------------------------------------------------------------------------- - -class IdWrapper: - _draft = None - _idinternal = None - - is_id_wrapper = True - is_rfc_wrapper = False - - draft_name = None - # Active/Expired/RFC/Withdrawn by Submitter/Replaced/Withdrawn by IETF - draft_status = None - # Revision is sometimes incorrect (+1 too large) if status != Active - latest_revision = None - # Set if and only if draft_status is "RFC" - rfc_number = None - title = None - tracker_id = None - publication_date = None - ietf_process = None - - def __init__(self, draft): - self.id = self - if isinstance(draft, IDInternal) and not settings.USE_DB_REDESIGN_PROXY_CLASSES: - self._idinternal = draft - self._draft = self._idinternal.draft - else: - self._draft = draft - if draft.idinternal: - self._idinternal = draft.idinternal - if self._idinternal: - self.ietf_process = IetfProcessData(self._idinternal) - - self.draft_name = self._draft.filename - self.draft_status = str(self._draft.status) - if self.draft_status == "RFC": - if self._draft.rfc_number: - self.rfc_number = self._draft.rfc_number - else: - # Handle incorrect database entries - self.draft_status = "Expired" - self.latest_revision = self._draft.revision_display() - self.title = self._draft.title - self.tracker_id = self._draft.id_document_tag - self.resurrect_requested_by = self._idinternal.resurrect_requested_by if self._idinternal else None - self.publication_date = self._draft.revision_date - if not self.publication_date: - # should never happen -- but unfortunately it does. Return an - # obviously bogus date - self.publication_date = date(1990,1,1) - - def rfc_editor_state(self): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - s = self._draft.get_state("draft-rfceditor") - if s: - # extract possible extra annotations - tags = self._draft.tags.filter(slug__in=("iana", "ref")) - return "*".join([s.name] + [t.slug.upper() for t in tags]) - else: - return None - - try: - qs = self._draft.rfc_editor_queue_state - return qs.state - except RfcEditorQueue.DoesNotExist: - pass - return None - - def replaced_by(self): - try: - if self._draft.replaced_by: - return [self._draft.replaced_by.filename] - except InternetDraft.DoesNotExist: - pass - return None - def replaces(self): - r = [str(r.filename) for r in self._draft.replaces_set.all()] - if len(r) > 0: - return r - else: - return None - def in_ietf_process(self): - return self.ietf_process != None - - def submission(self): - - if self._draft.stream_id != u'ietf': - return self._draft.stream - - if self._draft.group_id == Acronym.INDIVIDUAL_SUBMITTER: - return "Individual" - - if self._draft.group and self._draft.group.type_id == "area": - return u"Individual in %s area" % self._draft.group.acronym - - a = self.group_acronym() - if a: - if self._draft.stream_id == "ietf" and self._draft.get_state_slug("draft-stream-ietf") == "c-adopt": - return "candidate for %s WG" % (a, a) - - return "%s WG" % (a, a) - - return "" - submission.allow_tags = True - - def search_archive(self): - - if self._idinternal and self._idinternal.stream in ("IRTF","ISE"): - return "www.ietf.org/mail-archive/web/" - - if self._draft.group_id == Acronym.INDIVIDUAL_SUBMITTER or (settings.USE_DB_REDESIGN_PROXY_CLASSES and self._draft.group.type_id == "area"): - return "www.ietf.org/mail-archive/web/" - - a = self._draft.group_ml_archive() - if a: - return a - - return "" - - def file_types(self): - return self._draft.file_type.split(",") - - def group_acronym(self): - if self._draft.group_id != 0 and self._draft.group != None and str(self._draft.group) != "none": - if settings.USE_DB_REDESIGN_PROXY_CLASSES and self._draft.group.type_id == "area": - return None - return str(self._draft.group) - else: - return None - - # TODO: Returning integers here isn't nice - # 0=Unknown, 1=IETF, 2=IAB, 3=IRTF, 4=Independent - def stream_id(self): - if self.draft_name.startswith("draft-iab-"): - return 2 - elif self.draft_name.startswith("draft-irtf-"): - return 3 - elif self._idinternal: - if self._idinternal.stream == "ISE": - return 4 - else: - return 1 - elif self.group_acronym(): - return 1 - else: - return 0 - - def draft_name_and_revision(self): - return self.draft_name+"-"+self.latest_revision - - def friendly_state(self): - if self.draft_status == "RFC": - return "RFC %d" % (reverse('doc_view', args=['rfc%d' % self.rfc_number]), self.rfc_number) - elif self.draft_status == "Active": - if self.in_ietf_process(): - if self.ietf_process.main_state == "Dead": - # Many drafts in "Dead" state are not dead; they're - # just not currently under IESG processing. Show - # them as "I-D Exists (IESG: Dead)" instead... - return "I-D Exists (IESG: "+self.ietf_process.state+")" - elif self.ietf_process.main_state == "In Last Call": - return self.ietf_process.state + " (ends "+str(self._idinternal.document().lc_expiration_date)+")" - else: - return self.ietf_process.state - else: - return "I-D Exists" - else: - if self.in_ietf_process() and self.ietf_process.main_state == "Dead": - return self.draft_status+" (IESG: "+self.ietf_process.state+")" - # Expired/Withdrawn by Submitter/IETF - return self.draft_status - - def abstract(self): - return self._draft.clean_abstract() - - # TODO: ugly hack - def authors(self): - return self._draft.authors - - def expected_expiration_date(self): - if self.draft_status == "Active" and self._draft.can_expire(): - return self._draft.expiration() - else: - return None - - def ad_name(self): - if self.in_ietf_process(): - return self.ietf_process.ad_name() - else: - return None - - def get_absolute_url(self): - return "/doc/"+self.draft_name+"/" - def displayname_with_link(self): - return '%s' % (self.get_absolute_url(), self.draft_name_and_revision()) - - def underlying_document(self): - """ Expose the Document object underneath the proxy """ - from ietf.doc.models import Document - return Document.objects.get(docalias__name=self.draft_name) - - def to_json(self): - result = jsonify_helper(self, ['draft_name', 'draft_status', 'latest_revision', 'rfc_number', 'title', 'tracker_id', 'publication_date','rfc_editor_state', 'replaced_by', 'replaces', 'in_ietf_process', 'file_types', 'group_acronym', 'stream_id','friendly_state', 'abstract', 'ad_name']) - if self.in_ietf_process(): - result['ietf_process'] = self.ietf_process.dict() - return json.dumps(result, indent=2) - -# --------------------------------------------------------------------------- - -class RfcWrapper: - _rfc = None - _rfcindex = None - _idinternal = None - - is_id_wrapper = False - is_rfc_wrapper = True - - rfc_number = None - title = None - publication_date = None - maturity_level = None - ietf_process = None - draft_name = None - - def __init__(self, rfcindex, rfc=None, idinternal=None): - self._rfcindex = rfcindex - self._rfc = rfc - self._idinternal = idinternal - self.rfc = self - - if not self._idinternal: - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - pub = rfcindex.rfc_published_date - started = rfcindex.started_iesg_process if hasattr(rfcindex, 'started_iesg_process') else rfcindex.latest_event(type="started_iesg_process") - if pub and started and pub < started.time.date(): - self._idinternal = rfcindex - else: - try: - self._idinternal = IDInternal.objects.get(rfc_flag=1, draft=self._rfcindex.rfc_number) - except IDInternal.DoesNotExist: - pass - - if self._idinternal: - self.ietf_process = IetfProcessData(self._idinternal) - - self.rfc_number = self._rfcindex.rfc_number - self.title = self._rfcindex.title - self.publication_date = self._rfcindex.rfc_published_date - self.maturity_level = self._rfcindex.current_status - if not self.maturity_level: - self.maturity_level = "Unknown" - - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - if not rfcindex.name.startswith('rfc'): - self.draft_name = rfcindex.name - return # we've already done the lookup while importing so skip the rest - - ids = InternetDraft.objects.filter(rfc_number=self.rfc_number) - if len(ids) >= 1: - self.draft_name = ids[0].filename - elif self._rfcindex and self._rfcindex.draft: - # rfcindex occasionally includes drafts that were not - # really submitted to IETF (e.g. April 1st) - ids = InternetDraft.objects.filter(filename=self._rfcindex.draft) - if len(ids) > 0: - self.draft_name = self._rfcindex.draft - - def _rfc_doc_list(self, name): - if (not self._rfcindex) or (not getattr(self._rfcindex, name)): - return None - else: - s = getattr(self._rfcindex, name) - s = s.replace(",", ", ") - s = re.sub("([A-Z])([0-9])", "\\1 \\2", s) - return s - def obsoleted_by(self): - return self._rfc_doc_list("obsoleted_by") - def obsoletes(self): - return self._rfc_doc_list("obsoletes") - def updated_by(self): - return self._rfc_doc_list("updated_by") - def updates(self): - return self._rfc_doc_list("updates") - def also(self): - return self._rfc_doc_list("also") - def has_errata(self): - return self._rfcindex and (self._rfcindex.has_errata > 0) - def stream_name(self): - if not self._rfcindex: - return None - else: - x = self._rfcindex.stream - if x == "INDEPENDENT": - return "Independent Submission Stream" - elif x == "LEGACY": - return "Legacy Stream" - else: - return x+" Stream" - - def in_ietf_process(self): - return self.ietf_process != None - - def file_types(self): - types = self._rfcindex.file_formats - types = types.replace("ascii","txt") - return ["."+x for x in types.split(",")] - - def friendly_state(self): - if self.in_ietf_process(): - s = self.ietf_process.main_state - if not s in ["RFC Published", "AD is watching", "Dead"]: - return "RFC %d (%s)
%s (to %s)" % (self.rfc_number, self.maturity_level, self.ietf_process.state, self.ietf_process.intended_maturity_level()) - return "RFC %d (%s)" % (self.rfc_number, self.maturity_level) - - def ad_name(self): - if self.in_ietf_process(): - return self.ietf_process.ad_name() - else: - # TODO: get AD name of the draft - return None - def filename(self): - return self._rfcindex.filename - - @models.permalink - def get_absolute_url(self): - return ('ietf.doc.views_doc.document_main', ['rfc%s' % (str(self.rfc_number))]) - def displayname_with_link(self): - return 'RFC %d' % (self.get_absolute_url(), self.rfc_number) - - def to_json(self): - result = jsonify_helper(self, ['rfc_number', 'title', 'publication_date', 'maturity_level', 'obsoleted_by','obsoletes','updated_by','updates','also','has_errata','stream_name','file_types','in_ietf_process', 'friendly_state']) - if self.in_ietf_process(): - result['ietf_process'] = self.ietf_process.dict() - return json.dumps(result, indent=2) - - def underlying_document(self): - """ Expose the Document object underneath the proxy """ - # Things like RFC500 are special - there may not _be_ a docalias for them - from ietf.doc.models import Document - q = Document.objects.filter(docalias__name='rfc%04d'%self.rfc_number) - if q: - return q[0] - else: - return None - -# --------------------------------------------------------------------------- - -class IetfProcessData: - _idinternal = None - main_state = None - sub_state = None - state = None - _ballot = None - def __init__(self, idinternal): - self._idinternal = idinternal - i = self._idinternal - self.main_state = str(i.cur_state) - if i.cur_sub_state_id > 0: - self.sub_state = str(i.cur_sub_state) - self.state = self.main_state + "::" + self.sub_state - else: - self.sub_state = None - self.state = self.main_state - - def has_iesg_ballot(self): - try: - if self._idinternal.ballot.ballot_issued: - return True - except BallotInfo.DoesNotExist: - pass - return False - - def has_active_iesg_ballot(self): - if not self.has_iesg_ballot(): - return False - if not self.main_state in BALLOT_ACTIVE_STATES: - return False - if (not self._idinternal.rfc_flag) and self._idinternal.draft.status_id != 1: - # Active - return False - return True - - # don't call this unless has_[active_]iesg_ballot returns True - def iesg_ballot(self): - if not self._ballot: - self._ballot = BallotWrapper(self._idinternal) - return self._ballot - - # don't call this unless has_[active_]iesg_ballot returns True - def iesg_ballot_needed( self ): - standardsTrack = 'Standard' in self.intended_maturity_level() or \ - self.intended_maturity_level() in ("BCP", "Best Current Practice") - return self.iesg_ballot().ballot.needed( standardsTrack ) - - def ad_name(self): - return str(self._idinternal.job_owner) - - def iesg_note(self): - if self._idinternal.note: - n = self._idinternal.note - # Hide unnecessary note of form "RFC 1234" - if re.match("^RFC\s*\d+$", n): - return None - return n - else: - return None - - def state_date(self): - try: - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - return self._idinternal.docevent_set.filter( - Q(desc__istartswith="Draft Added by ")| - Q(desc__istartswith="Draft Added in state ")| - Q(desc__istartswith="Draft added in state ")| - Q(desc__istartswith="State changed to ")| - Q(desc__istartswith="State Changes to ")| - Q(desc__istartswith="Sub state has been changed to ")| - Q(desc__istartswith="State has been changed to ")| - Q(desc__istartswith="IESG has approved and state has been changed to")| - Q(desc__istartswith="IESG process started in state")).order_by('-time')[0].time.date() - return self._idinternal.comments().filter( - Q(comment_text__istartswith="Draft Added by ")| - Q(comment_text__istartswith="Draft Added in state ")| - Q(comment_text__istartswith="Draft added in state ")| - Q(comment_text__istartswith="State changed to ")| - Q(comment_text__istartswith="State Changes to ")| - Q(comment_text__istartswith="Sub state has been changed to ")| - Q(comment_text__istartswith="State has been changed to ")| - Q(comment_text__istartswith="IESG has approved and state has been changed to")).order_by('-id')[0].date - except IndexError: - # should never happen -- return an obviously bogus date - return date(1990,1,1) - - def dict(self): - result = {'main_state':self.main_state, - 'sub_state':self.sub_state, - 'state':self.state, - 'state_date':str(self.state_date()), - 'has_iesg_ballot':self.has_iesg_ballot(), - 'has_active_iesg_ballot':self.has_active_iesg_ballot(), - 'ad_name':self.ad_name(), - 'intended_maturity_level':self.intended_maturity_level(), - 'telechat_date':self.telechat_date()} - if result['telechat_date']: - result['telechat_date'] = str(result['telechat_date']) - result['telechat_returning_item'] = self.telechat_returning_item() - if self.iesg_note(): - result['iesg_note'] = self.iesg_note() - if self.has_iesg_ballot(): - result['iesg_ballot'] = self.iesg_ballot().dict() - return result - - def intended_maturity_level(self): - if self._idinternal.rfc_flag: - s = str(self._idinternal.document().intended_status) - # rfc_intend_status table uses different names, argh! - if s == "Proposed": - s = "Proposed Standard" - elif s == "Draft": - s = "Draft Standard" - elif s == "None": - s = None - else: - s = str(self._idinternal.draft.intended_status) - if s == "None": - s = None - elif s == "Request": - s = None - return s - - def telechat_date(self): - # return date only if it's on upcoming agenda - if self._idinternal.agenda: - return self._idinternal.telechat_date - else: - return None - - def telechat_returning_item(self): - # should be called only if telechat_date() returns non-None - return bool(self._idinternal.returning_item) - - def state_change_notice_to(self): - return self._idinternal.state_change_notice_to - - # comment_log? - -# --------------------------------------------------------------------------- - -class IdRfcWrapper: - rfc = None - id = None - iprCount = None - iprUrl = None - - def __init__(self, id, rfc): - self.id = id - self.rfc = rfc - if id: - iprs = IprDraft.objects.filter(document=self.id.tracker_id, ipr__status__in=[1,3]) - self.iprUrl = "/ipr/search?option=document_search&id_document_tag=" + str(self.id.tracker_id) - elif rfc: - iprs = IprRfc.objects.filter(document=self.rfc.rfc_number, ipr__status__in=[1,3]) - self.iprUrl = "/ipr/search?option=rfc_search&rfc_search=" + str(self.rfc.rfc_number) - else: - raise ValueError("Construction with null id and rfc") - # iprs is a list of docs which contain IPR - self.iprCount = len(iprs) - - def title(self): - if self.rfc: - return self.rfc.title - else: - return self.id.title - - def friendly_state(self): - if self.rfc: - return self.rfc.friendly_state() - else: - return self.id.friendly_state() - - def get_absolute_url(self): - if self.rfc: - return self.rfc.get_absolute_url() - else: - return self.id.get_absolute_url() - - def comment_count(self): - if self.rfc: - return DocumentComment.objects.filter(document=self.rfc.rfc_number,rfc_flag=1).count() - else: - return DocumentComment.objects.filter(document=self.id.tracker_id).exclude(rfc_flag=1).count() - - def ad_name(self): - if self.rfc: - s = self.rfc.ad_name() - if s: - return s - if self.id: - return self.id.ad_name() - return None - - def publication_date(self): - if self.rfc: - return self.rfc.publication_date - else: - return self.id.publication_date - - def telechat_date(self): - if self.rfc and self.rfc.in_ietf_process(): - return self.rfc.ietf_process.telechat_date() - elif self.id and self.id.in_ietf_process(): - return self.id.ietf_process.telechat_date() - else: - return None - - def view_sort_group(self): - if self.rfc: - return 'RFC' - elif self.id.draft_status == "Active": - return 'Active Internet-Draft' - else: - return 'Old Internet-Draft' - - def view_sort_group_byad(self): - if self.rfc: - return 'RFC' - elif self.id.draft_status == "Active": - if self.id.in_ietf_process(): - if self.id.ietf_process._idinternal.cur_state_id == IDState.DEAD: - return 'IESG Dead Internet-Draft' - else: - return "%s Internet-Draft" % self.id.ietf_process._idinternal.cur_state - else: - return 'Active Internet-Draft' - else: - return 'Old Internet-Draft' - - def view_sort_key(self, sort_by=None): - if sort_by is None: - if self.rfc: - return "2%04d" % self.rfc.rfc_number - elif self.id.draft_status == "Active": - return "1"+self.id.draft_name - else: - return "3"+self.id.draft_name - else: - if self.rfc: - sort_key = "2" - elif self.id.draft_status == "Active": - sort_key = "1" - else: - sort_key = "3" - - # Depending on what we're sorting on, we may - # need to do some conversion. - if sort_by == "title": - sort_key += self.title() - elif sort_by == "date": - sort_key = sort_key + str(self.publication_date()) - elif sort_by == "status": - if self.rfc: - sort_key += "%04d" % self.rfc.rfc_number - else: - sort_key += self.id.draft_status - elif sort_by == "ipr": - sort_key += self.iprUrl - elif sort_by == "ad": - return self.view_sort_key_byad() - else: - # sort default or unknown sort value, revert to default - if self.rfc: - sort_key += "%04d" % self.rfc.rfc_number - else: - sort_key += self.id.draft_name - - return sort_key - - def view_sort_key_byad(self): - if self.rfc: - return "2%04d" % self.rfc.rfc_number - elif self.id.draft_status == "Active": - if self.id.in_ietf_process(): - return "11%02d" % (self.id.ietf_process._idinternal.cur_state_id) - else: - return "10" - else: - return "3" - -# --------------------------------------------------------------------------- - -class BallotWrapper: - _idinternal = None - ballot = None - ballot_active = False - _positions = None - position_values = ["Discuss", "Yes", "No Objection", "Abstain", "Recuse", "No Record"] - - def __init__(self, idinternal): - self._idinternal = idinternal - self.ballot = idinternal.ballot - if not idinternal.rfc_flag: - self.ballot_active = self.ballot.ballot_issued and (str(idinternal.cur_state) in BALLOT_ACTIVE_STATES) and str(idinternal.draft.status)=="Active"; - else: - self.ballot_active = self.ballot.ballot_issued and (str(idinternal.cur_state) in BALLOT_ACTIVE_STATES) - self._ballot_set = None - - def approval_text(self): - return self.ballot.approval_text - def ballot_writeup(self): - return self.ballot.ballot_writeup - def is_active(self): - return self.ballot_active - def ballot_id(self): - return self._idinternal.ballot_id - def was_deferred(self): - return self.ballot.defer - def deferred_by(self): - return self.ballot.defer_by - def deferred_date(self): - return self.ballot.defer_date - def is_ballot_set(self): - if not self._ballot_set: - self._ballot_set = self._idinternal.ballot_set() - return len(list(self._ballot_set)) > 1 - def ballot_set_other(self): - if not self.is_ballot_set(): - return [] - else: - return self._ballot_set.exclude(draft=self._idinternal) - - def _init(self): - if not settings.USE_DB_REDESIGN_PROXY_CLASSES: - self.old_init() - return - - from ietf.person.models import Person - from ietf.doc.models import BallotPositionDocEvent, NewRevisionDocEvent, BallotDocEvent - - active_ads = Person.objects.filter(role__name="ad", role__group__state="active").distinct() - - positions = [] - seen = {} - - new_revisions = list(NewRevisionDocEvent.objects.filter(doc=self.ballot, type="new_revision").order_by('-time', '-id')) - - ballot = self.ballot.latest_event(BallotDocEvent, type="created_ballot") - - for pos in BallotPositionDocEvent.objects.filter(doc=self.ballot, type="changed_ballot_position", ballot=ballot).select_related('ad').order_by("-time", '-id'): - if pos.ad not in seen: - p = dict(ad_name=pos.ad.plain_name(), - ad_username=pos.ad.pk, # ought to rename this in doc_ballot_list - position=pos.pos.name, - is_old_ad=pos.ad not in active_ads, - old_positions=[]) - - rev = pos.doc.rev - for n in new_revisions: - if n.time <= pos.time: - rev = n.rev - break - - if pos.pos.slug == "discuss": - p["has_text"] = True - p["discuss_text"] = pos.discuss - p["discuss_date"] = pos.discuss_time.date() - p["discuss_revision"] = rev - - if pos.comment: - p["has_text"] = True - p["comment_text"] = pos.comment - p["comment_date"] = pos.comment_time.date() - p["comment_revision"] = rev - - positions.append(p) - seen[pos.ad] = p - else: - latest = seen[pos.ad] - if latest["old_positions"]: - prev = latest["old_positions"][-1] - else: - prev = latest["position"] - - if prev != pos.pos.name: - seen[pos.ad]["old_positions"].append(pos.pos.name) - - # add any missing ADs as No Record - if self.ballot_active: - for ad in active_ads: - if ad not in seen: - d = dict(ad_name=ad.plain_name(), - ad_username=ad.pk, - position="No Record", - ) - positions.append(d) - - self._positions = positions - - def old_init(self): - try: - ads = set() - except NameError: - # for Python 2.3 - from sets import Set as set - ads = set() - - positions = [] - all_comments = self.ballot.comments.all().select_related('ad') - for p in self.ballot.positions.all().select_related('ad'): - po = create_position_object(self.ballot, p, all_comments) - #if not self.ballot_active: - # if 'is_old_ad' in po: - # del po['is_old_ad'] - ads.add(str(p.ad)) - positions.append(po) - for c in all_comments: - if (str(c.ad) not in ads) and c.ad.is_current_ad(): - positions.append({'has_text':True, - 'comment_text':c.text, - 'comment_date':c.date, - 'comment_revision':str(c.revision), - 'ad_name':str(c.ad), - 'ad_username': c.ad.login_name, - 'position':'No Record', - 'is_old_ad':False}) - ads.add(str(c.ad)) - if self.ballot_active: - for ad in IESGLogin.active_iesg(): - if str(ad) not in ads: - positions.append(dict(ad_name=str(ad), - ad_username=ad.login_name, - position="No Record")) - self._positions = positions - - def position_for_ad(self, ad_name): - pl = self.position_list() - for p in pl: - if p["ad_name"] == ad_name: - return p["position"] - return None - - def position_list(self): - if not self._positions: - self._init() - return self._positions - - def get(self, v): - return [p for p in self.position_list() if p['position']==v] - - def get_discuss(self): - return self.get("Discuss") - def get_yes(self): - return self.get("Yes") - def get_no_objection(self): - return self.get("No Objection") - def get_abstain(self): - return self.get("Abstain") - def get_recuse(self): - return self.get("Recuse") - def get_no_record(self): - return self.get("No Record") - - def get_texts(self): - return [p for p in self.position_list() if ('has_text' in p) and p['has_text']] - - def dict(self): - summary = {} - for key in self.position_values: - tag = key.lower().replace(" ", "_") - summary[tag] = [ pos["ad_name"] for pos in self.get(key) ] - positions = self.position_list() - for i in range(len(positions)): - for key in ["comment_date", "discuss_date", ]: - if key in positions[i]: - positions[i][key] = positions[i][key].strftime("%Y-%m-%d") - return { - "active": self.is_active(), - "approval_text": self.approval_text(), - "ballot_writeup": self.ballot_writeup(), - "ballot_id": self.ballot_id(), - "deferred_by": unicode(self.deferred_by()), - "deferred_date": self.deferred_date() and self.deferred_date().strftime("%Y-%m-%d") , - "positions": positions, - "summary": summary, - "was_deferred": self.was_deferred(), - } - -def position_to_string(position): - positions = {"yes":"Yes", - "noobj":"No Objection", - "discuss":"Discuss", - "abstain":"Abstain", - "recuse":"Recuse"} - if not position: - return "No Record" - p = None - for k,v in positions.iteritems(): - if getattr(position, k) > 0: - p = v - if not p: - p = "No Record" - return p - -def create_position_object(ballot, position, all_comments): - positions = {"yes":"Yes", - "noobj":"No Objection", - "discuss":"Discuss", - "abstain":"Abstain", - "recuse":"Recuse"} - p = None - for k,v in positions.iteritems(): - if position.__dict__[k] > 0: - p = v - if not p: - p = "No Record" - r = dict(ad_name=str(position.ad), - ad_username=position.ad.login_name, - position=p) - if not position.ad.is_current_ad(): - r['is_old_ad'] = True - else: - r['is_old_ad'] = False - - was = [v for k,v in positions.iteritems() if position.__dict__[k] < 0] - if len(was) > 0: - r['old_positions'] = was - - comment = None - for c in all_comments: - if c.ad == position.ad: - comment = c - break - if comment and comment.text: - r['has_text'] = True - r['comment_text'] = comment.text - r['comment_date'] = comment.date - r['comment_revision'] = str(comment.revision) - - if p == "Discuss": - try: - discuss = ballot.discusses.get(ad=position.ad) - if discuss.text: - r['discuss_text'] = discuss.text - else: - r['discuss_text'] = '(empty)' - r['discuss_revision'] = str(discuss.revision) - r['discuss_date'] = discuss.date - except IESGDiscuss.DoesNotExist: - # this should never happen, but unfortunately it does - # fill in something to keep other parts of the code happy - r['discuss_text'] = "(error: discuss text not found)" - r['discuss_revision'] = "00" - r['discuss_date'] = date(2000, 1,1) - r['has_text'] = True - return r - diff --git a/ietf/idrfc/mirror_draft_versions.py b/ietf/idrfc/mirror_draft_versions.py deleted file mode 100644 index faffe5c35..000000000 --- a/ietf/idrfc/mirror_draft_versions.py +++ /dev/null @@ -1,88 +0,0 @@ -# Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -# All rights reserved. Contact: Pasi Eronen -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# -# * Neither the name of the Nokia Corporation and/or its -# subsidiary(-ies) nor the names of its contributors may be used -# to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -from ietf import settings -from django.core import management -management.setup_environ(settings) -from django import db - -import urllib2 -from datetime import datetime -import socket -import sys - -URL = "http://merlot.tools.ietf.org/~pasi/draft_versions.txt" -TABLE = "draft_versions_mirror" - -log_data = "" -def log(line): - global log_data - if len(sys.argv) > 1: - print line - else: - log_data += line + "\n" - -try: - log("output from mirror_draft_versions.py:\n") - log("time: "+str(datetime.now())) - log("host: "+socket.gethostname()) - log("url: "+URL) - - log("downloading...") - socket.setdefaulttimeout(30) - response = urllib2.urlopen(URL) - #log("got \n"+str(response.info())) - log("parsing...") - data = [] - for line in response.readlines(): - rec = line[:-1].split("\t") - data.append(rec) - - log("got " + str(len(data)) + " entries") - if len(data) < 10000: - raise Exception('not enough data') - - log("connecting to database...") - cursor = db.connection.cursor() - log("removing old data...") - cursor.execute("DELETE FROM "+TABLE) - log("inserting new data...") - cursor.executemany("INSERT INTO "+TABLE+" (filename, revision, revision_date) VALUES (%s, %s, %s)", data) - cursor.close() - db.connection._commit() - db.connection.close() - - log("all done!") - log_data = "" -finally: - if len(log_data) > 0: - print log_data diff --git a/ietf/idrfc/models.py b/ietf/idrfc/models.py deleted file mode 100644 index 7687eb2b0..000000000 --- a/ietf/idrfc/models.py +++ /dev/null @@ -1,104 +0,0 @@ -# Copyright (C) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). -# All rights reserved. Contact: Pasi Eronen -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# -# * Neither the name of the Nokia Corporation and/or its -# subsidiary(-ies) nor the names of its contributors may be used -# to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -from django.db import models -from ietf.idtracker.models import InternetDraft - -class RfcEditorQueue(models.Model): - STREAM_CHOICES = ( - (0, 'Unknown'), - (1, 'IETF'), - (2, 'IAB'), - (3, 'IRTF'), - (4, 'Independent') - ) - draft = models.OneToOneField(InternetDraft, db_column="id_document_tag", related_name="rfc_editor_queue_state",primary_key=True) - date_received = models.DateField() - state = models.CharField(max_length=200, blank=True, null=True) - # currently, queue2.xml does not have this information, so - # this field will be NULL (but we could get it from other sources) - state_date = models.DateField(blank=True,null=True) - stream = models.IntegerField(choices=STREAM_CHOICES) - auth48_url = models.CharField(max_length=200, blank=True, null=True) - rfc_number = models.IntegerField(null=True) - def __str__(self): - return "RfcEditorQueue"+str([self.draft, self.date_received, self.state, self.state_date, self.stream]) - class Meta: - db_table = "rfc_editor_queue_mirror" - -class RfcEditorQueueRef(models.Model): - source = models.ForeignKey(InternetDraft, db_column="source", related_name="rfc_editor_queue_refs") - destination = models.CharField(max_length=200) - in_queue = models.BooleanField() - direct = models.BooleanField() # Is this a direct (or indirect) depencency? - class Meta: - db_table = "rfc_editor_queue_mirror_refs" - -class RfcIndex(models.Model): - rfc_number = models.IntegerField(primary_key=True) - title = models.CharField(max_length=250) - authors = models.CharField(max_length=250) - rfc_published_date = models.DateField() - current_status = models.CharField(max_length=50,null=True) - updates = models.CharField(max_length=200,blank=True,null=True) - updated_by = models.CharField(max_length=200,blank=True,null=True) - obsoletes = models.CharField(max_length=200,blank=True,null=True) - obsoleted_by = models.CharField(max_length=200,blank=True,null=True) - also = models.CharField(max_length=50,blank=True,null=True) - draft = models.CharField(max_length=200,null=True) - has_errata = models.BooleanField() - stream = models.CharField(max_length=15,blank=True,null=True) - wg = models.CharField(max_length=15,blank=True,null=True) - file_formats = models.CharField(max_length=20,blank=True,null=True) - def __str__(self): - return "RfcIndex"+str(self.rfc_number) - class Meta: - db_table = "rfc_index_mirror" - -class DraftVersions(models.Model): - # Django does not support multi-column primary keys, so - # we can't use filename+revision. But the key for this table - # does not really matter, so we'll have an 'id' field - id = models.AutoField(primary_key=True) - filename = models.CharField(max_length=200, db_index=True) - revision = models.CharField(max_length=2) - revision_date = models.DateField() - def __str__(self): - return "DraftVersions"+self.filename+self.revision+str(self.revision_date) - class Meta: - db_table = "draft_versions_mirror" - - -from django.conf import settings -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - RfcIndexOld = RfcIndex - from ietf.doc.proxy import RfcIndex diff --git a/ietf/idtracker/.gitignore b/ietf/idtracker/.gitignore deleted file mode 100644 index a74b07aee..000000000 --- a/ietf/idtracker/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/*.pyc diff --git a/ietf/idtracker/__init__.py b/ietf/idtracker/__init__.py deleted file mode 100644 index a4b306690..000000000 --- a/ietf/idtracker/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# Copyright The IETF Trust 2007, All Rights Reserved - diff --git a/ietf/idtracker/migrations/.gitignore b/ietf/idtracker/migrations/.gitignore deleted file mode 100644 index a74b07aee..000000000 --- a/ietf/idtracker/migrations/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/*.pyc diff --git a/ietf/idtracker/migrations/0002_shepherd.py b/ietf/idtracker/migrations/0002_shepherd.py deleted file mode 100644 index 091ab06f5..000000000 --- a/ietf/idtracker/migrations/0002_shepherd.py +++ /dev/null @@ -1,437 +0,0 @@ - -from south.db import db -from django.db import models -from ietf.idtracker.models import * - -class Migration: - - def forwards(self, orm): - - # Adding field 'InternetDraft.shepherd' - db.add_column('internet_drafts', 'shepherd', orm['idtracker.internetdraft:shepherd']) - - - - def backwards(self, orm): - - # Deleting field 'InternetDraft.shepherd' - db.delete_column('internet_drafts', 'shepherd_id') - - - - models = { - 'idtracker.acronym': { - 'Meta': {'db_table': "'acronym'"}, - 'acronym': ('django.db.models.fields.CharField', [], {'max_length': '12'}), - 'acronym_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name_key': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'idtracker.area': { - 'Meta': {'db_table': "'areas'"}, - 'area_acronym': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['idtracker.Acronym']", 'unique': 'True', 'primary_key': 'True'}), - 'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'concluded_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'extra_email_addresses': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'last_modified_date': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'blank': 'True'}), - 'start_date': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.AreaStatus']"}) - }, - 'idtracker.areadirector': { - 'Meta': {'db_table': "'area_directors'"}, - 'area': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Area']", 'null': 'True', 'db_column': "'area_acronym_id'"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}) - }, - 'idtracker.areagroup': { - 'Meta': {'db_table': "'area_group'"}, - 'area': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'areagroup'", 'db_column': "'area_acronym_id'", 'to': "orm['idtracker.Area']"}), - 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IETFWG']", 'unique': 'True', 'db_column': "'group_acronym_id'"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.areastatus': { - 'Meta': {'db_table': "'area_status'"}, - 'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.areawgurl': { - 'Meta': {'db_table': "'wg_www_pages'"}, - 'description': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True', 'db_column': "'area_ID'"}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_column': "'area_Name'"}), - 'url': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'idtracker.ballotinfo': { - 'Meta': {'db_table': "'ballot_info'"}, - 'active': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'an_sent': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'an_sent_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ansent'", 'null': 'True', 'db_column': "'an_sent_by'", 'to': "orm['idtracker.IESGLogin']"}), - 'an_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'approval_text': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'ballot': ('django.db.models.fields.AutoField', [], {'primary_key': 'True', 'db_column': "'ballot_id'"}), - 'ballot_issued': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), - 'ballot_writeup': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'defer': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'defer_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'deferred'", 'null': 'True', 'db_column': "'defer_by'", 'to': "orm['idtracker.IESGLogin']"}), - 'defer_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'last_call_text': ('django.db.models.fields.TextField', [], {'blank': 'True'}) - }, - 'idtracker.chairshistory': { - 'Meta': {'db_table': "'chairs_history'"}, - 'chair_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Role']"}), - 'end_year': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}), - 'present_chair': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'start_year': ('django.db.models.fields.IntegerField', [], {}) - }, - 'idtracker.documentcomment': { - 'Meta': {'db_table': "'document_comments'"}, - 'ballot': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), - 'comment_text': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'created_by': ('BrokenForeignKey', ["orm['idtracker.IESGLogin']"], {'null': 'True', 'db_column': "'created_by'", 'null_values': '(0,999)'}), - 'date': ('django.db.models.fields.DateField', [], {'default': 'datetime.date.today', 'db_column': "'comment_date'"}), - 'document': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDInternal']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'origin_state': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments_coming_from_state'", 'null': 'True', 'db_column': "'origin_state'", 'to': "orm['idtracker.IDState']"}), - 'public_flag': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'result_state': ('BrokenForeignKey', ["orm['idtracker.IDState']"], {'related_name': '"comments_leading_to_state"', 'null': 'True', 'db_column': "'result_state'", 'null_values': '(0,99)'}), - 'rfc_flag': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), - 'time': ('django.db.models.fields.CharField', [], {'default': "'05:10:39'", 'max_length': '20', 'db_column': "'comment_time'"}), - 'version': ('django.db.models.fields.CharField', [], {'max_length': '3', 'blank': 'True'}) - }, - 'idtracker.emailaddress': { - 'Meta': {'db_table': "'email_addresses'"}, - 'address': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'email_address'"}), - 'comment': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_column': "'email_comment'", 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person_or_org': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}), - 'priority': ('django.db.models.fields.IntegerField', [], {'db_column': "'email_priority'"}), - 'type': ('django.db.models.fields.CharField', [], {'max_length': '4', 'db_column': "'email_type'"}) - }, - 'idtracker.goalmilestone': { - 'Meta': {'db_table': "'goals_milestones'"}, - 'description': ('django.db.models.fields.TextField', [], {}), - 'done': ('django.db.models.fields.CharField', [], {'max_length': '4', 'blank': 'True'}), - 'done_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'expected_due_date': ('django.db.models.fields.DateField', [], {}), - 'gm_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'group_acronym': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IETFWG']"}), - 'last_modified_date': ('django.db.models.fields.DateField', [], {}) - }, - 'idtracker.idauthor': { - 'Meta': {'db_table': "'id_authors'"}, - 'author_order': ('django.db.models.fields.IntegerField', [], {}), - 'document': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'authors'", 'db_column': "'id_document_tag'", 'to': "orm['idtracker.InternetDraft']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}) - }, - 'idtracker.idintendedstatus': { - 'Meta': {'db_table': "'id_intended_status'"}, - 'intended_status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'intended_status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.idinternal': { - 'Meta': {'db_table': "'id_internal'"}, - 'agenda': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), - 'approved_in_minute': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), - 'area_acronym': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Area']"}), - 'assigned_to': ('django.db.models.fields.CharField', [], {'max_length': '25', 'blank': 'True'}), - 'ballot': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'drafts'", 'db_column': "'ballot_id'", 'to': "orm['idtracker.BallotInfo']"}), - 'cur_state': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'docs'", 'db_column': "'cur_state'", 'to': "orm['idtracker.IDState']"}), - 'cur_sub_state': ('BrokenForeignKey', ["orm['idtracker.IDSubState']"], {'related_name': "'docs'", 'null': 'True', 'null_values': '(0,-1)', 'blank': 'True'}), - 'dnp': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), - 'dnp_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'draft': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.InternetDraft']", 'unique': 'True', 'primary_key': 'True', 'db_column': "'id_document_tag'"}), - 'email_display': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'event_date': ('django.db.models.fields.DateField', [], {'null': 'True'}), - 'group_flag': ('django.db.models.fields.IntegerField', [], {'default': '0', 'blank': 'True'}), - 'job_owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'documents'", 'db_column': "'job_owner'", 'to': "orm['idtracker.IESGLogin']"}), - 'mark_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'marked'", 'db_column': "'mark_by'", 'to': "orm['idtracker.IESGLogin']"}), - 'noproblem': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), - 'note': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'prev_state': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'docs_prev'", 'db_column': "'prev_state'", 'to': "orm['idtracker.IDState']"}), - 'prev_sub_state': ('BrokenForeignKey', ["orm['idtracker.IDSubState']"], {'related_name': "'docs_prev'", 'null': 'True', 'null_values': '(0,-1)', 'blank': 'True'}), - 'primary_flag': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), - 'resurrect_requested_by': ('BrokenForeignKey', ["orm['idtracker.IESGLogin']"], {'related_name': "'docsresurrected'", 'null': 'True', 'db_column': "'resurrect_requested_by'", 'blank': 'True'}), - 'returning_item': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), - 'rfc_flag': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), - 'state_change_notice_to': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), - 'status_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'telechat_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'token_email': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), - 'token_name': ('django.db.models.fields.CharField', [], {'max_length': '25', 'blank': 'True'}), - 'via_rfc_editor': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}) - }, - 'idtracker.idnextstate': { - 'Meta': {'db_table': "'ref_next_states_new'"}, - 'condition': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), - 'cur_state': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'nextstate'", 'to': "orm['idtracker.IDState']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'next_state': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'prevstate'", 'to': "orm['idtracker.IDState']"}) - }, - 'idtracker.idstate': { - 'Meta': {'db_table': "'ref_doc_states_new'"}, - 'description': ('django.db.models.fields.TextField', [], {'db_column': "'document_desc'", 'blank': 'True'}), - 'document_state_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'equiv_group_flag': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), - 'state': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_column': "'document_state_val'"}) - }, - 'idtracker.idstatus': { - 'Meta': {'db_table': "'id_status'"}, - 'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.idsubstate': { - 'Meta': {'db_table': "'sub_state'"}, - 'description': ('django.db.models.fields.TextField', [], {'db_column': "'sub_state_desc'", 'blank': 'True'}), - 'sub_state': ('django.db.models.fields.CharField', [], {'max_length': '55', 'db_column': "'sub_state_val'"}), - 'sub_state_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.iesgcomment': { - 'Meta': {'unique_together': "(('ballot', 'ad'),)", 'db_table': "'ballots_comment'"}, - 'active': ('django.db.models.fields.IntegerField', [], {}), - 'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IESGLogin']"}), - 'ballot': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments'", 'to': "orm['idtracker.BallotInfo']"}), - 'date': ('django.db.models.fields.DateField', [], {'db_column': "'comment_date'"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'revision': ('django.db.models.fields.CharField', [], {'max_length': '2'}), - 'text': ('django.db.models.fields.TextField', [], {'db_column': "'comment_text'", 'blank': 'True'}) - }, - 'idtracker.iesgdiscuss': { - 'Meta': {'unique_together': "(('ballot', 'ad'),)", 'db_table': "'ballots_discuss'"}, - 'active': ('django.db.models.fields.IntegerField', [], {}), - 'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IESGLogin']"}), - 'ballot': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'discusses'", 'to': "orm['idtracker.BallotInfo']"}), - 'date': ('django.db.models.fields.DateField', [], {'db_column': "'discuss_date'"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'revision': ('django.db.models.fields.CharField', [], {'max_length': '2'}), - 'text': ('django.db.models.fields.TextField', [], {'db_column': "'discuss_text'", 'blank': 'True'}) - }, - 'idtracker.iesglogin': { - 'Meta': {'db_table': "'iesg_login'"}, - 'default_search': ('django.db.models.fields.NullBooleanField', [], {'null': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '25', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '25', 'blank': 'True'}), - 'login_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), - 'password': ('django.db.models.fields.CharField', [], {'max_length': '25'}), - 'person': ('BrokenForeignKey', ["orm['idtracker.PersonOrOrgInfo']"], {'unique': 'True', 'null': 'True', 'db_column': "'person_or_org_tag'", 'null_values': '(0,888888)'}), - 'pgp_id': ('django.db.models.fields.CharField', [], {'max_length': '20', 'null': 'True', 'blank': 'True'}), - 'user_level': ('django.db.models.fields.IntegerField', [], {}) - }, - 'idtracker.ietfwg': { - 'Meta': {'db_table': "'groups_ietf'"}, - 'area_director': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.AreaDirector']", 'null': 'True'}), - 'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'concluded_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'dormant_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'email_address': ('django.db.models.fields.CharField', [], {'max_length': '60', 'blank': 'True'}), - 'email_archive': ('django.db.models.fields.CharField', [], {'max_length': '95', 'blank': 'True'}), - 'email_keyword': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'email_subscribe': ('django.db.models.fields.CharField', [], {'max_length': '120', 'blank': 'True'}), - 'group_acronym': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['idtracker.Acronym']", 'unique': 'True', 'primary_key': 'True'}), - 'group_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.WGType']"}), - 'last_modified_date': ('django.db.models.fields.DateField', [], {}), - 'meeting_scheduled': ('django.db.models.fields.CharField', [], {'max_length': '3', 'blank': 'True'}), - 'meeting_scheduled_old': ('django.db.models.fields.CharField', [], {'max_length': '3', 'blank': 'True'}), - 'proposed_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.WGStatus']"}) - }, - 'idtracker.internetdraft': { - 'Meta': {'db_table': "'internet_drafts'"}, - 'abstract': ('django.db.models.fields.TextField', [], {}), - 'b_approve_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'b_discussion_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'b_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'dunn_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True'}), - 'expired_tombstone': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'extension_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'file_type': ('django.db.models.fields.CharField', [], {'max_length': '20'}), - 'filename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), - 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Acronym']", 'db_column': "'group_acronym_id'"}), - 'id_document_key': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'id_document_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'intended_status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDIntendedStatus']"}), - 'last_modified_date': ('django.db.models.fields.DateField', [], {}), - 'lc_changes': ('django.db.models.fields.CharField', [], {'max_length': '3', 'null': 'True'}), - 'lc_expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'lc_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'local_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), - 'replaced_by': ('BrokenForeignKey', ["orm['idtracker.InternetDraft']"], {'related_name': "'replaces_set'", 'null': 'True', 'db_column': "'replaced_by'", 'blank': 'True'}), - 'review_by_rfc_editor': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'revision': ('django.db.models.fields.CharField', [], {'max_length': '2'}), - 'revision_date': ('django.db.models.fields.DateField', [], {}), - 'rfc_number': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), - 'shepherd': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}), - 'start_date': ('django.db.models.fields.DateField', [], {}), - 'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDStatus']"}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'id_document_name'"}), - 'txt_page_count': ('django.db.models.fields.IntegerField', [], {}), - 'wgreturn_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}) - }, - 'idtracker.irtf': { - 'Meta': {'db_table': "'irtf'"}, - 'acronym': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'irtf_acronym'", 'blank': 'True'}), - 'charter_text': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'irtf_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'meeting_scheduled': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'irtf_name'", 'blank': 'True'}) - }, - 'idtracker.irtfchair': { - 'Meta': {'db_table': "'irtf_chairs'"}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'irtf': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IRTF']"}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}) - }, - 'idtracker.personororginfo': { - 'Meta': {'db_table': "'person_or_org_info'"}, - 'address_type': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'created_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'date_created': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}), - 'date_modified': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'first_name_key': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'last_name_key': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'middle_initial': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'middle_initial_key': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'modified_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'name_prefix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'name_suffix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'person_or_org_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'record_type': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}) - }, - 'idtracker.phonenumber': { - 'Meta': {'db_table': "'phone_numbers'"}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person_or_org': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}), - 'phone_comment': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), - 'phone_number': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), - 'phone_priority': ('django.db.models.fields.IntegerField', [], {}), - 'phone_type': ('django.db.models.fields.CharField', [], {'max_length': '3'}) - }, - 'idtracker.position': { - 'Meta': {'unique_together': "(('ballot', 'ad'),)", 'db_table': "'ballots'"}, - 'abstain': ('django.db.models.fields.IntegerField', [], {}), - 'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IESGLogin']"}), - 'approve': ('django.db.models.fields.IntegerField', [], {'default': '0'}), - 'ballot': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'positions'", 'to': "orm['idtracker.BallotInfo']"}), - 'discuss': ('django.db.models.fields.IntegerField', [], {}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'noobj': ('django.db.models.fields.IntegerField', [], {'db_column': "'no_col'"}), - 'recuse': ('django.db.models.fields.IntegerField', [], {}), - 'yes': ('django.db.models.fields.IntegerField', [], {'db_column': "'yes_col'"}) - }, - 'idtracker.postaladdress': { - 'Meta': {'db_table': "'postal_addresses'"}, - 'address_priority': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), - 'address_type': ('django.db.models.fields.CharField', [], {'max_length': '4'}), - 'aff_company_key': ('django.db.models.fields.CharField', [], {'max_length': '70', 'blank': 'True'}), - 'affiliated_company': ('django.db.models.fields.CharField', [], {'max_length': '70', 'blank': 'True'}), - 'city': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'country': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'department': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'mail_stop': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'person_or_org': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}), - 'person_title': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'postal_code': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'staddr1': ('django.db.models.fields.CharField', [], {'max_length': '40'}), - 'staddr2': ('django.db.models.fields.CharField', [], {'max_length': '40', 'blank': 'True'}), - 'state_or_prov': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}) - }, - 'idtracker.rfc': { - 'Meta': {'db_table': "'rfcs'"}, - 'area_acronym': ('django.db.models.fields.CharField', [], {'max_length': '8', 'blank': 'True'}), - 'b_approve_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'b_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'draft_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'fyi_number': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'group_acronym': ('django.db.models.fields.CharField', [], {'max_length': '8', 'blank': 'True'}), - 'historic_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'intended_status': ('django.db.models.fields.related.ForeignKey', [], {'default': '5', 'to': "orm['idtracker.RfcIntendedStatus']", 'db_column': "'intended_status_id'"}), - 'last_modified_date': ('django.db.models.fields.DateField', [], {}), - 'lc_expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'lc_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'online_version': ('django.db.models.fields.CharField', [], {'default': "'YES'", 'max_length': '3'}), - 'proposed_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'rfc_name_key': ('django.db.models.fields.CharField', [], {'max_length': '200'}), - 'rfc_number': ('django.db.models.fields.IntegerField', [], {'primary_key': 'True'}), - 'rfc_published_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'standard_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.RfcStatus']", 'db_column': "'status_id'"}), - 'std_number': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'db_column': "'rfc_name'"}), - 'txt_page_count': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}) - }, - 'idtracker.rfcauthor': { - 'Meta': {'db_table': "'rfc_authors'"}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}), - 'rfc': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'authors'", 'db_column': "'rfc_number'", 'to': "orm['idtracker.Rfc']"}) - }, - 'idtracker.rfcintendedstatus': { - 'Meta': {'db_table': "'rfc_intend_status'"}, - 'intended_status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}) - }, - 'idtracker.rfcobsolete': { - 'Meta': {'db_table': "'rfcs_obsolete'"}, - 'action': ('django.db.models.fields.CharField', [], {'max_length': '20'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'rfc': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'updates_or_obsoletes'", 'db_column': "'rfc_number'", 'to': "orm['idtracker.Rfc']"}), - 'rfc_acted_on': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'updated_or_obsoleted_by'", 'db_column': "'rfc_acted_on'", 'to': "orm['idtracker.Rfc']"}) - }, - 'idtracker.rfcstatus': { - 'Meta': {'db_table': "'rfc_status'"}, - 'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.role': { - 'Meta': {'db_table': "'chairs'"}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}), - 'role_name': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'chair_name'"}) - }, - 'idtracker.wgchair': { - 'Meta': {'db_table': "'g_chairs'"}, - 'group_acronym': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IETFWG']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}) - }, - 'idtracker.wgeditor': { - 'Meta': {'db_table': "'g_editors'"}, - 'group_acronym': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IETFWG']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'unique': 'True', 'db_column': "'person_or_org_tag'"}) - }, - 'idtracker.wgsecretary': { - 'Meta': {'db_table': "'g_secretaries'"}, - 'group_acronym': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IETFWG']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}) - }, - 'idtracker.wgstatus': { - 'Meta': {'db_table': "'g_status'"}, - 'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.wgtechadvisor': { - 'Meta': {'db_table': "'g_tech_advisors'"}, - 'group_acronym': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IETFWG']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}) - }, - 'idtracker.wgtype': { - 'Meta': {'db_table': "'g_type'"}, - 'group_type_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'type': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'group_type'"}) - } - } - - complete_apps = ['idtracker'] diff --git a/ietf/idtracker/migrations/0003_internet_draft_shepred_fk_blank_true.py b/ietf/idtracker/migrations/0003_internet_draft_shepred_fk_blank_true.py deleted file mode 100644 index d59878dad..000000000 --- a/ietf/idtracker/migrations/0003_internet_draft_shepred_fk_blank_true.py +++ /dev/null @@ -1,439 +0,0 @@ - -from south.db import db -from django.db import models -from ietf.idtracker.models import * - -class Migration: - - def forwards(self, orm): - - # Changing field 'InternetDraft.shepherd' - # (to signature: django.db.models.fields.related.ForeignKey(to=orm['idtracker.PersonOrOrgInfo'], null=True, blank=True)) - db.alter_column('internet_drafts', 'shepherd_id', orm['idtracker.internetdraft:shepherd']) - - - - def backwards(self, orm): - - # Changing field 'InternetDraft.shepherd' - # (to signature: django.db.models.fields.related.ForeignKey(to=orm['idtracker.PersonOrOrgInfo'])) - db.alter_column('internet_drafts', 'shepherd_id', orm['idtracker.internetdraft:shepherd']) - - - - models = { - 'idtracker.acronym': { - 'Meta': {'db_table': "'acronym'"}, - 'acronym': ('django.db.models.fields.CharField', [], {'max_length': '12'}), - 'acronym_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name_key': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'idtracker.area': { - 'Meta': {'db_table': "'areas'"}, - 'area_acronym': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['idtracker.Acronym']", 'unique': 'True', 'primary_key': 'True'}), - 'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'concluded_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'extra_email_addresses': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'last_modified_date': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'blank': 'True'}), - 'start_date': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.AreaStatus']"}) - }, - 'idtracker.areadirector': { - 'Meta': {'db_table': "'area_directors'"}, - 'area': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Area']", 'null': 'True', 'db_column': "'area_acronym_id'"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}) - }, - 'idtracker.areagroup': { - 'Meta': {'db_table': "'area_group'"}, - 'area': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'areagroup'", 'db_column': "'area_acronym_id'", 'to': "orm['idtracker.Area']"}), - 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IETFWG']", 'unique': 'True', 'db_column': "'group_acronym_id'"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.areastatus': { - 'Meta': {'db_table': "'area_status'"}, - 'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.areawgurl': { - 'Meta': {'db_table': "'wg_www_pages'"}, - 'description': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True', 'db_column': "'area_ID'"}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_column': "'area_Name'"}), - 'url': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'idtracker.ballotinfo': { - 'Meta': {'db_table': "'ballot_info'"}, - 'active': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'an_sent': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'an_sent_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ansent'", 'null': 'True', 'db_column': "'an_sent_by'", 'to': "orm['idtracker.IESGLogin']"}), - 'an_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'approval_text': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'ballot': ('django.db.models.fields.AutoField', [], {'primary_key': 'True', 'db_column': "'ballot_id'"}), - 'ballot_issued': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), - 'ballot_writeup': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'defer': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'defer_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'deferred'", 'null': 'True', 'db_column': "'defer_by'", 'to': "orm['idtracker.IESGLogin']"}), - 'defer_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'last_call_text': ('django.db.models.fields.TextField', [], {'blank': 'True'}) - }, - 'idtracker.chairshistory': { - 'Meta': {'db_table': "'chairs_history'"}, - 'chair_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Role']"}), - 'end_year': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}), - 'present_chair': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'start_year': ('django.db.models.fields.IntegerField', [], {}) - }, - 'idtracker.documentcomment': { - 'Meta': {'db_table': "'document_comments'"}, - 'ballot': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), - 'comment_text': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'created_by': ('BrokenForeignKey', ["orm['idtracker.IESGLogin']"], {'null': 'True', 'db_column': "'created_by'", 'null_values': '(0,999)'}), - 'date': ('django.db.models.fields.DateField', [], {'default': 'datetime.date.today', 'db_column': "'comment_date'"}), - 'document': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDInternal']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'origin_state': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments_coming_from_state'", 'null': 'True', 'db_column': "'origin_state'", 'to': "orm['idtracker.IDState']"}), - 'public_flag': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'result_state': ('BrokenForeignKey', ["orm['idtracker.IDState']"], {'related_name': '"comments_leading_to_state"', 'null': 'True', 'db_column': "'result_state'", 'null_values': '(0,99)'}), - 'rfc_flag': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), - 'time': ('django.db.models.fields.CharField', [], {'default': "'08:36:20'", 'max_length': '20', 'db_column': "'comment_time'"}), - 'version': ('django.db.models.fields.CharField', [], {'max_length': '3', 'blank': 'True'}) - }, - 'idtracker.emailaddress': { - 'Meta': {'db_table': "'email_addresses'"}, - 'address': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'email_address'"}), - 'comment': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_column': "'email_comment'", 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person_or_org': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}), - 'priority': ('django.db.models.fields.IntegerField', [], {'db_column': "'email_priority'"}), - 'type': ('django.db.models.fields.CharField', [], {'max_length': '4', 'db_column': "'email_type'"}) - }, - 'idtracker.goalmilestone': { - 'Meta': {'db_table': "'goals_milestones'"}, - 'description': ('django.db.models.fields.TextField', [], {}), - 'done': ('django.db.models.fields.CharField', [], {'max_length': '4', 'blank': 'True'}), - 'done_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'expected_due_date': ('django.db.models.fields.DateField', [], {}), - 'gm_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'group_acronym': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IETFWG']"}), - 'last_modified_date': ('django.db.models.fields.DateField', [], {}) - }, - 'idtracker.idauthor': { - 'Meta': {'db_table': "'id_authors'"}, - 'author_order': ('django.db.models.fields.IntegerField', [], {}), - 'document': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'authors'", 'db_column': "'id_document_tag'", 'to': "orm['idtracker.InternetDraft']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}) - }, - 'idtracker.idintendedstatus': { - 'Meta': {'db_table': "'id_intended_status'"}, - 'intended_status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'intended_status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.idinternal': { - 'Meta': {'db_table': "'id_internal'"}, - 'agenda': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), - 'approved_in_minute': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), - 'area_acronym': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Area']"}), - 'assigned_to': ('django.db.models.fields.CharField', [], {'max_length': '25', 'blank': 'True'}), - 'ballot': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'drafts'", 'db_column': "'ballot_id'", 'to': "orm['idtracker.BallotInfo']"}), - 'cur_state': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'docs'", 'db_column': "'cur_state'", 'to': "orm['idtracker.IDState']"}), - 'cur_sub_state': ('BrokenForeignKey', ["orm['idtracker.IDSubState']"], {'related_name': "'docs'", 'null': 'True', 'null_values': '(0,-1)', 'blank': 'True'}), - 'dnp': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), - 'dnp_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'draft': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.InternetDraft']", 'unique': 'True', 'primary_key': 'True', 'db_column': "'id_document_tag'"}), - 'email_display': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'event_date': ('django.db.models.fields.DateField', [], {'null': 'True'}), - 'group_flag': ('django.db.models.fields.IntegerField', [], {'default': '0', 'blank': 'True'}), - 'job_owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'documents'", 'db_column': "'job_owner'", 'to': "orm['idtracker.IESGLogin']"}), - 'mark_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'marked'", 'db_column': "'mark_by'", 'to': "orm['idtracker.IESGLogin']"}), - 'noproblem': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), - 'note': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'prev_state': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'docs_prev'", 'db_column': "'prev_state'", 'to': "orm['idtracker.IDState']"}), - 'prev_sub_state': ('BrokenForeignKey', ["orm['idtracker.IDSubState']"], {'related_name': "'docs_prev'", 'null': 'True', 'null_values': '(0,-1)', 'blank': 'True'}), - 'primary_flag': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), - 'resurrect_requested_by': ('BrokenForeignKey', ["orm['idtracker.IESGLogin']"], {'related_name': "'docsresurrected'", 'null': 'True', 'db_column': "'resurrect_requested_by'", 'blank': 'True'}), - 'returning_item': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), - 'rfc_flag': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), - 'state_change_notice_to': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), - 'status_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'telechat_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'token_email': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), - 'token_name': ('django.db.models.fields.CharField', [], {'max_length': '25', 'blank': 'True'}), - 'via_rfc_editor': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}) - }, - 'idtracker.idnextstate': { - 'Meta': {'db_table': "'ref_next_states_new'"}, - 'condition': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), - 'cur_state': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'nextstate'", 'to': "orm['idtracker.IDState']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'next_state': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'prevstate'", 'to': "orm['idtracker.IDState']"}) - }, - 'idtracker.idstate': { - 'Meta': {'db_table': "'ref_doc_states_new'"}, - 'description': ('django.db.models.fields.TextField', [], {'db_column': "'document_desc'", 'blank': 'True'}), - 'document_state_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'equiv_group_flag': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), - 'state': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_column': "'document_state_val'"}) - }, - 'idtracker.idstatus': { - 'Meta': {'db_table': "'id_status'"}, - 'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.idsubstate': { - 'Meta': {'db_table': "'sub_state'"}, - 'description': ('django.db.models.fields.TextField', [], {'db_column': "'sub_state_desc'", 'blank': 'True'}), - 'sub_state': ('django.db.models.fields.CharField', [], {'max_length': '55', 'db_column': "'sub_state_val'"}), - 'sub_state_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.iesgcomment': { - 'Meta': {'unique_together': "(('ballot', 'ad'),)", 'db_table': "'ballots_comment'"}, - 'active': ('django.db.models.fields.IntegerField', [], {}), - 'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IESGLogin']"}), - 'ballot': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments'", 'to': "orm['idtracker.BallotInfo']"}), - 'date': ('django.db.models.fields.DateField', [], {'db_column': "'comment_date'"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'revision': ('django.db.models.fields.CharField', [], {'max_length': '2'}), - 'text': ('django.db.models.fields.TextField', [], {'db_column': "'comment_text'", 'blank': 'True'}) - }, - 'idtracker.iesgdiscuss': { - 'Meta': {'unique_together': "(('ballot', 'ad'),)", 'db_table': "'ballots_discuss'"}, - 'active': ('django.db.models.fields.IntegerField', [], {}), - 'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IESGLogin']"}), - 'ballot': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'discusses'", 'to': "orm['idtracker.BallotInfo']"}), - 'date': ('django.db.models.fields.DateField', [], {'db_column': "'discuss_date'"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'revision': ('django.db.models.fields.CharField', [], {'max_length': '2'}), - 'text': ('django.db.models.fields.TextField', [], {'db_column': "'discuss_text'", 'blank': 'True'}) - }, - 'idtracker.iesglogin': { - 'Meta': {'db_table': "'iesg_login'"}, - 'default_search': ('django.db.models.fields.NullBooleanField', [], {'null': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '25', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '25', 'blank': 'True'}), - 'login_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), - 'password': ('django.db.models.fields.CharField', [], {'max_length': '25'}), - 'person': ('BrokenForeignKey', ["orm['idtracker.PersonOrOrgInfo']"], {'unique': 'True', 'null': 'True', 'db_column': "'person_or_org_tag'", 'null_values': '(0,888888)'}), - 'pgp_id': ('django.db.models.fields.CharField', [], {'max_length': '20', 'null': 'True', 'blank': 'True'}), - 'user_level': ('django.db.models.fields.IntegerField', [], {}) - }, - 'idtracker.ietfwg': { - 'Meta': {'db_table': "'groups_ietf'"}, - 'area_director': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.AreaDirector']", 'null': 'True'}), - 'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'concluded_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'dormant_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'email_address': ('django.db.models.fields.CharField', [], {'max_length': '60', 'blank': 'True'}), - 'email_archive': ('django.db.models.fields.CharField', [], {'max_length': '95', 'blank': 'True'}), - 'email_keyword': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'email_subscribe': ('django.db.models.fields.CharField', [], {'max_length': '120', 'blank': 'True'}), - 'group_acronym': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['idtracker.Acronym']", 'unique': 'True', 'primary_key': 'True'}), - 'group_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.WGType']"}), - 'last_modified_date': ('django.db.models.fields.DateField', [], {}), - 'meeting_scheduled': ('django.db.models.fields.CharField', [], {'max_length': '3', 'blank': 'True'}), - 'meeting_scheduled_old': ('django.db.models.fields.CharField', [], {'max_length': '3', 'blank': 'True'}), - 'proposed_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.WGStatus']"}) - }, - 'idtracker.internetdraft': { - 'Meta': {'db_table': "'internet_drafts'"}, - 'abstract': ('django.db.models.fields.TextField', [], {}), - 'b_approve_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'b_discussion_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'b_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'dunn_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True'}), - 'expired_tombstone': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'extension_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'file_type': ('django.db.models.fields.CharField', [], {'max_length': '20'}), - 'filename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), - 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Acronym']", 'db_column': "'group_acronym_id'"}), - 'id_document_key': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'id_document_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'intended_status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDIntendedStatus']"}), - 'last_modified_date': ('django.db.models.fields.DateField', [], {}), - 'lc_changes': ('django.db.models.fields.CharField', [], {'max_length': '3', 'null': 'True'}), - 'lc_expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'lc_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'local_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), - 'replaced_by': ('BrokenForeignKey', ["orm['idtracker.InternetDraft']"], {'related_name': "'replaces_set'", 'null': 'True', 'db_column': "'replaced_by'", 'blank': 'True'}), - 'review_by_rfc_editor': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'revision': ('django.db.models.fields.CharField', [], {'max_length': '2'}), - 'revision_date': ('django.db.models.fields.DateField', [], {}), - 'rfc_number': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), - 'shepherd': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'null': 'True', 'blank': 'True'}), - 'start_date': ('django.db.models.fields.DateField', [], {}), - 'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDStatus']"}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'id_document_name'"}), - 'txt_page_count': ('django.db.models.fields.IntegerField', [], {}), - 'wgreturn_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}) - }, - 'idtracker.irtf': { - 'Meta': {'db_table': "'irtf'"}, - 'acronym': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'irtf_acronym'", 'blank': 'True'}), - 'charter_text': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'irtf_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'meeting_scheduled': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'irtf_name'", 'blank': 'True'}) - }, - 'idtracker.irtfchair': { - 'Meta': {'db_table': "'irtf_chairs'"}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'irtf': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IRTF']"}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}) - }, - 'idtracker.personororginfo': { - 'Meta': {'db_table': "'person_or_org_info'"}, - 'address_type': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'created_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'date_created': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}), - 'date_modified': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'first_name_key': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'last_name_key': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'middle_initial': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'middle_initial_key': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'modified_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'name_prefix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'name_suffix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'person_or_org_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'record_type': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}) - }, - 'idtracker.phonenumber': { - 'Meta': {'db_table': "'phone_numbers'"}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person_or_org': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}), - 'phone_comment': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), - 'phone_number': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), - 'phone_priority': ('django.db.models.fields.IntegerField', [], {}), - 'phone_type': ('django.db.models.fields.CharField', [], {'max_length': '3'}) - }, - 'idtracker.position': { - 'Meta': {'unique_together': "(('ballot', 'ad'),)", 'db_table': "'ballots'"}, - 'abstain': ('django.db.models.fields.IntegerField', [], {}), - 'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IESGLogin']"}), - 'approve': ('django.db.models.fields.IntegerField', [], {'default': '0'}), - 'ballot': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'positions'", 'to': "orm['idtracker.BallotInfo']"}), - 'discuss': ('django.db.models.fields.IntegerField', [], {}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'noobj': ('django.db.models.fields.IntegerField', [], {'db_column': "'no_col'"}), - 'recuse': ('django.db.models.fields.IntegerField', [], {}), - 'yes': ('django.db.models.fields.IntegerField', [], {'db_column': "'yes_col'"}) - }, - 'idtracker.postaladdress': { - 'Meta': {'db_table': "'postal_addresses'"}, - 'address_priority': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), - 'address_type': ('django.db.models.fields.CharField', [], {'max_length': '4'}), - 'aff_company_key': ('django.db.models.fields.CharField', [], {'max_length': '70', 'blank': 'True'}), - 'affiliated_company': ('django.db.models.fields.CharField', [], {'max_length': '70', 'blank': 'True'}), - 'city': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'country': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'department': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'mail_stop': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'person_or_org': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}), - 'person_title': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'postal_code': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'staddr1': ('django.db.models.fields.CharField', [], {'max_length': '40'}), - 'staddr2': ('django.db.models.fields.CharField', [], {'max_length': '40', 'blank': 'True'}), - 'state_or_prov': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}) - }, - 'idtracker.rfc': { - 'Meta': {'db_table': "'rfcs'"}, - 'area_acronym': ('django.db.models.fields.CharField', [], {'max_length': '8', 'blank': 'True'}), - 'b_approve_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'b_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'draft_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'fyi_number': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'group_acronym': ('django.db.models.fields.CharField', [], {'max_length': '8', 'blank': 'True'}), - 'historic_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'intended_status': ('django.db.models.fields.related.ForeignKey', [], {'default': '5', 'to': "orm['idtracker.RfcIntendedStatus']", 'db_column': "'intended_status_id'"}), - 'last_modified_date': ('django.db.models.fields.DateField', [], {}), - 'lc_expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'lc_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'online_version': ('django.db.models.fields.CharField', [], {'default': "'YES'", 'max_length': '3'}), - 'proposed_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'rfc_name_key': ('django.db.models.fields.CharField', [], {'max_length': '200'}), - 'rfc_number': ('django.db.models.fields.IntegerField', [], {'primary_key': 'True'}), - 'rfc_published_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'standard_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.RfcStatus']", 'db_column': "'status_id'"}), - 'std_number': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'db_column': "'rfc_name'"}), - 'txt_page_count': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}) - }, - 'idtracker.rfcauthor': { - 'Meta': {'db_table': "'rfc_authors'"}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}), - 'rfc': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'authors'", 'db_column': "'rfc_number'", 'to': "orm['idtracker.Rfc']"}) - }, - 'idtracker.rfcintendedstatus': { - 'Meta': {'db_table': "'rfc_intend_status'"}, - 'intended_status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}) - }, - 'idtracker.rfcobsolete': { - 'Meta': {'db_table': "'rfcs_obsolete'"}, - 'action': ('django.db.models.fields.CharField', [], {'max_length': '20'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'rfc': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'updates_or_obsoletes'", 'db_column': "'rfc_number'", 'to': "orm['idtracker.Rfc']"}), - 'rfc_acted_on': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'updated_or_obsoleted_by'", 'db_column': "'rfc_acted_on'", 'to': "orm['idtracker.Rfc']"}) - }, - 'idtracker.rfcstatus': { - 'Meta': {'db_table': "'rfc_status'"}, - 'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.role': { - 'Meta': {'db_table': "'chairs'"}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}), - 'role_name': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'chair_name'"}) - }, - 'idtracker.wgchair': { - 'Meta': {'db_table': "'g_chairs'"}, - 'group_acronym': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IETFWG']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}) - }, - 'idtracker.wgeditor': { - 'Meta': {'db_table': "'g_editors'"}, - 'group_acronym': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IETFWG']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'unique': 'True', 'db_column': "'person_or_org_tag'"}) - }, - 'idtracker.wgsecretary': { - 'Meta': {'db_table': "'g_secretaries'"}, - 'group_acronym': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IETFWG']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}) - }, - 'idtracker.wgstatus': { - 'Meta': {'db_table': "'g_status'"}, - 'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.wgtechadvisor': { - 'Meta': {'db_table': "'g_tech_advisors'"}, - 'group_acronym': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IETFWG']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}) - }, - 'idtracker.wgtype': { - 'Meta': {'db_table': "'g_type'"}, - 'group_type_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'type': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'group_type'"}) - } - } - - complete_apps = ['idtracker'] diff --git a/ietf/idtracker/migrations/__init__.py b/ietf/idtracker/migrations/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/ietf/idtracker/models.py b/ietf/idtracker/models.py deleted file mode 100644 index ca647cb4d..000000000 --- a/ietf/idtracker/models.py +++ /dev/null @@ -1,1196 +0,0 @@ -# Copyright The IETF Trust 2007, All Rights Reserved - -import os.path -import datetime -import re -import math - -from django.conf import settings -from django.db import models -from ietf.utils import FKAsOneToOne -from ietf.utils.broken_foreign_key import BrokenForeignKey -from ietf.utils.cached_lookup_field import CachedLookupField -from ietf.utils.admin import admin_link -from ietf.group.colors import fg_group_colors, bg_group_colors - -class Acronym(models.Model): - INDIVIDUAL_SUBMITTER = 1027 - - acronym_id = models.AutoField(primary_key=True) - acronym = models.CharField(max_length=12) - name = models.CharField(max_length=100) - name_key = models.CharField(max_length=50, editable=False) - def save(self): - self.name_key = self.name.upper() - super(Acronym, self).save() - def __str__(self): - return self.acronym - class Meta: - db_table = "acronym" - -class AreaStatus(models.Model): - status_id = models.AutoField(primary_key=True) - status = models.CharField(max_length=25, db_column='status_value') - def __str__(self): - return self.status - class Meta: - verbose_name = "Area Status" - verbose_name_plural = "Area Statuses" - db_table = 'area_status' - -# I think equiv_group_flag is historical. -class IDState(models.Model): - PUBLICATION_REQUESTED = 10 - LAST_CALL_REQUESTED = 15 - IN_LAST_CALL = 16 - WAITING_FOR_WRITEUP = 18 - WAITING_FOR_AD_GO_AHEAD = 19 - IESG_EVALUATION = 20 - IESG_EVALUATION_DEFER = 21 - APPROVED_ANNOUNCEMENT_SENT = 30 - AD_WATCHING = 42 - DEAD = 99 - DO_NOT_PUBLISH_STATES = (33, 34) - - document_state_id = models.AutoField(primary_key=True) - state = models.CharField(max_length=50, db_column='document_state_val') - equiv_group_flag = models.IntegerField(null=True, blank=True) - description = models.TextField(blank=True, db_column='document_desc') - def __str__(self): - return self.state - def choices(): - return [(state.document_state_id, state.state) for state in IDState.objects.all()] - choices = staticmethod(choices) - class Meta: - db_table = 'ref_doc_states_new' - ordering = ['document_state_id'] - -class IDNextState(models.Model): - cur_state = models.ForeignKey(IDState, related_name='nextstate') - next_state = models.ForeignKey(IDState, related_name='prevstate') - condition = models.CharField(blank=True, max_length=255) - def __str__(self): - return "%s -> %s" % (self.cur_state.state, self.next_state.state ) - class Meta: - db_table = 'ref_next_states_new' - -class IDSubState(models.Model): - sub_state_id = models.AutoField(primary_key=True) - sub_state = models.CharField(max_length=55, db_column='sub_state_val') - description = models.TextField(blank=True, db_column='sub_state_desc') - def __str__(self): - return self.sub_state - class Meta: - db_table = 'sub_state' - ordering = ['sub_state_id'] - -class Area(models.Model): - ACTIVE=1 - area_acronym = models.OneToOneField(Acronym, primary_key=True) - start_date = models.DateField(auto_now_add=True) - concluded_date = models.DateField(null=True, blank=True) - status = models.ForeignKey(AreaStatus) - comments = models.TextField(blank=True) - last_modified_date = models.DateField(auto_now=True) - extra_email_addresses = models.TextField(blank=True,null=True) - def __str__(self): - return self.area_acronym.acronym - def additional_urls(self): - return AreaWGURL.objects.filter(name=self.area_acronym.name) - def active_wgs(self): - return IETFWG.objects.filter(group_type=1,status=IETFWG.ACTIVE,areagroup__area=self).order_by('group_acronym__acronym') - def active_areas(): - return Area.objects.filter(status=Area.ACTIVE).order_by('area_acronym__acronym') - active_areas = staticmethod(active_areas) - - # these are copied to Group because it is still proxied. - def upcase_acronym(self): - return self.area_acronym.upper() - - def fg_color(self): - return fg_group_colors[self.upcase_area_acronym] - - def bg_color(self): - return bg_group_colors[self.upcase_area_acronym] - - class Meta: - db_table = 'areas' - verbose_name="area" - -class AreaWGURL(models.Model): - id = models.AutoField(primary_key=True, db_column='area_ID') - # For WGs, this is the WG acronym; for areas, it's the area name. - name = models.CharField(max_length=50, db_column='area_Name') - url = models.CharField(max_length=50) - description = models.CharField(max_length=50) - def __unicode__(self): - return u'%s (%s)' % (self.name, self.description) - class Meta: - ordering = ['name'] - verbose_name = "Area/WG URL" - db_table = "wg_www_pages" - -class IDStatus(models.Model): - status_id = models.AutoField(primary_key=True) - status = models.CharField(max_length=25, db_column='status_value') - def __str__(self): - return self.status - class Meta: - db_table = "id_status" - verbose_name="I-D Status" - verbose_name_plural="I-D Statuses" - -class IDIntendedStatus(models.Model): - intended_status_id = models.AutoField(primary_key=True) - intended_status = models.CharField(max_length=25, db_column='status_value') - def __str__(self): - return self.intended_status - class Meta: - db_table = "id_intended_status" - verbose_name="I-D Intended Publication Status" - verbose_name_plural="I-D Intended Publication Statuses" - -class InternetDraft(models.Model): - DAYS_TO_EXPIRE=185 - id_document_tag = models.AutoField(primary_key=True) - title = models.CharField(max_length=255, db_column='id_document_name') - id_document_key = models.CharField(max_length=255, editable=False) - group = models.ForeignKey(Acronym, db_column='group_acronym_id') - filename = models.CharField(max_length=255, unique=True) - revision = models.CharField(max_length=2) - revision_date = models.DateField() - file_type = models.CharField(max_length=20) - txt_page_count = models.IntegerField() - local_path = models.CharField(max_length=255, blank=True, null=True) - start_date = models.DateField() - expiration_date = models.DateField(null=True) - abstract = models.TextField() - dunn_sent_date = models.DateField(null=True, blank=True) - extension_date = models.DateField(null=True, blank=True) - status = models.ForeignKey(IDStatus) - intended_status = models.ForeignKey(IDIntendedStatus) - lc_sent_date = models.DateField(null=True, blank=True) - lc_changes = models.CharField(max_length=3,null=True) - lc_expiration_date = models.DateField(null=True, blank=True) - b_sent_date = models.DateField(null=True, blank=True) - b_discussion_date = models.DateField(null=True, blank=True) - b_approve_date = models.DateField(null=True, blank=True) - wgreturn_date = models.DateField(null=True, blank=True) - rfc_number = models.IntegerField(null=True, blank=True, db_index=True) - comments = models.TextField(blank=True,null=True) - last_modified_date = models.DateField() - replaced_by = BrokenForeignKey('self', db_column='replaced_by', blank=True, null=True, related_name='replaces_set') - replaces = FKAsOneToOne('replaces', reverse=True) - review_by_rfc_editor = models.BooleanField() - expired_tombstone = models.BooleanField() - idinternal = FKAsOneToOne('idinternal', reverse=True, query=models.Q(rfc_flag = 0)) - shepherd = BrokenForeignKey('PersonOrOrgInfo', null=True, blank=True, null_values=(0, )) - def __str__(self): - return self.filename - def save(self, *args, **kwargs): - self.id_document_key = self.title.upper() - super(InternetDraft, self).save(*args, **kwargs) - def displayname(self): - return self.filename - def file_tag(self): - return "<%s>" % (self.filename_with_rev()) - def filename_with_rev(self): - return "%s-%s.txt" % (self.filename, self.revision_display()) - def name(self): - # small hack to make model forward-compatible with new schema - return self.filename - def group_acronym(self): - return self.group.acronym - def group_ml_archive(self): - return self.group.ietfwg.clean_email_archive() - def idstate(self): - idinternal = self.idinternal - if idinternal: - return idinternal.docstate() - else: - return "I-D Exists" - def revision_display(self): - r = int(self.revision) - if self.status.status != 'Active' and not self.expired_tombstone: - r = max(r - 1, 0) - return "%02d" % r - def expiration(self): - return self.revision_date + datetime.timedelta(self.DAYS_TO_EXPIRE) - def can_expire(self): - # Copying the logic from expire-ids-1 without thinking - # much about it. - if self.review_by_rfc_editor: - return False - idinternal = self.idinternal - if idinternal: - cur_state_id = idinternal.cur_state_id - # 42 is "AD is Watching"; this matches what's in the - # expire-ids-1 perl script. - # A better way might be to add a column to the table - # saying whether or not a document is prevented from - # expiring. - if cur_state_id < 42: - return False - return True - - def clean_abstract(self): - # Cleaning based on what "id-abstracts-text" script does - a = self.abstract - a = re.sub(" *\r\n *", "\n", a) # get rid of DOS line endings - a = re.sub(" *\r *", "\n", a) # get rid of MAC line endings - a = re.sub("(\n *){3,}", "\n\n", a) # get rid of excessive vertical whitespace - a = re.sub("\f[\n ]*[^\n]*\n", "", a) # get rid of page headers - # Get rid of 'key words' boilerplate and anything which follows it: - # (No way that is part of the abstract...) - a = re.sub("(?s)(Conventions [Uu]sed in this [Dd]ocument|Requirements [Ll]anguage)?[\n ]*The key words \"MUST\", \"MUST NOT\",.*$", "", a) - # Get rid of status/copyright boilerplate - a = re.sub("(?s)\nStatus of [tT]his Memo\n.*$", "", a) - # wrap long lines without messing up formatting of Ok paragraphs: - while re.match("([^\n]{72,}?) +", a): - a = re.sub("([^\n]{72,}?) +([^\n ]*)(\n|$)", "\\1\n\\2 ", a) - # Remove leading and trailing whitespace - a = a.strip() - return a - - class Meta: - db_table = "internet_drafts" - -class PersonOrOrgInfo(models.Model): - person_or_org_tag = models.AutoField(primary_key=True) - record_type = models.CharField(blank=True, null=True, max_length=8) - name_prefix = models.CharField(blank=True, null=True, max_length=10) - first_name = models.CharField(blank=True, max_length=20) - first_name_key = models.CharField(blank=True, max_length=20, editable=False) - middle_initial = models.CharField(blank=True, null=True, max_length=4) - middle_initial_key = models.CharField(blank=True, null=True, max_length=4, editable=False) - last_name = models.CharField(blank=True, max_length=50) - last_name_key = models.CharField(blank=True, max_length=50, editable=False) - name_suffix = models.CharField(blank=True, null=True, max_length=10) - date_modified = models.DateField(null=True, blank=True, auto_now=True) - modified_by = models.CharField(blank=True, null=True, max_length=8) - date_created = models.DateField(auto_now_add=True, null=True) - created_by = models.CharField(blank=True, null=True, max_length=8) - address_type = models.CharField(blank=True, null=True, max_length=4) - def save(self, **kwargs): - self.first_name_key = self.first_name.upper() - self.middle_initial_key = self.middle_initial.upper() - self.last_name_key = self.last_name.upper() - super(PersonOrOrgInfo, self).save(**kwargs) - def __str__(self): - # For django.VERSION 0.96 - if self.first_name == '' and self.last_name == '': - return "(Person #%s)" % self.person_or_org_tag - return "%s %s" % ( self.first_name or "", self.last_name or "") - def __unicode__(self): - # For django.VERSION 1.x - if self.first_name == '' and self.last_name == '': - return u"(Person #%s)" % self.person_or_org_tag - return u"%s %s" % ( self.first_name or u"", self.last_name or u"") - def email(self, priority=1, type=None): - name = unicode(self) - email = '' - addresses = self.emailaddress_set.filter(address__contains="@").order_by('priority') - if addresses: - email = addresses[0].address - for a in addresses: - if a.priority == priority: - email = a.address - return (name, email) - # Added by Sunny Lee to display person's affiliation - 5/26/2007 - def affiliation(self, priority=1): - try: - postal = self.postaladdress_set.get(address_priority=priority) - except PostalAddress.DoesNotExist: - return "PersonOrOrgInfo with no postal address!" - except AssertionError: - return "PersonOrOrgInfo with multiple priority-%d addresses!" % priority - return "%s" % ( postal.affiliated_company or postal.department or "???" ) - def full_name_as_key(self): - return self.first_name.lower() + "." + self.last_name.lower() - class Meta: - db_table = 'person_or_org_info' - ordering = ['last_name'] - verbose_name="Rolodex Entry" - verbose_name_plural="Rolodex" - -# could use a mapping for user_level -class IESGLogin(models.Model): - SECRETARIAT_LEVEL = 0 - AD_LEVEL = 1 - INACTIVE_AD_LEVEL = 2 - - USER_LEVEL_CHOICES = ( - (SECRETARIAT_LEVEL, 'Secretariat'), - (AD_LEVEL, 'IESG'), - (INACTIVE_AD_LEVEL, 'ex-IESG'), - (3, 'Level 3'), - (4, 'Comment Only(?)'), - ) - id = models.AutoField(primary_key=True) - login_name = models.CharField(blank=True, max_length=255) - password = models.CharField(max_length=25) - user_level = models.IntegerField(choices=USER_LEVEL_CHOICES) - first_name = models.CharField(blank=True, max_length=25) - last_name = models.CharField(blank=True, max_length=25) - # this could be a OneToOneField but the unique constraint is violated in the data (for person_or_org_tag=188) - person = BrokenForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag', unique=True, null_values=(0, 888888), null=True) - pgp_id = models.CharField(blank=True, null=True, max_length=20) - default_search = models.NullBooleanField() - def __str__(self): - #return "%s, %s" % ( self.last_name, self.first_name) - return "%s %s" % ( self.first_name, self.last_name) - def is_current_ad(self): - return self.user_level == 1 - def active_iesg(): - return IESGLogin.objects.filter(user_level=1,id__gt=1).order_by('last_name') #XXX hardcoded - active_iesg = staticmethod(active_iesg) - class Meta: - db_table = 'iesg_login' - -class AreaDirector(models.Model): - area = models.ForeignKey(Area, db_column='area_acronym_id', null=True) - person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag') - def __str__(self): - return "%s (%s)" % ( self.person, self.role() ) - def role(self): - try: - return "%s AD" % self.area - except Area.DoesNotExist: - return "?%d? AD" % self.area_id - class Meta: - db_table = 'area_directors' - - -### -# RFC tables - -class RfcIntendedStatus(models.Model): - NONE=5 - intended_status_id = models.AutoField(primary_key=True) - status = models.CharField(max_length=25, db_column='status_value') - def __str__(self): - return self.status - class Meta: - db_table = 'rfc_intend_status' - verbose_name = 'RFC Intended Status Field' - -class RfcStatus(models.Model): - status_id = models.AutoField(primary_key=True) - status = models.CharField(max_length=25, db_column='status_value') - def __str__(self): - return self.status - class Meta: - db_table = 'rfc_status' - verbose_name = 'RFC Status' - verbose_name_plural = 'RFC Statuses' - -class Rfc(models.Model): - ONLINE_CHOICES=(('YES', 'Yes'), ('NO', 'No')) - rfc_number = models.IntegerField(primary_key=True) - title = models.CharField(max_length=200, db_column='rfc_name') - rfc_name_key = models.CharField(max_length=200, editable=False) - group_acronym = models.CharField(blank=True, max_length=8) - area_acronym = models.CharField(blank=True, max_length=8) - status = models.ForeignKey(RfcStatus, db_column="status_id") - intended_status = models.ForeignKey(RfcIntendedStatus, db_column="intended_status_id", default=RfcIntendedStatus.NONE) - fyi_number = models.CharField(blank=True, max_length=20) - std_number = models.CharField(blank=True, max_length=20) - txt_page_count = models.IntegerField(null=True, blank=True) - online_version = models.CharField(choices=ONLINE_CHOICES, max_length=3, default='YES') - rfc_published_date = models.DateField(null=True, blank=True) - proposed_date = models.DateField(null=True, blank=True) - draft_date = models.DateField(null=True, blank=True) - standard_date = models.DateField(null=True, blank=True) - historic_date = models.DateField(null=True, blank=True) - lc_sent_date = models.DateField(null=True, blank=True) - lc_expiration_date = models.DateField(null=True, blank=True) - b_sent_date = models.DateField(null=True, blank=True) - b_approve_date = models.DateField(null=True, blank=True) - comments = models.TextField(blank=True) - last_modified_date = models.DateField() - - idinternal = CachedLookupField(lookup=lambda self: IDInternal.objects.get(draft=self.rfc_number, rfc_flag=1)) - group = CachedLookupField(lookup=lambda self: Acronym.objects.get(acronym=self.group_acronym)) - - def __str__(self): - return "RFC%04d" % ( self.rfc_number ) - def save(self): - self.rfc_name_key = self.title.upper() - self.last_modified_date = datetime.date.today() - super(Rfc, self).save() - def displayname(self): - return "%s.txt" % ( self.filename() ) - def filename(self): - return "rfc%d" % ( self.rfc_number ) - def name(self): - # small hack to make model forward-compatible with new schema - return self.filename() - def revision(self): - return "RFC" - def revision_display(self): - return "RFC" - def file_tag(self): - return "RFC %s" % self.rfc_number - - # return set of RfcObsolete objects obsoleted or updated by this RFC - def obsoletes(self): - return RfcObsolete.objects.filter(rfc=self.rfc_number) - - # return set of RfcObsolete objects obsoleting or updating this RFC - def obsoleted_by(self): - return RfcObsolete.objects.filter(rfc_acted_on=self.rfc_number) - - class Meta: - db_table = 'rfcs' - verbose_name = 'RFC' - verbose_name_plural = 'RFCs' - -class RfcAuthor(models.Model): - rfc = models.ForeignKey(Rfc, db_column='rfc_number', related_name='authors') - person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag') - def __str__(self): - return "%s, %s" % ( self.person.last_name, self.person.first_name) - class Meta: - db_table = 'rfc_authors' - verbose_name = 'RFC Author' - -class RfcObsolete(models.Model): - ACTION_CHOICES=(('Obsoletes', 'Obsoletes'), ('Updates', 'Updates')) - rfc = models.ForeignKey(Rfc, db_column='rfc_number', related_name='updates_or_obsoletes') - action = models.CharField(max_length=20, choices=ACTION_CHOICES) - rfc_acted_on = models.ForeignKey(Rfc, db_column='rfc_acted_on', related_name='updated_or_obsoleted_by') - def __str__(self): - return "RFC%04d %s RFC%04d" % (self.rfc_id, self.action, self.rfc_acted_on_id) - class Meta: - db_table = 'rfcs_obsolete' - verbose_name = 'RFC updates or obsoletes' - verbose_name_plural = verbose_name - -## End RFC Tables - -class BallotInfo(models.Model): # Added by Michael Lee - ballot = models.AutoField(primary_key=True, db_column='ballot_id') - active = models.BooleanField() - an_sent = models.BooleanField() - an_sent_date = models.DateField(null=True, blank=True) - an_sent_by = models.ForeignKey(IESGLogin, db_column='an_sent_by', related_name='ansent', null=True) - defer = models.BooleanField(blank=True) - defer_by = models.ForeignKey(IESGLogin, db_column='defer_by', related_name='deferred', null=True) - defer_date = models.DateField(null=True, blank=True) - approval_text = models.TextField(blank=True) - last_call_text = models.TextField(blank=True) - ballot_writeup = models.TextField(blank=True) - ballot_issued = models.IntegerField(null=True, blank=True) - def __str__(self): - try: - return "Ballot for %s" % self.drafts.get(primary_flag=1) - except IDInternal.DoesNotExist: - return "Ballot ID %d (no I-D?)" % (self.ballot) - def remarks(self): - remarks = list(self.discusses.all()) + list(self.comments.all()) - return remarks - def active_positions(self): - '''Returns a list of dicts, with AD and Position tuples''' - active_iesg = IESGLogin.active_iesg() - ads = [ad.id for ad in active_iesg] - positions = {} - for position in self.positions.filter(ad__in=ads): - positions[position.ad_id] = position - ret = [] - for ad in active_iesg: - ret.append({'ad': ad, 'pos': positions.get(ad.id, None)}) - return ret - def needed(self, standardsTrack=True): - '''Returns text answering the question "what does this document - need to pass?". The return value is only useful if the document - is currently in IESG evaluation.''' - active_iesg = IESGLogin.active_iesg() - ads = [ad.id for ad in active_iesg] - yes = 0 - noobj = 0 - discuss = 0 - recuse = 0 - for position in self.positions.filter(ad__in=ads): - yes += 1 if position.yes > 0 else 0 - noobj += 1 if position.noobj > 0 else 0 - discuss += 1 if position.discuss > 0 else 0 - recuse += 1 if position.recuse > 0 else 0 - answer = '' - if yes < 1: - answer += "Needs a YES. " - if discuss > 0: - if discuss == 1: - answer += "Has a DISCUSS. " - else: - answer += "Has %d DISCUSSes. " % discuss - if standardsTrack: - # For standards-track, need positions from 2/3 of the - # non-recused current IESG. - needed = int(math.ceil(( active_iesg.count() - recuse ) * 2.0 /3.0)) - else: - # Info and experimental only need one position. - # Info and experimental without Yes have their full spec now. - if yes < 1: - return answer.rstrip() - else: - needed = 1 - have = yes + noobj - if have < needed: - more = needed - have - if more == 1: - answer += "Needs one more position " - else: - answer += "Needs %d more positions " % more - if discuss: - if discuss == 1: - answer += "once the DISCUSS is resolved." - else: - answer += "once %d DISCUSSES are resolved." % discuss - else: - answer += ". " - else: - answer += "Has enough positions to pass" - if discuss: - if discuss == 1: - answer += " once the DISCUSS is resolved" - else: - answer += " once %d DISCUSSES are resolved" % discuss - answer += ". " - - return answer.rstrip() - - class Meta: - db_table = 'ballot_info' - -def format_document_state(state, substate): - if substate: - return state.state + "::" + substate.sub_state - else: - return state.state - -class IDInternal(models.Model): - """ - An IDInternal represents a document that has been added to the - I-D tracker. It can be either an Internet Draft or an RFC. - The table has only a single primary key field, meaning that - there is the danger of RFC number collision with low-numbered - Internet Drafts. - - Since it's most common to be an Internet Draft, the draft - field is defined as a FK to InternetDrafts. One side effect - of this is that select_related() will only work with - rfc_flag=0. - - When searching where matches may be either I-Ds or RFCs, - you cannot use draft__ as that will cause an INNER JOIN - which will limit the responses to I-Ds. - """ - - ACTIVE=1 - PUBLISHED=3 - EXPIRED=2 - WITHDRAWN_SUBMITTER=4 - REPLACED=5 - WITHDRAWN_IETF=6 - INACTIVE_STATES=[99,32,42] - - draft = models.ForeignKey(InternetDraft, primary_key=True, unique=True, db_column='id_document_tag') - rfc_flag = models.IntegerField(null=True) - ballot = models.ForeignKey(BallotInfo, related_name='drafts', db_column="ballot_id") - primary_flag = models.IntegerField(blank=True, null=True) - group_flag = models.IntegerField(blank=True, default=0) - token_name = models.CharField(blank=True, max_length=25) - token_email = models.CharField(blank=True, max_length=255) - note = models.TextField(blank=True) - status_date = models.DateField(blank=True,null=True) - email_display = models.CharField(blank=True, max_length=50) - agenda = models.IntegerField(null=True, blank=True) - cur_state = models.ForeignKey(IDState, db_column='cur_state', related_name='docs') - prev_state = models.ForeignKey(IDState, db_column='prev_state', related_name='docs_prev') - assigned_to = models.CharField(blank=True, max_length=25) - mark_by = models.ForeignKey(IESGLogin, db_column='mark_by', related_name='marked') - job_owner = models.ForeignKey(IESGLogin, db_column='job_owner', related_name='documents') - event_date = models.DateField(null=True) - area_acronym = models.ForeignKey(Area) - cur_sub_state = BrokenForeignKey(IDSubState, related_name='docs', null=True, blank=True, null_values=(0, -1)) - prev_sub_state = BrokenForeignKey(IDSubState, related_name='docs_prev', null=True, blank=True, null_values=(0, -1)) - returning_item = models.IntegerField(null=True, blank=True) - telechat_date = models.DateField(null=True, blank=True) - via_rfc_editor = models.IntegerField(null=True, blank=True) - state_change_notice_to = models.CharField(blank=True, max_length=255) - dnp = models.IntegerField(null=True, blank=True) - dnp_date = models.DateField(null=True, blank=True) - noproblem = models.IntegerField(null=True, blank=True) - resurrect_requested_by = BrokenForeignKey(IESGLogin, db_column='resurrect_requested_by', related_name='docsresurrected', null=True, blank=True) - approved_in_minute = models.IntegerField(null=True, blank=True) - def __str__(self): - if self.rfc_flag: - return "RFC%04d" % ( self.draft_id ) - else: - return self.draft.filename - def get_absolute_url(self): - if self.rfc_flag: - return "/doc/rfc%d/" % ( self.draft_id ) - else: - return "/doc/%s/" % ( self.draft.filename ) - _cached_rfc = None - def document(self): - if self.rfc_flag: - if self._cached_rfc is None: - self._cached_rfc = Rfc.objects.get(rfc_number=self.draft_id) - return self._cached_rfc - else: - return self.draft - def public_comments(self): - return self.comments().filter(public_flag=True) - def comments(self): - # would filter by rfc_flag but the database is broken. (see - # trac ticket #96) so this risks collisions. - # return self.documentcomment_set.all().order_by('-date','-time','-id') - # - # the obvious code above doesn't work with django.VERSION 1.0/1.1 - # because "draft" isn't a true foreign key (when rfc_flag=1 the - # related InternetDraft object doesn't necessarily exist). - return DocumentComment.objects.filter(document=self.draft_id).order_by('-date','-time','-id') - def ballot_set(self): - return IDInternal.objects.filter(ballot=self.ballot_id).order_by('-primary_flag') - def ballot_primary(self): - return IDInternal.objects.filter(ballot=self.ballot_id,primary_flag=1) - def ballot_others(self): - return IDInternal.objects.filter(models.Q(primary_flag=0)|models.Q(primary_flag__isnull=True), ballot=self.ballot_id) - def docstate(self): - return format_document_state(self.cur_state, self.cur_sub_state) - def change_state(self, state, sub_state): - self.prev_state = self.cur_state - self.cur_state = state - self.prev_sub_state_id = self.cur_sub_state_id - self.cur_sub_state = sub_state - class Meta: - db_table = 'id_internal' - verbose_name = 'IDTracker Draft' - def draft_link(self): - try: - if self.rfc_flag: - return 'rfc%s' % (self.draft.pk, self.draft.pk) - else: - return '%s' % (self.draft.filename, self.draft.filename) - except Exception: - return "" - draft_link.allow_tags = True - def tracker_link(self): - try: - if self.rfc_flag: - return 'rfc%s' % (self.draft.pk, self.draft.pk) - else: - return '%s' % (self.draft.filename, self.draft.filename) - except Exception: - return "" - tracker_link.allow_tags = True - -class DocumentComment(models.Model): - BALLOT_DISCUSS = 1 - BALLOT_COMMENT = 2 - BALLOT_CHOICES = ( - (BALLOT_DISCUSS, 'discuss'), - (BALLOT_COMMENT, 'comment'), - ) - document = models.ForeignKey(IDInternal) - # NOTE: This flag is often NULL, which complicates its correct use... - rfc_flag = models.IntegerField(null=True, blank=True) - public_flag = models.BooleanField() - date = models.DateField(db_column='comment_date', default=datetime.date.today) - time = models.CharField(db_column='comment_time', max_length=20, default=lambda: datetime.datetime.now().strftime("%H:%M:%S")) - version = models.CharField(blank=True, max_length=3) - comment_text = models.TextField(blank=True) - # NOTE: This is not a true foreign key -- it sometimes has values - # (like 999) that do not exist in IESGLogin. So using select_related() - # will break! - created_by = BrokenForeignKey(IESGLogin, db_column='created_by', null=True, null_values=(0, 999)) - result_state = BrokenForeignKey(IDState, db_column='result_state', null=True, related_name="comments_leading_to_state", null_values=(0, 99)) - origin_state = models.ForeignKey(IDState, db_column='origin_state', null=True, related_name="comments_coming_from_state") - ballot = models.IntegerField(null=True, choices=BALLOT_CHOICES) - def __str__(self): - return "\"%s...\" by %s" % (self.comment_text[:20], self.get_author()) - def get_absolute_url(self): - # use self.document.rfc_flag, since - # self.rfc_flag is not always set properly. - if self.document.rfc_flag: - return "/idtracker/rfc%d/comment/%d/" % (self.document_id, self.id) - else: - return "/idtracker/%s/comment/%d/" % (self.document.draft.filename, self.id) - def get_author(self): - if self.created_by: - return str(self.created_by) - else: - return "(System)" - def get_username(self): - if self.created_by: - return self.created_by.login_name - else: - return "(System)" - def get_fullname(self): - if self.created_by: - return self.created_by.first_name + " " + self.created_by.last_name - else: - return "(System)" - def datetime(self): - # this is just a straightforward combination, except that the time is - # stored incorrectly in the database. - return datetime.datetime.combine( self.date, datetime.time( * [int(s) for s in self.time.split(":")] ) ) - def doc_id(self): - return self.document_id - def doc_name(self): - return self.document.draft.filename - class Meta: - db_table = 'document_comments' - -class Position(models.Model): - ballot = models.ForeignKey(BallotInfo, related_name='positions') - ad = models.ForeignKey(IESGLogin) - yes = models.IntegerField(db_column='yes_col') - noobj = models.IntegerField(db_column='no_col') - abstain = models.IntegerField() - approve = models.IntegerField(default=0) # doesn't appear to be used anymore? - discuss = models.IntegerField() - recuse = models.IntegerField() - def __str__(self): - return "Position for %s on %s" % ( self.ad, self.ballot ) - def abstain_ind(self): - if self.recuse: - return 'R' - if self.abstain: - return 'X' - else: - return ' ' - def name(self): - positions = {"yes":"Yes", - "noobj":"No Objection", - "discuss":"Discuss", - "abstain":"Abstain", - "recuse":"Recuse"} - p = None - for k,v in positions.iteritems(): - if self.__dict__[k] > 0: - p = v - if not p: - p = "No Record" - return p - - class Meta: - db_table = 'ballots' - unique_together = (('ballot', 'ad'), ) - verbose_name = "IESG Ballot Position" - -class IESGComment(models.Model): - ballot = models.ForeignKey(BallotInfo, related_name="comments") - ad = models.ForeignKey(IESGLogin) - date = models.DateField(db_column="comment_date") - revision = models.CharField(max_length=2) - active = models.IntegerField() # doesn't appear to be used - text = models.TextField(blank=True, db_column="comment_text") - def __str__(self): - return "Comment text by %s on %s" % ( self.ad, self.ballot ) - def is_comment(self): - return True - class Meta: - db_table = 'ballots_comment' - unique_together = (('ballot', 'ad'), ) - verbose_name = 'IESG Comment Text' - verbose_name_plural = 'IESG Comments' - -class IESGDiscuss(models.Model): - ballot = models.ForeignKey(BallotInfo, related_name="discusses") - ad = models.ForeignKey(IESGLogin) - date = models.DateField(db_column="discuss_date") - revision = models.CharField(max_length=2) - active = models.IntegerField() - text = models.TextField(blank=True, db_column="discuss_text") - def __str__(self): - return "Discuss text by %s on %s" % ( self.ad, self.ballot ) - def is_discuss(self): - return True - class Meta: - db_table = 'ballots_discuss' - unique_together = (('ballot', 'ad'), ) - verbose_name = 'IESG Discuss Text' - verbose_name_plural = 'IESG Discusses' - -class IDAuthor(models.Model): - document = models.ForeignKey(InternetDraft, db_column='id_document_tag', related_name='authors') - person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag') - author_order = models.IntegerField() - def __str__(self): - return "%s authors %s" % ( self.person, self.document.filename ) - def email(self): - addresses = self.person.emailaddress_set.filter(type='I-D',priority=self.document_id) - if len(addresses) == 0: - return None - else: - return addresses[0].address - def final_author_order(self): - # Unfortunately, multiple authors for the same draft can have - # the same value for author_order (although they should not). - # Sort by person_id in that case to get a deterministic ordering. - return "%08d%08d" % (self.author_order, self.person_id) - class Meta: - db_table = 'id_authors' - verbose_name = "I-D Author" - ordering = ['document','author_order'] - -# PostalAddress, EmailAddress and PhoneNumber are edited in -# the admin for the Rolodex. -# The unique_together constraint is commented out for now, because -# of a bug in oldforms and AutomaticManipulator which fails to -# create the isUniquefoo_bar method properly. Since django is -# moving away from oldforms, I have to assume that this is going -# to be fixed by moving admin to newforms. -# must decide which field is/are core. -class PostalAddress(models.Model): - address_type = models.CharField(max_length=4) - address_priority = models.IntegerField(null=True) - person_or_org = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag') - person_title = models.CharField(max_length=50, blank=True) - affiliated_company = models.CharField(max_length=70, blank=True) - aff_company_key = models.CharField(max_length=70, blank=True, editable=False) - department = models.CharField(max_length=100, blank=True) - staddr1 = models.CharField(max_length=40) - staddr2 = models.CharField(max_length=40, blank=True) - mail_stop = models.CharField(max_length=20, blank=True) - city = models.CharField(max_length=20, blank=True) - state_or_prov = models.CharField(max_length=20, blank=True) - postal_code = models.CharField(max_length=20, blank=True) - country = models.CharField(max_length=20, blank=True) - def save(self): - self.aff_company_key = self.affiliated_company.upper() - super(PostalAddress, self).save() - class Meta: - db_table = 'postal_addresses' - #unique_together = (('address_type', 'person_or_org'), ) - verbose_name_plural = 'Postal Addresses' - -class EmailAddress(models.Model): - person_or_org = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag') - type = models.CharField(max_length=4, db_column='email_type') - priority = models.IntegerField(db_column='email_priority') - address = models.CharField(max_length=255, db_column='email_address') - comment = models.CharField(blank=True, null=True, max_length=255, db_column='email_comment') - def __str__(self): - return self.address - person_link = admin_link('person_or_org') - def priority_link(self): - if self.type=="I-D": - return '%s' % (self.priority, self.priority) - else: - return self.priority - priority_link.allow_tags = True - class Meta: - db_table = 'email_addresses' - #unique_together = (('email_priority', 'person_or_org'), ) - # with this, I get 'ChangeManipulator' object has no attribute 'isUniqueemail_priority_person_or_org' - verbose_name_plural = 'Email addresses' - -class PhoneNumber(models.Model): - person_or_org = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag') - phone_type = models.CharField(max_length=3) - phone_priority = models.IntegerField() - phone_number = models.CharField(blank=True, max_length=255) - phone_comment = models.CharField(blank=True, max_length=255) - class Meta: - db_table = 'phone_numbers' - #unique_together = (('phone_priority', 'person_or_org'), ) - -### Working Groups - -class WGType(models.Model): - group_type_id = models.AutoField(primary_key=True) - type = models.CharField(max_length=25, db_column='group_type') - def __str__(self): - return self.type - class Meta: - verbose_name = "WG Type" - db_table = 'g_type' - -class WGStatus(models.Model): - status_id = models.AutoField(primary_key=True) - status = models.CharField(max_length=25, db_column='status_value') - def __str__(self): - return self.status - class Meta: - verbose_name = "WG Status" - verbose_name_plural = "WG Statuses" - db_table = 'g_status' - -class IETFWG(models.Model): - ACTIVE = 1 - group_acronym = models.OneToOneField(Acronym, primary_key=True, editable=False) - group_type = models.ForeignKey(WGType) - proposed_date = models.DateField(null=True, blank=True) - start_date = models.DateField(null=True, blank=True) - dormant_date = models.DateField(null=True, blank=True) - concluded_date = models.DateField(null=True, blank=True) - status = models.ForeignKey(WGStatus) - area_director = models.ForeignKey(AreaDirector, null=True) - meeting_scheduled = models.CharField(blank=True, max_length=3) - email_address = models.CharField(blank=True, max_length=60) - email_subscribe = models.CharField(blank=True, max_length=120) - email_keyword = models.CharField(blank=True, max_length=50) - email_archive = models.CharField(blank=True, max_length=95) - comments = models.TextField(blank=True) - last_modified_date = models.DateField() - meeting_scheduled_old = models.CharField(blank=True, max_length=3) - area = FKAsOneToOne('areagroup', reverse=True) - def __str__(self): - return self.group_acronym.acronym - def active_drafts(self): - return self.group_acronym.internetdraft_set.all().filter(status__status="Active") - def choices(): - return [(wg.group_acronym_id, wg.group_acronym.acronym) for wg in IETFWG.objects.all().filter(group_type__type='WG').select_related().order_by('acronym.acronym')] - choices = staticmethod(choices) - def area_acronym(self): - areas = AreaGroup.objects.filter(group__exact=self.group_acronym) - if areas: - return areas[areas.count()-1].area.area_acronym - else: - return None - def area_directors(self): - areas = AreaGroup.objects.filter(group__exact=self.group_acronym) - if areas: - return areas[areas.count()-1].area.areadirector_set.all() - else: - return None - def chairs(self): # return a set of WGChair objects for this work group - return WGChair.objects.filter(group_acronym__exact=self.group_acronym) - def secretaries(self): # return a set of WGSecretary objects for this group - return WGSecretary.objects.filter(group_acronym__exact=self.group_acronym) - def milestones(self): # return a set of GoalMilestone objects for this group - return GoalMilestone.objects.filter(group_acronym__exact=self.group_acronym) - def rfcs(self): # return a set of Rfc objects for this group - return Rfc.objects.filter(group_acronym__exact=self.group_acronym) - def drafts(self): # return a set of Rfc objects for this group - return InternetDraft.objects.filter(group__exact=self.group_acronym) - def charter_text(self): # return string containing WG description read from file - # get file path from settings. Syntesize file name from path, acronym, and suffix - try: - filename = os.path.join(settings.IETFWG_DESCRIPTIONS_PATH, self.group_acronym.acronym) + ".desc.txt" - desc_file = open(filename) - desc = desc_file.read() - except BaseException: - desc = 'Error Loading Work Group Description' - return desc - def additional_urls(self): - return AreaWGURL.objects.filter(name=self.group_acronym.acronym) - def clean_email_archive(self): - x = self.email_archive - # remove "current/" and "maillist.html" - x = re.sub("^(http://www\.ietf\.org/mail-archive/web/)([^/]+/)(current/)?([a-z]+\.html)?$", "\\1\\2", x) - return x - chairs_link = admin_link('chairs') - class Meta: - db_table = 'groups_ietf' - ordering = ['?'] # workaround django wanting to sort by acronym but not joining with it - verbose_name = 'IETF Working Group' - -class WGChair(models.Model): - person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag') - group_acronym = models.ForeignKey(IETFWG) - def __str__(self): - return "%s (%s)" % ( self.person, self.role() ) - def role(self): - return "%s %s Chair" % ( self.group_acronym, self.group_acronym.group_type ) - person_link = admin_link('person') - group_link = admin_link('group_acronym') - class Meta: - db_table = 'g_chairs' - verbose_name = "WG Chair" - -class WGEditor(models.Model): - group_acronym = models.ForeignKey(IETFWG) - person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag', unique=True) - def __str__(self): - return "%s (%s)" % (self.person, self.role()) - def role(self): - return "%s Editor" % self.group_acronym - class Meta: - db_table = 'g_editors' - verbose_name = "WG Editor" - -# Note: there is an empty table 'g_secretary'. -# This uses the 'g_secretaries' table but is called 'GSecretary' to -# match the model naming scheme. -class WGSecretary(models.Model): - group_acronym = models.ForeignKey(IETFWG) - person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag') - def __str__(self): - return "%s (%s)" % ( self.person, self.role() ) - def role(self): - return "%s %s Secretary" % ( self.group_acronym, self.group_acronym.group_type ) - class Meta: - db_table = 'g_secretaries' - verbose_name = "WG Secretary" - verbose_name_plural = "WG Secretaries" - -class WGTechAdvisor(models.Model): - group_acronym = models.ForeignKey(IETFWG) - person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag') - def __str__(self): - return "%s (%s)" % ( self.person, self.role() ) - def role(self): - return "%s Technical Advisor" % self.group_acronym - class Meta: - db_table = 'g_tech_advisors' - verbose_name = "WG Technical Advisor" - -class AreaGroup(models.Model): - area = models.ForeignKey(Area, db_column='area_acronym_id', related_name='areagroup') - group = models.ForeignKey(IETFWG, db_column='group_acronym_id', unique=True) - def __str__(self): - return "%s is in %s" % ( self.group, self.area ) - class Meta: - db_table = 'area_group' - verbose_name = 'Area this group is in' - verbose_name_plural = 'Area to Group mappings' - -class GoalMilestone(models.Model): - DONE_CHOICES = ( - ('Done', 'Done'), - ('No', 'Not Done'), - ) - gm_id = models.AutoField(primary_key=True) - group_acronym = models.ForeignKey(IETFWG) - description = models.TextField() - expected_due_date = models.DateField() - done_date = models.DateField(null=True, blank=True) - done = models.CharField(blank=True, choices=DONE_CHOICES, max_length=4) - last_modified_date = models.DateField() - def __str__(self): - return self.description - class Meta: - db_table = 'goals_milestones' - verbose_name = 'IETF WG Goal or Milestone' - verbose_name_plural = 'IETF WG Goals or Milestones' - ordering = ['expected_due_date'] - - -#### end wg stuff - -class Role(models.Model): - '''This table is named 'chairs' in the database, as its original - role was to store "who are IETF, IAB and IRTF chairs?". It has - since expanded to store roles, such as "IAB Exec Dir" and "IAD", - so the model is renamed. - ''' - person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag') - role_name = models.CharField(max_length=25, db_column='chair_name') - - # Role values - IETF_CHAIR = 1 - IAB_CHAIR = 2 - NOMCOM_CHAIR = 3 - IAB_EXCUTIVE_DIRECTOR = 4 - IRTF_CHAIR = 5 - IAD_CHAIR = 6 - RSOC_CHAIR = 7 - - # This __str__ makes it odd to use as a ForeignKey. - def __str__(self): - return "%s (%s)" % (self.person, self.role()) - def role(self): - if self.role_name in ('IETF', 'IAB', 'IRTF', 'NomCom'): - return "%s Chair" % self.role_name - else: - return self.role_name - class Meta: - db_table = 'chairs' - -class ChairsHistory(models.Model): - chair_type = models.ForeignKey(Role) - present_chair = models.BooleanField() - person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag') - start_year = models.IntegerField() - end_year = models.IntegerField(null=True, blank=True) - def __str__(self): - return str(self.person) - class Meta: - db_table = 'chairs_history' - -# -# IRTF RG info -class IRTF(models.Model): - irtf_id = models.AutoField(primary_key=True) - acronym = models.CharField(blank=True, max_length=25, db_column='irtf_acronym') - name = models.CharField(blank=True, max_length=255, db_column='irtf_name') - charter_text = models.TextField(blank=True,null=True) - meeting_scheduled = models.BooleanField(blank=True) - def __str__(self): - return self.acronym - def chairs(self): # return a set of IRTFChair objects for this work group - return IRTFChair.objects.filter(irtf=self) - class Meta: - db_table = 'irtf' - verbose_name="IRTF Research Group" - -class IRTFChair(models.Model): - irtf = models.ForeignKey(IRTF) - person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag') - def __str__(self): - return "%s is chair of %s" % (self.person, self.irtf) - class Meta: - db_table = 'irtf_chairs' - verbose_name="IRTF Research Group Chair" - -class IDDates(models.Model): - FIRST_CUT_OFF = 1 - SECOND_CUT_OFF = 2 - IETF_MONDAY = 3 - ALL_IDS_PROCESSED_BY = 4 - IETF_MONDAY_AFTER = 5 - APPROVED_V00_SUBMISSIONS = 6 - - date = models.DateField(db_column="id_date") - description = models.CharField(max_length=255, db_column="date_name") - f_name = models.CharField(max_length=255) - - class Meta: - db_table = 'id_dates' - -# Not a model, but it's related. -# This is used in the view to represent documents -# in "I-D Exists". -# -class DocumentWrapper(object): - '''A wrapper for a document, used to synthesize I-D Exists.''' - document = None - synthetic = True - job_owner = "Not Assigned Yet" - docstate = "I-D Exists" - cur_state = "I-D Exists" - cur_state_id = 100 - primary_flag = 1 - def __init__(self, document): - self.document = document - -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - InternetDraftOld = InternetDraft - IDInternalOld = IDInternal - RfcOld = Rfc - BallotInfoOld = BallotInfo - IDStateOld = IDState - IDSubStateOld = IDSubState - AreaOld = Area - AcronymOld = Acronym - IESGLoginOld = IESGLogin - IETFWGOld = IETFWG - IRTFOld = IRTF - AreaGroupOld = AreaGroup - from ietf.doc.proxy import InternetDraft, IDInternal, BallotInfo, Rfc, IDState - from ietf.name.proxy import IDSubState - from ietf.group.proxy import Area, Acronym, IETFWG, IRTF, AreaGroup - from ietf.person.proxy import IESGLogin - - -# changes done by convert-096.py:changed maxlength to max_length -# removed core -# removed edit_inline -# removed max_num_in_admin -# removed num_in_admin -# removed raw_id_admin diff --git a/ietf/idtracker/templatetags/.gitignore b/ietf/idtracker/templatetags/.gitignore deleted file mode 100644 index a74b07aee..000000000 --- a/ietf/idtracker/templatetags/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/*.pyc diff --git a/ietf/idtracker/templatetags/__init__.py b/ietf/idtracker/templatetags/__init__.py deleted file mode 100644 index a4b306690..000000000 --- a/ietf/idtracker/templatetags/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# Copyright The IETF Trust 2007, All Rights Reserved - diff --git a/ietf/iesg/admin.py b/ietf/iesg/admin.py index 7f33b717e..8dfe86601 100644 --- a/ietf/iesg/admin.py +++ b/ietf/iesg/admin.py @@ -5,9 +5,5 @@ class TelechatAgendaItemAdmin(admin.ModelAdmin): pass admin.site.register(TelechatAgendaItem, TelechatAgendaItemAdmin) -class WGActionAdmin(admin.ModelAdmin): - pass -admin.site.register(WGAction, WGActionAdmin) - admin.site.register(TelechatDate) diff --git a/ietf/iesg/agenda.py b/ietf/iesg/agenda.py new file mode 100644 index 000000000..d9c69ac81 --- /dev/null +++ b/ietf/iesg/agenda.py @@ -0,0 +1,217 @@ +# utilities for constructing agendas for IESG telechats + +import codecs, re, os, datetime + +# FIXME: once we're on Python 2.7, replace with: from collections import OrderedDict +from django.utils.datastructures import SortedDict as OrderedDict + +from django.http import Http404 +from django.conf import settings + +from ietf.iesg.models import TelechatDate, TelechatAgendaItem +from ietf.doc.models import Document, TelechatDocEvent, LastCallDocEvent, ConsensusDocEvent, DocEvent +from ietf.group.models import Group, GroupMilestone + +def get_agenda_date(date=None): + if not date: + try: + return TelechatDate.objects.active().order_by('date')[0].date + except IndexError: + return datetime.date.today() + else: + try: + # FIXME: .active() + return TelechatDate.objects.all().get(date=datetime.datetime.strptime(date, "%Y-%m-%d").date()).date + except (ValueError, TelechatDate.DoesNotExist): + raise Http404 + +def get_doc_section(doc): + if doc.type_id == 'draft': + if doc.intended_std_level_id in ["bcp", "ds", "ps", "std"]: + s = "2" + else: + s = "3" + + g = doc.group_acronym() + if g and str(g) != 'none': + s += ".1" + elif s == "3" and doc.stream_id in ("ise","irtf"): + s += ".3" + else: + s += ".2" + if doc.get_state_slug() != "rfc" and doc.get_state_slug('draft-iesg') not in ("lc", "writeupw", "goaheadw", "iesg-eva", "defer"): + s += ".3" + elif doc.returning_item(): + s += ".2" + else: + s += ".1" + + elif doc.type_id == 'charter': + s = "4" + if doc.group.state_id in ('active', 'dormant'): + s += ".2" + else: + s += ".1" + if doc.get_state_slug() in ('extrev', 'iesgrev'): + s += '.2' + else: + s += '.1' + + elif doc.type_id == 'statchg': + protocol_action = False + for relation in doc.relateddocument_set.filter(relationship__slug__in=('tops','tois','tohist','toinf','tobcp','toexp')): + if relation.relationship.slug in ('tops','tois') or relation.target.document.std_level.slug in ('std','ds','ps'): + protocol_action = True + if protocol_action: + s = "2.3" + else: + s = "3.3" + if doc.get_state_slug() not in ("iesgeval", "defer", "appr-pr", "appr-pend", "appr-sent"): + s += ".3" + elif doc.returning_item(): + s += ".2" + else: + s += ".1" + + elif doc.type_id == 'conflrev': + if doc.get_state('conflrev').slug not in ('adrev','iesgeval','appr-reqnopub-pend','appr-reqnopub-sent','appr-noprob-pend','appr-noprob-sent','defer'): + s = "3.4.3" + elif doc.returning_item(): + s = "3.4.2" + else: + s = "3.4.1" + + return s + +def agenda_sections(): + return OrderedDict([ + ('1', {'title':"Administrivia"}), + ('1.1', {'title':"Roll Call"}), + ('1.2', {'title':"Bash the Agenda"}), + ('1.3', {'title':"Approval of the Minutes of Past Telechats"}), + ('1.4', {'title':"List of Remaining Action Items from Last Telechat"}), + ('2', {'title':"Protocol Actions"}), + ('2.1', {'title':"WG Submissions"}), + ('2.1.1', {'title':"New Items", 'docs': []}), + ('2.1.2', {'title':"Returning Items", 'docs':[]}), + ('2.1.3', {'title':"For Action", 'docs':[]}), + ('2.2', {'title':"Individual Submissions"}), + ('2.2.1', {'title':"New Items", 'docs':[]}), + ('2.2.2', {'title':"Returning Items", 'docs':[]}), + ('2.2.3', {'title':"For Action", 'docs':[]}), + ('2.3', {'title':"Status Changes"}), + ('2.3.1', {'title':"New Items", 'docs':[]}), + ('2.3.2', {'title':"Returning Items", 'docs':[]}), + ('2.3.3', {'title':"For Action", 'docs':[]}), + ('3', {'title':"Document Actions"}), + ('3.1', {'title':"WG Submissions"}), + ('3.1.1', {'title':"New Items", 'docs':[]}), + ('3.1.2', {'title':"Returning Items", 'docs':[]}), + ('3.1.3', {'title':"For Action", 'docs':[]}), + ('3.2', {'title':"Individual Submissions Via AD"}), + ('3.2.1', {'title':"New Items", 'docs':[]}), + ('3.2.2', {'title':"Returning Items", 'docs':[]}), + ('3.2.3', {'title':"For Action", 'docs':[]}), + ('3.3', {'title':"Status Changes"}), + ('3.3.1', {'title':"New Items", 'docs':[]}), + ('3.3.2', {'title':"Returning Items", 'docs':[]}), + ('3.3.3', {'title':"For Action", 'docs':[]}), + ('3.4', {'title':"IRTF and Independent Submission Stream Documents"}), + ('3.4.1', {'title':"New Items", 'docs':[]}), + ('3.4.2', {'title':"Returning Items", 'docs':[]}), + ('3.4.3', {'title':"For Action", 'docs':[]}), + ('4', {'title':"Working Group Actions"}), + ('4.1', {'title':"WG Creation"}), + ('4.1.1', {'title':"Proposed for IETF Review", 'docs':[]}), + ('4.1.2', {'title':"Proposed for Approval", 'docs':[]}), + ('4.2', {'title':"WG Rechartering"}), + ('4.2.1', {'title':"Under Evaluation for IETF Review", 'docs':[]}), + ('4.2.2', {'title':"Proposed for Approval", 'docs':[]}), + ('5', {'title':"IAB News We Can Use"}), + ('6', {'title':"Management Issues"}), + ('7', {'title':"Working Group News"}), + ]) + +def fill_in_agenda_administrivia(date, sections): + extra_info_files = ( + ("1.1", "roll_call", settings.IESG_ROLL_CALL_FILE), + ("1.3", "minutes", settings.IESG_MINUTES_FILE), + ("1.4", "action_items", settings.IESG_TASK_FILE), + ) + + for s, key, filename in extra_info_files: + try: + with codecs.open(filename, 'r', 'utf-8', 'replace') as f: + t = f.read().strip() + except IOError: + t = u"(Error reading %s)" % filename + + sections[s]["text"] = t + +def fill_in_agenda_docs(date, sections, matches=None): + if not matches: + matches = Document.objects.filter(docevent__telechatdocevent__telechat_date=date) + matches = matches.select_related("stream", "group").distinct() + + docs = [] + for doc in matches: + if doc.latest_event(TelechatDocEvent, type="scheduled_for_telechat").telechat_date != date: + continue + + e = doc.latest_event(type="started_iesg_process") + doc.balloting_started = e.time if e else datetime.datetime.min + + if doc.type_id == "draft": + s = doc.get_state("draft-iana-review") + if s: # and s.slug in ("not-ok", "changed", "need-rev"): + doc.iana_review_state = str(s) + + if doc.get_state_slug("draft-iesg") == "lc": + e = doc.latest_event(LastCallDocEvent, type="sent_last_call") + if e: + doc.lastcall_expires = e.expires + + if doc.stream_id in ("ietf", "irtf", "iab"): + doc.consensus = "Unknown" + e = doc.latest_event(ConsensusDocEvent, type="changed_consensus") + if e: + doc.consensus = "Yes" if e.consensus else "No" + elif doc.type_id == "conflrev": + doc.conflictdoc = doc.relateddocument_set.get(relationship__slug='conflrev').target.document + elif doc.type_id == "charter": + #if doc.group.state_id not in ("proposed", "active"): + # continue + + doc.group.txt_link = settings.CHARTER_TXT_URL + "%s-%s.txt" % (doc.canonical_name(), doc.rev) + + num = get_doc_section(doc) + if num: # and num in sections + sections[num]["docs"].append(doc) + + # prune empty "For action" sections + empty_for_action = [num for num, section in sections.iteritems() + if section["title"] == "For Action" and not section["docs"]] + for num in empty_for_action: + del sections[num] + + # Be careful to keep this the same as what's used in agenda_documents + for s in sections.itervalues(): + if "docs" in s: + s["docs"].sort(key=lambda d: d.balloting_started) + +def fill_in_agenda_management_issues(date, sections): + s = "6.%s" + for i, item in enumerate(TelechatAgendaItem.objects.filter(type=3).order_by('id'), start=1): + sections[s % i] = { "title": item.title, "text": item.text } + +def agenda_data(date=None): + """Return a dict with the different IESG telechat agenda components.""" + date = get_agenda_date(date) + sections = agenda_sections() + + fill_in_agenda_administrivia(date, sections) + fill_in_agenda_docs(date, sections) + fill_in_agenda_management_issues(date, sections) + + return { 'date': date.isoformat(), 'sections': sections } + diff --git a/ietf/iesg/feeds.py b/ietf/iesg/feeds.py index 72c77ebd1..a17441f03 100644 --- a/ietf/iesg/feeds.py +++ b/ietf/iesg/feeds.py @@ -8,27 +8,31 @@ import datetime class IESGAgenda(Feed): title = "Documents on Future IESG Telechat Agendas" - link = "http://datatracker.ietf.org/iesg/agenda/" + link = settings.IDTRACKER_BASE_URL + "/iesg/agenda/" feed_type = Atom1Feed def items(self): from ietf.doc.models import TelechatDocEvent - drafts = Document.objects.filter(docevent__telechatdocevent__telechat_date__gte=datetime.date.min).distinct() - for d in drafts: + docs = Document.objects.filter(docevent__telechatdocevent__telechat_date__gte=datetime.date.today()).distinct() + for d in docs: d.latest_telechat_event = d.latest_event(TelechatDocEvent, type="scheduled_for_telechat") - drafts = [d for d in drafts if d.latest_telechat_event.telechat_date] - drafts.sort(key=lambda d: d.latest_telechat_event.telechat_date) - return drafts + docs = [d for d in docs if d.latest_telechat_event.telechat_date] + docs.sort(key=lambda d: d.latest_telechat_event.telechat_date, reverse=True) + return docs + def item_categories(self, doc): + return [ str(doc.telechat_date) ] - def item_categories(self, item): - return [ str(item.telechat_date) ] - - def item_pubdate(self, item): - return item.latest_telechat_event.time + def item_pubdate(self, doc): + return doc.latest_telechat_event.time - def item_author_name(self, item): - return str( item.ad ) if item.ad else "None" + def item_author_name(self, doc): + return doc.ad.plain_name() if doc.ad else "None" - def item_author_email(self, item): - return str( item.ad.role_email("ad") ) if item.ad else "" + def item_author_email(self, doc): + if not doc.ad: + return "" + e = doc.ad.role_email("ad") + if not e: + return "" + return e.address diff --git a/ietf/iesg/fixtures/sieve-charter.txt b/ietf/iesg/fixtures/sieve-charter.txt deleted file mode 100644 index 389aef8d0..000000000 --- a/ietf/iesg/fixtures/sieve-charter.txt +++ /dev/null @@ -1,143 +0,0 @@ -Sieve Mail Filtering Language (sieve) -------------------------------------- -Current Status: Active -Last updated: 2010-05-07 - -Chairs: -Cyrus Daboo -Aaron Stone - -Applications Area Directors: -Alexey Melnikov -Peter Saint-Andre - -Applications Area Advisor: -Alexey Melnikov - -Mailing Lists: -General Discussion: sieve@ietf.org -To Subscribe: sieve-request@ietf.org -Archive: -http://www.ietf.org/mail-archive/web/sieve/current/maillist.html - -Description of Working Group: - -The SIEVE email filtering language is specified in RFC 5228, together -with a number of extensions. - -The SIEVE working group is being re-chartered to: - -(1) Finish work on existing in-progress Working Group documents: -(a) External lists (draft-ietf-sieve-external-lists) -(b) Notify SIP (draft-ietf-sieve-notify-sip-message) -(c) RegEx (draft-ietf-sieve-regex) -(d) Include/multi-script (draft-ietf-sieve-include) -(e) Sieve in IMAP (draft-ietf-sieve-imap-sieve) - -(2) Finalize and publish the following SIEVE extensions as proposed -standards: -(a) General Auto-reply (draft-george-sieve-autoreply) -(b) Notify presence (draft-george-sieve-notify-presence) -(c) Vacation time (draft-george-sieve-vacation-time) -(d) Convert messages (draft-melnikov-sieve-convert) - -Additional drafts may be added to this list, but only via a charter -revision. There must also be demonstrable willingness in the SIEVE -development community to actually implement a given extension before it -can be added to this charter. - -(3) Work on a specification for iCalendar and vCard extraction, and -cooperate with the VCARDDAV WG for address book tests in Sieve. - -(4) Work on a specification to describe how EAI/IDN issues should be -handled in SIEVE. - -(5) Work on a "Benefits of SIEVE" guide for client and server vendors -that: -(a) Describes the SIEVE protocol and its suite of extensions. -(b) Explains the benefits of server-side filtering in practical terms. -(c) Shows how client-side filtering can be migrated to SIEVE. - -(6) Produce one or more informational RFCs containing a set of test -scripts and test email messages that are to be filtered by the scripts, -and the expected results of that filtering. This will serve as the basis -of a interoperability test suite to help determine the suitability of -moving the base specification and selected extensions to Draft status. - - -Goals and Milestones: -Done - Submit revised variables draft. -Done - Submit revised vacation draft. -Done - WG last call for variables draft. -Done - Initial submission of RFC 3028bis. -Done - WG last call for RFC 3028bis. -Done - Initial submission of revised relational draft. -Done - Initial submission of revised subaddress draft. -Done - Initial submission of revised spamtest/virustest draft. -Done - Submit revised editheader draft. -Done - Submit revised imapflags draft. -Done - WG last call of revised subaddress draft. -Done - Submit revised body test draft. -Done - Submit revised reject before delivery draft. -Done - WG last call for editheader draft. -Done - WG last call for body test draft. -Done - WG last call for refuse draft -Done - WG last call of revised spamtest draft -Done - Submit variables draft to IESG -Done - Submit revised loop draft -Done - Submit revised notification action draft -Done - WG last call of revised relational draft -Done - WG last call for imap-flags draft -Done - WG last call for vacation draft -Done - WG last call of revised subaddress draft -Done - Submit revised relational draft to IESG -Done - Submit vacation draft to IESG -Done - Submit revised subaddress draft to IESG -Done - Submit imapflags draft to IESG -Done - Submit revised spamtest draft to IESG -Done - Submit 3028bis to IESG -Done - Submit editheader draft to IESG -Done - Submit body test draft to IESG -Done - WG last call for notification action draft -Done - Submit notification action draft to IESG -Done - Submit refuse-reject to IESG -Done - Submit notify-mailto to IESG -Done - Submit mime-loops to IESG -Done - WGLC iHave -Done - WGLC Notary -Done - Submit iHave to IESG -Done - Submit Notary to IESG -Done - WGLC sieve-in-xml -Done - Submit sieve-in-xml to IESG -Done - WGLC ManageSIEVE -Done - Submit ManageSIEVE to IESG -Done - WGLC Notify-sip -Done - WGLC Metadata -Done - Submit Metadata to IESG -Done - Publish refuse/reject - RFC 5429 -Done - Publish notify base spec - RFC 5435 -Done - Publish notify mailto extension - RFC 5436 -Done - Publish notify xmpp extension - RFC 5437 -Done - Publish ihave - RFC 5463 -Done - Publish meta-data - RFC 5490 -Done - Publish mime loops - RFC 5703 -Done - Publish Sieve in XML - RFC 5784 -Done - Revised RegEx draft -Apr 2010 - Revised Include/multi-script draft -Apr 2010 - WGLC external-lists -May 2010 - WGLC Include/multi-script -May 2010 - Submit external-lists to IESG -Jun 2010 - Submit Include/multi-script to IESG -Jun 2010 - WGLC Notify-SIP -Jul 2010 - Initial eai-issues draft -Jul 2010 - Submit Notify-SIP to IESG -Aug 2010 - WGLC RegEx -Aug 2010 - Initial test-scripts draft -Aug 2010 - Initial benefits draft -Sep 2010 - Submit RegEx to IESG -Oct 2010 - WGLC eai-issues -Nov 2010 - Submit eai-issues to IESG -Nov 2010 - WGLC benefits -Jan 2011 - Submit benefits to IESG -Mar 2011 - WGLC test-scripts -Apr 2011 - Submit test-scripts to IESG \ No newline at end of file diff --git a/ietf/iesg/models.py b/ietf/iesg/models.py index f5b73b922..a797f9ab6 100644 --- a/ietf/iesg/models.py +++ b/ietf/iesg/models.py @@ -32,53 +32,10 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -from django.db import models -from django.conf import settings -from ietf.idtracker.models import Acronym import datetime -# This table is not used by any code right now, and according to Glen, -# probably not currently (Aug 2009) maintained by the secretariat. -#class TelechatMinutes(models.Model): -# telechat_date = models.DateField(null=True, blank=True) -# telechat_minute = models.TextField(blank=True) -# exported = models.IntegerField(null=True, blank=True) -# def get_absolute_url(self): -# return "/iesg/telechat/%d/" % self.id -# def __str__(self): -# return "IESG Telechat Minutes for %s" % self.telechat_date -# class Meta: -# db_table = 'telechat_minutes' -# verbose_name = "Telechat Minute Text" -# verbose_name_plural = "Telechat Minutes" - -# this model is deprecated -class TelechatDates(models.Model): - date1 = models.DateField(primary_key=True, null=True, blank=True) - date2 = models.DateField(null=True, blank=True) - date3 = models.DateField(null=True, blank=True) - date4 = models.DateField(null=True, blank=True) - def dates(self): - l = [] - if self.date1: - l.append(self.date1) - if self.date2: - l.append(self.date2) - if self.date3: - l.append(self.date3) - if self.date4: - l.append(self.date4) - return l - - def save(self): - # date1 isn't really a primary id, so save() doesn't work - raise NotImplemented - - def __str__(self): - return " / ".join([str(d) for d in [self.date1,self.date2,self.date3,self.date4]]) - class Meta: - db_table = "telechat_dates" - verbose_name = "Next Telechat Date" +from django.db import models +from django.conf import settings class TelechatAgendaItem(models.Model): TYPE_CHOICES = ( @@ -91,41 +48,10 @@ class TelechatAgendaItem(models.Model): text = models.TextField(blank=True, db_column='template_text') type = models.IntegerField(db_column='template_type', choices=TYPE_CHOICES, default=3) title = models.CharField(max_length=255, db_column='template_title') - #The following fields are apparently not used - #note = models.TextField(null=True,blank=True) - #discussed_status_id = models.IntegerField(null=True, blank=True) - #decision = models.TextField(null=True,blank=True) + def __unicode__(self): type_name = self.TYPE_CHOICES_DICT.get(self.type, str(self.type)) return u'%s: %s' % (type_name, self.title or "") - class Meta: - if not settings.USE_DB_REDESIGN_PROXY_CLASSES: - db_table = 'templates' - -class WGAction(models.Model): - CATEGORY_CHOICES = ( - (11, "WG Creation::In Internal Review"), - (12, "WG Creation::Proposed for IETF Review"), - (13, "WG Creation::Proposed for Approval"), - (21, "WG Rechartering::In Internal Review"), - (22, "WG Rechartering::Under evaluation for IETF Review"), - (23, "WG Rechartering::Proposed for Approval") - ) - # note that with the new schema, Acronym is monkey-patched and is really Group - group_acronym = models.ForeignKey(Acronym, db_column='group_acronym_id', primary_key=True, unique=True) - note = models.TextField(blank=True,null=True) - status_date = models.DateField() - agenda = models.BooleanField("On Agenda") - token_name = models.CharField(max_length=25) - category = models.IntegerField(db_column='pwg_cat_id', choices=CATEGORY_CHOICES, default=11) - telechat_date = models.DateField() #choices = [(x.telechat_date,x.telechat_date) for x in Telechat.objects.all().order_by('-telechat_date')]) - def __str__(self): - return str(self.telechat_date)+": "+str(self.group_acronym) - class Meta: - if not settings.USE_DB_REDESIGN_PROXY_CLASSES: - db_table = 'group_internal' - ordering = ['-telechat_date'] - verbose_name = "WG Action" class Telechat(models.Model): telechat_id = models.IntegerField(primary_key=True) @@ -136,6 +62,7 @@ class Telechat(models.Model): management_issue = models.TextField(blank=True) frozen = models.IntegerField(null=True, blank=True) mi_frozen = models.IntegerField(null=True, blank=True) + class Meta: db_table = u'telechat' @@ -160,55 +87,3 @@ class TelechatDate(models.Model): class Meta: ordering = ['-date'] - -class TelechatDatesProxyDummy(object): - def all(self): - class Dummy(object): - def __getitem__(self, i): - return self - - def get_date(self, index): - if not hasattr(self, "date_cache"): - self.date_cache = TelechatDate.objects.active().order_by("date") - - if index < len(self.date_cache): - return self.date_cache[index].date - return None - - #date1 = models.DateField(primary_key=True, null=True, blank= True) - @property - def date1(self): - return self.get_date(0) - #date2 = models.DateField(null=True, blank=True) - @property - def date2(self): - return self.get_date(1) - #date3 = models.DateField(null=True, blank=True) - @property - def date3(self): - return self.get_date(2) - #date4 = models.DateField(null=True, blank=True) - @property - def date4(self): - return self.get_date(3) - - def dates(self): - l = [] - if self.date1: - l.append(self.date1) - if self.date2: - l.append(self.date2) - if self.date3: - l.append(self.date3) - if self.date4: - l.append(self.date4) - return l - - return Dummy() - -class TelechatDatesProxy(object): - objects = TelechatDatesProxyDummy() - -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - TelechatDatesOld = TelechatDates - TelechatDates = TelechatDatesProxy diff --git a/ietf/iesg/tests.py b/ietf/iesg/tests.py index 91b85f875..16c23ebc6 100644 --- a/ietf/iesg/tests.py +++ b/ietf/iesg/tests.py @@ -1,67 +1,367 @@ -from datetime import timedelta -import os, shutil +import os, shutil, json from django.core.urlresolvers import reverse as urlreverse from django.conf import settings from pyquery import PyQuery -from ietf.idtracker.models import * +from ietf.utils.test_data import make_test_data +from ietf.doc.models import * +from ietf.person.models import Person +from ietf.group.models import Group +from ietf.name.models import StreamName from ietf.iesg.models import * -from ietf.utils.test_utils import TestCase, SimpleUrlTestCase, RealDatabaseTest, canonicalize_feed, login_testing_unauthorized -from ietf.ietfworkflows.models import Stream +from ietf.utils.test_utils import TestCase, login_testing_unauthorized +from ietf.iesg.agenda import get_agenda_date, agenda_data -class RescheduleOnAgendaTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['base', 'draft'] +class ReviewDecisionsTests(TestCase): + def test_review_decisions(self): + draft = make_test_data() - def test_reschedule(self): - draft = InternetDraft.objects.get(filename="draft-ietf-mipshop-pfmipv6") - draft.idinternal.telechat_date = TelechatDates.objects.all()[0].dates()[0] - draft.idinternal.agenda = True - draft.idinternal.returning_item = True - draft.idinternal.save() + e = DocEvent(type="iesg_approved") + e.doc = draft + e.by = Person.objects.get(name="Aread Irector") + e.save() - form_id = draft.idinternal.draft_id - telechat_date_before = draft.idinternal.telechat_date - - url = urlreverse('ietf.iesg.views.agenda_documents') - self.client.login(remote_user="klm") + url = urlreverse('ietf.iesg.views.review_decisions') - # normal get r = self.client.get(url) self.assertEquals(r.status_code, 200) - q = PyQuery(r.content) - self.assertEquals(len(q('form select[name=%s-telechat_date]' % form_id)), 1) - self.assertEquals(len(q('form input[name=%s-clear_returning_item]' % form_id)), 1) + self.assertTrue(draft.name in r.content) - # reschedule - comments_before = draft.idinternal.comments().count() - d = TelechatDates.objects.all()[0].dates()[2] +class IESGAgendaTests(TestCase): + def setUp(self): + make_test_data() - r = self.client.post(url, { '%s-telechat_date' % form_id: d.strftime("%Y-%m-%d"), - '%s-clear_returning_item' % form_id: "1" }) + ise_draft = Document.objects.get(name="draft-imaginary-independent-submission") + ise_draft.stream = StreamName.objects.get(slug="ise") + ise_draft.save() + + self.telechat_docs = { + "ietf_draft": Document.objects.get(name="draft-ietf-mars-test"), + "ise_draft": ise_draft, + "conflrev": Document.objects.get(name="conflict-review-imaginary-irtf-submission"), + "statchg": Document.objects.get(name="status-change-imaginary-mid-review"), + "charter": Document.objects.filter(type="charter")[0], + } + + by = Person.objects.get(name="Aread Irector") + date = get_agenda_date() + + self.draft_dir = os.path.abspath("tmp-agenda-draft-dir") + os.mkdir(self.draft_dir) + settings.INTERNET_DRAFT_PATH = self.draft_dir + + for d in self.telechat_docs.values(): + TelechatDocEvent.objects.create(type="scheduled_for_telechat", + doc=d, + by=by, + telechat_date=date, + returning_item=True) + + + def tearDown(self): + shutil.rmtree(self.draft_dir) + + def test_fill_in_agenda_docs(self): + draft = self.telechat_docs["ietf_draft"] + statchg = self.telechat_docs["statchg"] + conflrev = self.telechat_docs["conflrev"] + charter = self.telechat_docs["charter"] + + # put on agenda + date = datetime.date.today() + datetime.timedelta(days=50) + TelechatDate.objects.create(date=date) + telechat_event = TelechatDocEvent.objects.create( + type="scheduled_for_telechat", + doc=draft, + by=Person.objects.get(name="Aread Irector"), + telechat_date=date, + returning_item=False) + date_str = date.isoformat() + + # 2.1 protocol WG submissions + draft.intended_std_level_id = "ps" + draft.group = Group.objects.get(acronym="mars") + draft.save() + draft.set_state(State.objects.get(type="draft-iesg", slug="iesg-eva")) + self.assertTrue(draft in agenda_data(date_str)["sections"]["2.1.1"]["docs"]) + + telechat_event.returning_item = True + telechat_event.save() + self.assertTrue(draft in agenda_data(date_str)["sections"]["2.1.2"]["docs"]) + + telechat_event.returning_item = False + telechat_event.save() + draft.set_state(State.objects.get(type="draft-iesg", slug="pub-req")) + self.assertTrue(draft in agenda_data(date_str)["sections"]["2.1.3"]["docs"]) + + # 2.2 protocol individual submissions + draft.group = Group.objects.get(type="individ") + draft.save() + draft.set_state(State.objects.get(type="draft-iesg", slug="iesg-eva")) + self.assertTrue(draft in agenda_data(date_str)["sections"]["2.2.1"]["docs"]) + + telechat_event.returning_item = True + telechat_event.save() + self.assertTrue(draft in agenda_data(date_str)["sections"]["2.2.2"]["docs"]) + + telechat_event.returning_item = False + telechat_event.save() + draft.set_state(State.objects.get(type="draft-iesg", slug="pub-req")) + self.assertTrue(draft in agenda_data(date_str)["sections"]["2.2.3"]["docs"]) + + # 3.1 document WG submissions + draft.intended_std_level_id = "inf" + draft.group = Group.objects.get(acronym="mars") + draft.save() + draft.set_state(State.objects.get(type="draft-iesg", slug="iesg-eva")) + self.assertTrue(draft in agenda_data(date_str)["sections"]["3.1.1"]["docs"]) + + telechat_event.returning_item = True + telechat_event.save() + self.assertTrue(draft in agenda_data(date_str)["sections"]["3.1.2"]["docs"]) + + telechat_event.returning_item = False + telechat_event.save() + draft.set_state(State.objects.get(type="draft-iesg", slug="pub-req")) + self.assertTrue(draft in agenda_data(date_str)["sections"]["3.1.3"]["docs"]) + + # 3.2 document individual submissions + draft.group = Group.objects.get(type="individ") + draft.save() + draft.set_state(State.objects.get(type="draft-iesg", slug="iesg-eva")) + self.assertTrue(draft in agenda_data(date_str)["sections"]["3.2.1"]["docs"]) + + telechat_event.returning_item = True + telechat_event.save() + self.assertTrue(draft in agenda_data(date_str)["sections"]["3.2.2"]["docs"]) + + telechat_event.returning_item = False + telechat_event.save() + draft.set_state(State.objects.get(type="draft-iesg", slug="pub-req")) + self.assertTrue(draft in agenda_data(date_str)["sections"]["3.2.3"]["docs"]) + + # 2.3 protocol status changes + telechat_event.doc = statchg + telechat_event.save() + + relation = RelatedDocument.objects.create( + source=statchg, + target=DocAlias.objects.filter(name__startswith='rfc', document__std_level="ps")[0], + relationship_id="tohist") + + statchg.group = Group.objects.get(acronym="mars") + statchg.save() + statchg.set_state(State.objects.get(type="statchg", slug="iesgeval")) + self.assertTrue(statchg in agenda_data(date_str)["sections"]["2.3.1"]["docs"]) + + telechat_event.returning_item = True + telechat_event.save() + self.assertTrue(statchg in agenda_data(date_str)["sections"]["2.3.2"]["docs"]) + + telechat_event.returning_item = False + telechat_event.save() + statchg.set_state(State.objects.get(type="statchg", slug="adrev")) + self.assertTrue(statchg in agenda_data(date_str)["sections"]["2.3.3"]["docs"]) + + # 3.3 document status changes + relation.target = DocAlias.objects.filter(name__startswith='rfc', document__std_level="inf")[0] + relation.save() + + statchg.group = Group.objects.get(acronym="mars") + statchg.save() + statchg.set_state(State.objects.get(type="statchg", slug="iesgeval")) + self.assertTrue(statchg in agenda_data(date_str)["sections"]["3.3.1"]["docs"]) + + telechat_event.returning_item = True + telechat_event.save() + self.assertTrue(statchg in agenda_data(date_str)["sections"]["3.3.2"]["docs"]) + + telechat_event.returning_item = False + telechat_event.save() + statchg.set_state(State.objects.get(type="statchg", slug="adrev")) + self.assertTrue(statchg in agenda_data(date_str)["sections"]["3.3.3"]["docs"]) + + # 3.4 IRTF/ISE conflict reviews + telechat_event.doc = conflrev + telechat_event.save() + + conflrev.group = Group.objects.get(acronym="mars") + conflrev.save() + conflrev.set_state(State.objects.get(type="conflrev", slug="iesgeval")) + self.assertTrue(conflrev in agenda_data(date_str)["sections"]["3.4.1"]["docs"]) + + telechat_event.returning_item = True + telechat_event.save() + self.assertTrue(conflrev in agenda_data(date_str)["sections"]["3.4.2"]["docs"]) + + telechat_event.returning_item = False + telechat_event.save() + conflrev.set_state(State.objects.get(type="conflrev", slug="needshep")) + self.assertTrue(conflrev in agenda_data(date_str)["sections"]["3.4.3"]["docs"]) + + + # 4 WGs + telechat_event.doc = charter + telechat_event.save() + + charter.group = Group.objects.get(acronym="mars") + charter.save() + + charter.group.state_id = "bof" + charter.group.save() + + charter.set_state(State.objects.get(type="charter", slug="infrev")) + self.assertTrue(charter in agenda_data(date_str)["sections"]["4.1.1"]["docs"]) + + charter.set_state(State.objects.get(type="charter", slug="iesgrev")) + self.assertTrue(charter in agenda_data(date_str)["sections"]["4.1.2"]["docs"]) + + charter.group.state_id = "active" + charter.group.save() + + charter.set_state(State.objects.get(type="charter", slug="infrev")) + self.assertTrue(charter in agenda_data(date_str)["sections"]["4.2.1"]["docs"]) + + charter.set_state(State.objects.get(type="charter", slug="iesgrev")) + self.assertTrue(charter in agenda_data(date_str)["sections"]["4.2.2"]["docs"]) + + #for n, s in agenda_data(date_str)["sections"].iteritems(): + # print n, s.get("docs") if "docs" in s else s["title"] + + def test_feed(self): + url = "/feed/iesg-agenda/" + + r = self.client.get(url) self.assertEquals(r.status_code, 200) - # check that it moved below the right header in the DOM - d_header_pos = r.content.find("IESG telechat %s" % d.strftime("%Y-%m-%d")) - draft_pos = r.content.find(draft.filename) - self.assertTrue(d_header_pos < draft_pos) + for d in self.telechat_docs.values(): + self.assertTrue(d.name in r.content) + self.assertTrue(d.title in r.content) - draft = InternetDraft.objects.get(filename="draft-ietf-mipshop-pfmipv6") - self.assertEquals(draft.idinternal.telechat_date, d) - self.assertTrue(not draft.idinternal.returning_item) - self.assertEquals(draft.idinternal.comments().count(), comments_before + 1) - self.assertTrue("Telechat" in draft.idinternal.comments()[0].comment_text) + def test_agenda_json(self): + r = self.client.get(urlreverse("ietf.iesg.views.agenda_json")) + self.assertEquals(r.status_code, 200) -class RescheduleOnAgendaTestCaseREDESIGN(TestCase): - perma_fixtures = ['names'] + for k, d in self.telechat_docs.iteritems(): + if d.type_id == "charter": + self.assertTrue(d.group.name in r.content, "%s not in response" % k) + self.assertTrue(d.group.acronym in r.content, "%s acronym not in response" % k) + else: + self.assertTrue(d.name in r.content, "%s not in response" % k) + self.assertTrue(d.title in r.content, "%s title not in response" % k) + self.assertTrue(json.loads(r.content)) + + def test_agenda(self): + r = self.client.get(urlreverse("ietf.iesg.views.agenda")) + self.assertEquals(r.status_code, 200) + + for k, d in self.telechat_docs.iteritems(): + self.assertTrue(d.name in r.content, "%s not in response" % k) + self.assertTrue(d.title in r.content, "%s title not in response" % k) + + def test_agenda_txt(self): + r = self.client.get(urlreverse("ietf.iesg.views.agenda_txt")) + self.assertEquals(r.status_code, 200) + + for k, d in self.telechat_docs.iteritems(): + if d.type_id == "charter": + self.assertTrue(d.group.name in r.content, "%s not in response" % k) + self.assertTrue(d.group.acronym in r.content, "%s acronym not in response" % k) + else: + self.assertTrue(d.name in r.content, "%s not in response" % k) + self.assertTrue(d.title in r.content, "%s title not in response" % k) + + def test_agenda_scribe_template(self): + r = self.client.get(urlreverse("ietf.iesg.views.agenda_scribe_template")) + self.assertEquals(r.status_code, 200) + + for k, d in self.telechat_docs.iteritems(): + if d.type_id == "charter": + continue # scribe template doesn't contain chartering info + + self.assertTrue(d.name in r.content, "%s not in response" % k) + self.assertTrue(d.title in r.content, "%s title not in response" % k) + + def test_agenda_moderator_package(self): + url = urlreverse("ietf.iesg.views.agenda_moderator_package") + login_testing_unauthorized(self, "secretary", url) + r = self.client.get(url) + self.assertEquals(r.status_code, 200) + + for k, d in self.telechat_docs.iteritems(): + if d.type_id == "charter": + self.assertTrue(d.group.name in r.content, "%s not in response" % k) + self.assertTrue(d.group.acronym in r.content, "%s acronym not in response" % k) + else: + self.assertTrue(d.name in r.content, "%s not in response" % k) + self.assertTrue(d.title in r.content, "%s title not in response" % k) + + def test_agenda_package(self): + url = urlreverse("ietf.iesg.views.agenda_package") + login_testing_unauthorized(self, "secretary", url) + r = self.client.get(url) + self.assertEquals(r.status_code, 200) + + for k, d in self.telechat_docs.iteritems(): + if d.type_id == "charter": + self.assertTrue(d.group.name in r.content, "%s not in response" % k) + self.assertTrue(d.group.acronym in r.content, "%s acronym not in response" % k) + else: + self.assertTrue(d.name in r.content, "%s not in response" % k) + self.assertTrue(d.title in r.content, "%s title not in response" % k) + + def test_agenda_documents_txt(self): + url = urlreverse("ietf.iesg.views.agenda_documents_txt") + r = self.client.get(url) + self.assertEquals(r.status_code, 200) + + for k, d in self.telechat_docs.iteritems(): + self.assertTrue(d.name in r.content, "%s not in response" % k) + + def test_agenda_documents(self): + url = urlreverse("ietf.iesg.views.agenda_documents") + r = self.client.get(url) + self.assertEquals(r.status_code, 200) + + for k, d in self.telechat_docs.iteritems(): + self.assertTrue(d.name in r.content, "%s not in response" % k) + self.assertTrue(d.title in r.content, "%s title not in response" % k) + + def test_agenda_telechat_docs(self): + d1 = self.telechat_docs["ietf_draft"] + d2 = self.telechat_docs["ise_draft"] + + d1_filename = "%s-%s.txt" % (d1.name, d1.rev) + d2_filename = "%s-%s.txt" % (d2.name, d2.rev) + + with open(os.path.join(self.draft_dir, d1_filename), "w") as f: + f.write("test content") + + url = urlreverse("ietf.iesg.views.telechat_docs_tarfile", kwargs=dict(date=get_agenda_date().isoformat())) + r = self.client.get(url) + self.assertEquals(r.status_code, 200) + + import tarfile, StringIO + + tar = tarfile.open(None, fileobj=StringIO.StringIO(r.content)) + names = tar.getnames() + self.assertTrue(d1_filename in names) + self.assertTrue(d2_filename not in names) + self.assertTrue("manifest.txt" in names) + + f = tar.extractfile(d1_filename) + self.assertEqual(f.read(), "test content") + + f = tar.extractfile("manifest.txt") + lines = list(f.readlines()) + self.assertTrue("Included" in [l for l in lines if d1_filename in l][0]) + self.assertTrue("Not found" in [l for l in lines if d2_filename in l][0]) + +class RescheduleOnAgendaTests(TestCase): def test_reschedule(self): - from ietf.utils.test_data import make_test_data - from ietf.person.models import Person - from ietf.doc.models import TelechatDocEvent - draft = make_test_data() # add to schedule @@ -94,10 +394,12 @@ class RescheduleOnAgendaTestCaseREDESIGN(TestCase): r = self.client.post(url, { '%s-telechat_date' % form_id: d.isoformat(), '%s-clear_returning_item' % form_id: "1" }) - self.assertEquals(r.status_code, 200) + self.assertEquals(r.status_code, 302) # check that it moved below the right header in the DOM on the # agenda docs page + r = self.client.get(url) + self.assertEquals(r.status_code, 200) d_header_pos = r.content.find("IESG telechat %s" % d.isoformat()) draft_pos = r.content.find(draft.name) self.assertTrue(d_header_pos < draft_pos) @@ -107,376 +409,7 @@ class RescheduleOnAgendaTestCaseREDESIGN(TestCase): self.assertTrue(not draft.latest_event(TelechatDocEvent, "scheduled_for_telechat").returning_item) self.assertEquals(draft.docevent_set.count(), events_before + 1) - -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - RescheduleOnAgendaTestCase = RescheduleOnAgendaTestCaseREDESIGN - -class ManageTelechatDatesTestCase(TestCase): - perma_fixtures = ['base', 'draft'] - - def test_set_dates(self): - dates = TelechatDates.objects.all()[0] - url = urlreverse('ietf.iesg.views.telechat_dates') - login_testing_unauthorized(self, "klm", url) - - # normal get - r = self.client.get(url) - self.assertEquals(r.status_code, 200) - q = PyQuery(r.content) - self.assertEquals(len(q('form input[name=date1]')), 1) - - # post - new_date = dates.date1 + timedelta(days=7) - - r = self.client.post(url, dict(date1=new_date.isoformat(), - date2=new_date.isoformat(), - date3=new_date.isoformat(), - date4=new_date.isoformat(), - )) - self.assertEquals(r.status_code, 200) - - dates = TelechatDates.objects.all()[0] - self.assertTrue(dates.date1 == new_date) - - def test_rollup_dates(self): - dates = TelechatDates.objects.all()[0] - url = urlreverse('ietf.iesg.views.telechat_dates') - login_testing_unauthorized(self, "klm", url) - - old_date2 = dates.date2 - new_date = dates.date4 + timedelta(days=14) - r = self.client.post(url, dict(rollup_dates="1")) - self.assertEquals(r.status_code, 200) - - dates = TelechatDates.objects.all()[0] - self.assertTrue(dates.date4 == new_date) - self.assertTrue(dates.date1 == old_date2) - -# class ManageTelechatDatesTestCaseREDESIGN(TestCase): -# perma_fixtures = ['names'] - -# def test_set_dates(self): -# from ietf.utils.test_data import make_test_data -# make_test_data() - -# dates = TelechatDates.objects.all()[0] -# url = urlreverse('ietf.iesg.views.telechat_dates') -# login_testing_unauthorized(self, "secretary", url) - -# # normal get -# r = self.client.get(url) -# self.assertEquals(r.status_code, 200) -# q = PyQuery(r.content) -# self.assertEquals(len(q('form input[name=date1]')), 1) - -# # post -# new_date = dates.date1 + timedelta(days=7) - -# r = self.client.post(url, dict(date1=new_date.isoformat(), -# date2=new_date.isoformat(), -# date3=new_date.isoformat(), -# date4=new_date.isoformat(), -# )) -# self.assertEquals(r.status_code, 200) - -# dates = TelechatDates.objects.all()[0] -# self.assertTrue(dates.date1 == new_date) - -# def test_rollup_dates(self): -# from ietf.utils.test_data import make_test_data -# make_test_data() - -# dates = TelechatDates.objects.all()[0] -# url = urlreverse('ietf.iesg.views.telechat_dates') -# login_testing_unauthorized(self, "secretary", url) - -# old_date2 = dates.date2 -# new_date = dates.date4 + timedelta(days=14) -# r = self.client.post(url, dict(rollup_dates="1")) -# self.assertEquals(r.status_code, 200) - -# dates = TelechatDates.objects.all()[0] -# self.assertTrue(dates.date4 == new_date) -# self.assertTrue(dates.date1 == old_date2) - -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - #ManageTelechatDatesTestCase = ManageTelechatDatesTestCaseREDESIGN - del ManageTelechatDatesTestCase - -class WorkingGroupActionsTestCase(TestCase): - perma_fixtures = ['base', 'wgactions'] - - def setUp(self): - super(self.__class__, self).setUp() - - curdir = os.path.dirname(os.path.abspath(__file__)) - self.evaldir = os.path.join(curdir, "testdir") - os.mkdir(self.evaldir) - - src = os.path.join(curdir, "fixtures", "sieve-charter.txt") - shutil.copy(src, self.evaldir) - - settings.IESG_WG_EVALUATION_DIR = self.evaldir - - def tearDown(self): - super(self.__class__, self).tearDown() - shutil.rmtree(self.evaldir) - - - def test_working_group_actions(self): - url = urlreverse('iesg_working_group_actions') - login_testing_unauthorized(self, "klm", url) - - r = self.client.get(url) - self.assertEquals(r.status_code, 200) - q = PyQuery(r.content) - for wga in WGAction.objects.all(): - self.assertTrue(wga.group_acronym.name in r.content) - - self.assertTrue('(sieve)' in r.content) - - def test_delete_wgaction(self): - wga = WGAction.objects.all()[0] - url = urlreverse('iesg_edit_working_group_action', kwargs=dict(wga_id=wga.pk)) - login_testing_unauthorized(self, "klm", url) - - r = self.client.post(url, dict(delete="1")) - self.assertEquals(r.status_code, 302) - self.assertTrue(not WGAction.objects.filter(pk=wga.pk)) - - def test_edit_wgaction(self): - wga = WGAction.objects.all()[0] - url = urlreverse('iesg_edit_working_group_action', kwargs=dict(wga_id=wga.pk)) - login_testing_unauthorized(self, "klm", url) - - # normal get - r = self.client.get(url) - self.assertEquals(r.status_code, 200) - q = PyQuery(r.content) - self.assertEquals(len(q('form select[name=token_name]')), 1) - self.assertEquals(len(q('form select[name=telechat_date]')), 1) - - # change - dates = TelechatDates.objects.all()[0] - token_name = IESGLogin.active_iesg().exclude(first_name=wga.token_name)[0].first_name - old = wga.pk - r = self.client.post(url, dict(status_date=dates.date1.isoformat(), - token_name=token_name, - category="23", - note="Testing.", - telechat_date=dates.date4.isoformat())) - self.assertEquals(r.status_code, 302) - - wga = WGAction.objects.get(pk=old) - self.assertEquals(wga.status_date, dates.date1) - self.assertEquals(wga.token_name, token_name) - self.assertEquals(wga.category, 23) - self.assertEquals(wga.note, "Testing.") - self.assertEquals(wga.telechat_date, dates.date4) - - def test_add_possible_wg(self): - url = urlreverse('iesg_working_group_actions') - login_testing_unauthorized(self, "klm", url) - - r = self.client.post(url, dict(add="1", - filename='sieve-charter.txt')) - self.assertEquals(r.status_code, 302) - - add_url = r['Location'] - r = self.client.get(add_url) - self.assertEquals(r.status_code, 200) - q = PyQuery(r.content) - self.assertTrue('(sieve)' in r.content) - self.assertEquals(len(q('form select[name=token_name]')), 1) - self.assertEquals(q('form input[name=status_date]')[0].get("value"), "2010-05-07") - self.assertEquals(len(q('form select[name=telechat_date]')), 1) - - wgas_before = WGAction.objects.all().count() - dates = TelechatDates.objects.all()[0] - token_name = IESGLogin.active_iesg()[0].first_name - r = self.client.post(add_url, - dict(status_date=dates.date1.isoformat(), - token_name=token_name, - category="23", - note="Testing.", - telechat_date=dates.date4.isoformat())) - self.assertEquals(r.status_code, 302) - self.assertEquals(wgas_before + 1, WGAction.objects.all().count()) - - def test_delete_possible_wg(self): - url = urlreverse('iesg_working_group_actions') - login_testing_unauthorized(self, "klm", url) - - r = self.client.post(url, dict(delete="1", - filename='sieve-charter.txt')) - self.assertEquals(r.status_code, 200) - - self.assertTrue('(sieve)' not in r.content) - -class WorkingGroupActionsTestCaseREDESIGN(TestCase): - perma_fixtures = ['names'] - - def setUp(self): - super(self.__class__, self).setUp() - - curdir = os.path.dirname(os.path.abspath(__file__)) - self.evaldir = os.path.join(curdir, "tmp-testdir") - os.mkdir(self.evaldir) - - src = os.path.join(curdir, "fixtures", "sieve-charter.txt") - shutil.copy(src, self.evaldir) - - settings.IESG_WG_EVALUATION_DIR = self.evaldir - - def tearDown(self): - super(self.__class__, self).tearDown() - shutil.rmtree(self.evaldir) - - - def test_working_group_actions(self): - from ietf.utils.test_data import make_test_data - - make_test_data() - - url = urlreverse('iesg_working_group_actions') - login_testing_unauthorized(self, "secretary", url) - - r = self.client.get(url) - self.assertEquals(r.status_code, 200) - q = PyQuery(r.content) - for wga in WGAction.objects.all(): - self.assertTrue(wga.group_acronym.name in r.content) - - self.assertTrue('(sieve)' in r.content) - - def test_delete_wgaction(self): - from ietf.utils.test_data import make_test_data - - make_test_data() - - wga = WGAction.objects.all()[0] - url = urlreverse('iesg_edit_working_group_action', kwargs=dict(wga_id=wga.pk)) - login_testing_unauthorized(self, "secretary", url) - - r = self.client.post(url, dict(delete="1")) - self.assertEquals(r.status_code, 302) - self.assertTrue(not WGAction.objects.filter(pk=wga.pk)) - - def test_edit_wgaction(self): - from ietf.utils.test_data import make_test_data - from ietf.person.models import Person - - make_test_data() - - wga = WGAction.objects.all()[0] - url = urlreverse('iesg_edit_working_group_action', kwargs=dict(wga_id=wga.pk)) - login_testing_unauthorized(self, "secretary", url) - - # normal get - r = self.client.get(url) - self.assertEquals(r.status_code, 200) - q = PyQuery(r.content) - self.assertEquals(len(q('form select[name=token_name]')), 1) - self.assertEquals(len(q('form select[name=telechat_date]')), 1) - - # change - dates = TelechatDate.objects.active() - token_name = Person.objects.get(name="Ad No1").plain_name() - old = wga.pk - r = self.client.post(url, dict(status_date=dates[0].date.isoformat(), - token_name=token_name, - category="23", - note="Testing.", - telechat_date=dates[3].date.isoformat())) - self.assertEquals(r.status_code, 302) - - wga = WGAction.objects.get(pk=old) - self.assertEquals(wga.status_date, dates[0].date) - self.assertEquals(wga.token_name, token_name) - self.assertEquals(wga.category, 23) - self.assertEquals(wga.note, "Testing.") - self.assertEquals(wga.telechat_date, dates[3].date) - - def test_add_possible_wg(self): - from ietf.utils.test_data import make_test_data - from ietf.person.models import Person - from ietf.group.models import Group - - make_test_data() - - url = urlreverse('iesg_working_group_actions') - login_testing_unauthorized(self, "secretary", url) - - r = self.client.post(url, dict(add="1", - filename='sieve-charter.txt')) - self.assertEquals(r.status_code, 302) - - # now we got back a URL we can use for adding, but first make - # sure we got a proposed group with the acronym - group = Group.objects.create( - name="Sieve test test", - acronym="sieve", - state_id="proposed", - type_id="wg", - parent=None - ) - - add_url = r['Location'] - r = self.client.get(add_url) - self.assertEquals(r.status_code, 200) - q = PyQuery(r.content) - self.assertTrue('(sieve)' in r.content) - self.assertEquals(len(q('form select[name=token_name]')), 1) - self.assertEquals(q('form input[name=status_date]')[0].get("value"), "2010-05-07") - self.assertEquals(len(q('form select[name=telechat_date]')), 1) - - wgas_before = WGAction.objects.all().count() - dates = TelechatDate.objects.active() - token_name = Person.objects.get(name="Ad No1").plain_name() - r = self.client.post(add_url, - dict(status_date=dates[0].date.isoformat(), - token_name=token_name, - category="23", - note="Testing.", - telechat_date=dates[3].date.isoformat())) - self.assertEquals(r.status_code, 302) - self.assertEquals(wgas_before + 1, WGAction.objects.all().count()) - - def test_delete_possible_wg(self): - from ietf.utils.test_data import make_test_data - - make_test_data() - - url = urlreverse('iesg_working_group_actions') - login_testing_unauthorized(self, "secretary", url) - - r = self.client.post(url, dict(delete="1", - filename='sieve-charter.txt')) - self.assertEquals(r.status_code, 200) - - self.assertTrue('(sieve)' not in r.content) - -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - WorkingGroupActionsTestCase = WorkingGroupActionsTestCaseREDESIGN - - -class IesgUrlTestCase(SimpleUrlTestCase): - def testUrls(self): - self.doTestUrls(__file__) - def doCanonicalize(self, url, content): - if url.startswith("/feed/"): - return canonicalize_feed(content) - else: - return content - -#Tests added since database redesign that speak the new clases - -from ietf.doc.models import Document,TelechatDocEvent,State -from ietf.group.models import Person class DeferUndeferTestCase(TestCase): - - perma_fixtures = ['names'] - def helper_test_defer(self,name): doc = Document.objects.get(name=name) @@ -571,5 +504,24 @@ class DeferUndeferTestCase(TestCase): # when charters support being deferred, be sure to test them here def setUp(self): - from ietf.utils.test_data import make_test_data make_test_data() + +class IESGDiscussesTests(TestCase): + def test_feed(self): + draft = make_test_data() + draft.set_state(State.objects.get(type="draft-iesg", slug="iesg-eva")) + + pos = BallotPositionDocEvent() + pos.ballot = draft.latest_event(BallotDocEvent, type="created_ballot") + pos.pos_id = "discuss" + pos.type = "changed_ballot_position" + pos.doc = draft + pos.ad = pos.by = Person.objects.get(user__username="ad") + pos.save() + + r = self.client.get(urlreverse("ietf.iesg.views.discusses")) + self.assertEquals(r.status_code, 200) + + self.assertTrue(draft.name in r.content) + self.assertTrue(pos.ad.plain_name() in r.content) + diff --git a/ietf/iesg/testurl.list b/ietf/iesg/testurl.list deleted file mode 100644 index 1f7734032..000000000 --- a/ietf/iesg/testurl.list +++ /dev/null @@ -1,24 +0,0 @@ - -301 /iesg/telechat/ -301 /iesg/telechat/y/2007/ -301 /iesg/telechat/y/2007/apr/ -301 /iesg/telechat/354/ - -200 /iesg/agenda/ -200 /iesg/agenda/agenda.txt -200 /iesg/agenda/scribe_template.html -200 /iesg/agenda/documents.txt -200 /iesg/agenda/documents/ -200 /iesg/discusses/ - -302 /iesg/agenda/moderator_package.html -302 /iesg/agenda/agenda_package.txt -200 /iesg/_test/moderator_package.html -200 /iesg/_test/agenda_package.txt - -200 /iesg/ann/ind/ -200 /iesg/ann/new/ -# This takes ~ 300s: -#200 /iesg/ann/prev/ - -200 /feed/iesg-agenda/ diff --git a/ietf/iesg/urls.py b/ietf/iesg/urls.py index aa6532e13..9f0fc6c86 100644 --- a/ietf/iesg/urls.py +++ b/ietf/iesg/urls.py @@ -35,41 +35,23 @@ from django.conf.urls.defaults import patterns, url from django.conf import settings from ietf.iesg import views -from ietf.idtracker.models import BallotInfo - -queryset_ann = BallotInfo.objects.all() urlpatterns = patterns('', - (r'^telechat/.*$', 'django.views.generic.simple.redirect_to', { 'url': 'http://www.ietf.org/iesg/minutes.html' }) -) + (r'^telechat/.*$', 'django.views.generic.simple.redirect_to', { 'url': 'http://www.ietf.org/iesg/minutes.html' }), + (r'^ann/(?:ind|new|prev)/$', 'django.views.generic.simple.redirect_to', { 'url': "/iesg/decisions/", 'permanent': True }), + (r'^telechatdates/$', 'django.views.generic.simple.redirect_to', { 'url': '/admin/iesg/telechatdate/' }), -urlpatterns += patterns('django.views.generic.list_detail', - (r'^ann/(?P\d+)/$', 'object_detail', { 'queryset': queryset_ann, 'template_name':"iesg/ballotinfo_detail.html" }), + (r'^decisions/(?:(?P[0-9]{4})/)?$', views.review_decisions), + (r'^agenda/(?:(?P\d{4}-\d{2}-\d{2})/)?$', views.agenda), + (r'^agenda/(?:(?P\d{4}-\d{2}-\d{2})/)?agenda.txt$', views.agenda_txt), + (r'^agenda/(?:(?P\d{4}-\d{2}-\d{2})/)?agenda.json$', views.agenda_json), + (r'^agenda/(?:(?P\d{4}-\d{2}-\d{2})/)?scribe_template.html$', views.agenda_scribe_template), + (r'^agenda/(?:(?P\d{4}-\d{2}-\d{2})/)?moderator_package.html$', views.agenda_moderator_package), + (r'^agenda/(?:(?P\d{4}-\d{2}-\d{2})/)?agenda_package.txt$', views.agenda_package), + + (r'^agenda/documents.txt$', views.agenda_documents_txt), + (r'^agenda/documents/$', views.agenda_documents), + (r'^agenda/telechat-(?:(?P\d{4}-\d{2}-\d{2})-)?docs.tgz', views.telechat_docs_tarfile), + (r'^discusses/$', views.discusses), + (r'^milestones/$', views.milestones_needing_review), ) - -urlpatterns += patterns('', - (r'^ann/ind/$',views.inddocs), - (r'^ann/(?P[^/]+)/$',views.wgdocs), - (r'^agenda/$', views.agenda), - (r'^agenda/agenda.txt$', views.agenda_txt), - (r'^agenda/agenda.json$', views.agenda_json), - (r'^agenda/scribe_template.html$', views.agenda_scribe_template), - (r'^agenda/moderator_package.html$', views.agenda_moderator_package), - (r'^agenda/agenda_package.txt$', views.agenda_package), - (r'^agenda/documents.txt$', views.agenda_documents_txt), - (r'^agenda/documents/$', views.agenda_documents), - (r'^agenda/telechat-(?P\d+)-(?P\d+)-(?P\d+)-docs.tgz', views.telechat_docs_tarfile), - (r'^discusses/$', views.discusses), - (r'^milestones', views.milestones_needing_review), - (r'^telechatdates/$', 'django.views.generic.simple.redirect_to', { 'url': '/admin/iesg/telechatdate/' }), - url(r'^wgactions/$', views.working_group_actions, name="iesg_working_group_actions"), - url(r'^wgactions/add/$', views.edit_working_group_action, { 'wga_id': None }, name="iesg_add_working_group_action"), - url(r'^wgactions/(?P\d+)/$', views.edit_working_group_action, name="iesg_edit_working_group_action"), -) - -if settings.SERVER_MODE != 'production': - urlpatterns += patterns('', - (r'^agenda/(?P\d{4}-\d\d-\d\d)/$', views.agenda), - (r'^_test/moderator_package.html$', views.agenda_moderator_package_test), - (r'^_test/agenda_package.txt', views.agenda_package_test), - ) diff --git a/ietf/iesg/views.py b/ietf/iesg/views.py index f534312d5..a241b03cf 100644 --- a/ietf/iesg/views.py +++ b/ietf/iesg/views.py @@ -32,466 +32,265 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -import codecs, re, os, glob -import datetime -import tarfile +import codecs, re, os, glob, datetime +import tarfile, StringIO, time +import itertools -from ietf.idtracker.models import IDInternal, InternetDraft, AreaGroup, Position, IESGLogin, Acronym -from django.views.generic.list_detail import object_list from django.views.generic.simple import direct_to_template -from django.views.decorators.vary import vary_on_cookie from django.core.urlresolvers import reverse as urlreverse from django.http import Http404, HttpResponse, HttpResponseForbidden, HttpResponseRedirect from django.template import RequestContext, Context, loader -from django.shortcuts import render_to_response, get_object_or_404 +from django.shortcuts import render_to_response, get_object_or_404, redirect from django.conf import settings from django.utils import simplejson as json +from django.db import models from django import forms -from ietf.iesg.models import TelechatDates, TelechatAgendaItem, WGAction -from ietf.idrfc.idrfc_wrapper import IdWrapper, RfcWrapper -from ietf.doc.utils import update_telechat -from ietf.ietfauth.decorators import group_required, role_required -from ietf.ietfauth.utils import has_role + +from ietf.iesg.models import TelechatDate, TelechatAgendaItem from ietf.ipr.models import IprDocAlias -from ietf.doc.models import Document, TelechatDocEvent, LastCallDocEvent, ConsensusDocEvent +from ietf.doc.models import Document, TelechatDocEvent, LastCallDocEvent, ConsensusDocEvent, DocEvent, IESG_BALLOT_ACTIVE_STATES from ietf.group.models import Group, GroupMilestone +from ietf.person.models import Person -def date_threshold(): - """Return the first day of the month that is 185 days ago.""" - ret = datetime.date.today() - datetime.timedelta(days=185) - ret = ret - datetime.timedelta(days=ret.day - 1) - return ret +from ietf.doc.utils import update_telechat, augment_events_with_revision +from ietf.ietfauth.utils import has_role, role_required, user_is_person +from ietf.iesg.agenda import * -def inddocs(request): - queryset_list_ind = [d for d in InternetDraft.objects.filter(stream__in=("IRTF","ISE"), docevent__type="iesg_approved").distinct() if d.latest_event(type__in=("iesg_disapproved", "iesg_approved")).type == "iesg_approved"] - queryset_list_ind.sort(key=lambda d: d.b_approve_date, reverse=True) +def review_decisions(request, year=None): + events = DocEvent.objects.filter(type__in=("iesg_disapproved", "iesg_approved")) - queryset_list_ind_dnp = [d for d in IDInternal.objects.filter(stream__in=("IRTF","ISE"), docevent__type="iesg_disapproved").distinct() if d.latest_event(type__in=("iesg_disapproved", "iesg_approved")).type == "iesg_disapproved"] - queryset_list_ind_dnp.sort(key=lambda d: d.dnp_date, reverse=True) + years = sorted((d.year for d in events.dates('time', 'year')), reverse=True) - return render_to_response('iesg/independent_doc.html', - dict(object_list=queryset_list_ind, - object_list_dnp=queryset_list_ind_dnp), - context_instance=RequestContext(request)) - - -def wgdocs(request,cat): - pass - -def wgdocsREDESIGN(request,cat): - is_recent = 0 - proto_actions = [] - doc_actions = [] - threshold = date_threshold() - - proto_levels = ["bcp", "ds", "ps", "std"] - doc_levels = ["exp", "inf"] - - if cat == 'new': - is_recent = 1 - - drafts = InternetDraft.objects.filter(docevent__type="iesg_approved", docevent__time__gte=threshold, intended_std_level__in=proto_levels + doc_levels).exclude(stream__in=("ISE","IRTF")).distinct() - for d in drafts: - if d.b_approve_date and d.b_approve_date >= threshold: - if d.intended_std_level_id in proto_levels: - proto_actions.append(d) - elif d.intended_std_level_id in doc_levels: - doc_actions.append(d) - - elif cat == 'prev': - # proto - start_date = datetime.date(1997, 12, 1) - - drafts = InternetDraft.objects.filter(docevent__type="iesg_approved", docevent__time__lt=threshold, docevent__time__gte=start_date, intended_std_level__in=proto_levels).exclude(stream__in=("ISE","IRTF")).distinct() - - for d in drafts: - if d.b_approve_date and start_date <= d.b_approve_date < threshold: - proto_actions.append(d) - - # doc - start_date = datetime.date(1998, 10, 15) - - drafts = InternetDraft.objects.filter(docevent__type="iesg_approved", docevent__time__lt=threshold, docevent__time__gte=start_date, intended_std_level__in=doc_levels).exclude(stream__in=("ISE","IRTF")).distinct() - - for d in drafts: - if d.b_approve_date and start_date <= d.b_approve_date < threshold: - doc_actions.append(d) + if year: + year = int(year) + events = events.filter(time__year=year) else: - raise Http404 + d = datetime.date.today() - datetime.timedelta(days=185) + d = datetime.date(d.year, d.month, 1) + events = events.filter(time__gte=d) - proto_actions.sort(key=lambda d: d.b_approve_date, reverse=True) - doc_actions.sort(key=lambda d: d.b_approve_date, reverse=True) - - return render_to_response('iesg/ietf_doc.html', - dict(object_list=proto_actions, - object_list_doc=doc_actions, - is_recent=is_recent, - title_prefix="Recent" if is_recent else "Previous"), + events = events.select_related("doc", "doc__intended_std_level").order_by("-time", "-id") + + #proto_levels = ["bcp", "ds", "ps", "std"] + #doc_levels = ["exp", "inf"] + + timeframe = u"%s" % year if year else u"the past 6 months" + + return render_to_response('iesg/review_decisions.html', + dict(events=events, + years=years, + year=year, + timeframe=timeframe), context_instance=RequestContext(request)) -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - wgdocs = wgdocsREDESIGN - +def agenda_json(request, date=None): + data = agenda_data(date) -def get_doc_section(id): - pass + res = { + "telechat-date": str(data["date"]), + "as-of": str(datetime.datetime.utcnow()), + "sections": {}, + } -def get_doc_sectionREDESIGN(doc): - if doc.type_id == 'draft': - if doc.intended_std_level_id in ["bcp", "ds", "ps", "std"]: - s = "2" - else: - s = "3" + for num, section in data["sections"].iteritems(): + s = res["sections"][num] = { + "title": section["title"], + } - g = doc.group_acronym() - if g and str(g) != 'none': - s = s + "1" - elif (s == "3") and doc.stream_id in ("ise","irtf"): - s = s + "3" - else: - s = s + "2" - if not doc.get_state_slug=="rfc" and doc.get_state_slug('draft-iesg') not in ("lc", "writeupw", "goaheadw", "iesg-eva", "defer"): - s = s + "3" - elif doc.returning_item(): - s = s + "2" - else: - s = s + "1" - elif doc.type_id == 'charter': - s = get_wg_section(doc.group) - elif doc.type_id == 'statchg': - protocol_action = False - for relation in doc.relateddocument_set.filter(relationship__slug__in=('tops','tois','tohist','toinf','tobcp','toexp')): - if relation.relationship.slug in ('tops','tois') or relation.target.document.std_level.slug in ('std','ds','ps'): - protocol_action = True - if protocol_action: - s="23" - else: - s="33" - if doc.get_state_slug() not in ("iesgeval", "defer", "appr-pr", "appr-pend", "appr-sent"): - s = s + "3" - elif doc.returning_item(): - s = s + "2" - else: - s = s + "1" - elif doc.type_id == 'conflrev': - if doc.get_state('conflrev').slug not in ('adrev','iesgeval','appr-reqnopub-pend','appr-reqnopub-sent','appr-noprob-pend','appr-noprob-sent','defer'): - s = "343" - elif doc.returning_item(): - s = "342" - else: - s = "341" - - return s - -def get_wg_section(wg): - s = "" - charter_slug = None - if wg.charter: - charter_slug = wg.charter.get_state_slug() - if wg.state_id in ['active','dormant']: - if charter_slug in ['extrev','iesgrev']: - s = '422' - else: - s = '421' - else: - if charter_slug in ['extrev','iesgrev']: - s = '412' - else: - s = '411' - return s - -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - get_doc_section = get_doc_sectionREDESIGN - -def agenda_docs(date, next_agenda): - matches = Document.objects.filter(docevent__telechatdocevent__telechat_date=date).select_related("stream").distinct() - - docmatches = [] - - for doc in matches: - if doc.latest_event(TelechatDocEvent, type="scheduled_for_telechat").telechat_date != date: + if "docs" not in section: continue - e = doc.latest_event(type="started_iesg_process") - doc.balloting_started = e.time if e else datetime.datetime.min + docs = section["docs"] - if doc.type_id == "draft": - s = doc.get_state("draft-iana-review") - if s: # and s.slug in ("not-ok", "changed", "need-rev"): - doc.iana_review_state = str(s) + if "4" <= num < "5": + # charters + s["wgs"] = [] - if doc.get_state_slug("draft-iesg") == "lc": - e = doc.latest_event(LastCallDocEvent, type="sent_last_call") - if e: - doc.lastcall_expires = e.expires + for doc in docs: + wginfo = { + 'docname': doc.canonical_name(), + 'rev': doc.rev, + 'wgname': doc.group.name, + 'acronym': doc.group.acronym, + 'ad': doc.group.ad.name if doc.group.ad else None, + } - if doc.stream_id in ("ietf", "irtf", "iab"): - doc.consensus = "Unknown" - e = doc.latest_event(ConsensusDocEvent, type="changed_consensus") - if e: - doc.consensus = "Yes" if e.consensus else "No" - elif doc.type_id=='conflrev': - doc.conflictdoc = doc.relateddocument_set.get(relationship__slug='conflrev').target.document + # consider moving the charters to "docs" like the other documents + s['wgs'].append(wginfo) + else: + # other documents + s["docs"] = [] - docmatches.append(doc) + for doc in docs: + docinfo = { + 'docname':doc.canonical_name(), + 'title':doc.title, + 'ad':doc.ad.name if doc.ad else None, + } - # Be careful to keep this the same as what's used in agenda_documents - docmatches.sort(key=lambda d: d.balloting_started) - - res = dict(("s%s%s%s" % (i, j, k), []) for i in range(2, 5) for j in range (1, 4) for k in range(1, 4)) - for k in range(1,4): - res['s34%d'%k]=[] - for id in docmatches: - section_key = "s"+get_doc_section(id) - if section_key not in res: - res[section_key] = [] - res[section_key].append({'obj':id}) - return res + if doc.note: + docinfo['note'] = doc.note + defer = doc.active_defer_event() + if defer: + docinfo['defer-by'] = defer.by.name + docinfo['defer-at'] = str(defer.time) + if doc.type_id == "draft": + docinfo['rev'] = doc.rev + docinfo['intended-std-level'] = str(doc.intended_std_level) + if doc.rfc_number(): + docinfo['rfc-number'] = doc.rfc_number() -def agenda_wg_actions(date): - res = dict(("s%s%s%s" % (i, j, k), []) for i in range(2, 5) for j in range (1, 4) for k in range(1, 4)) - charters = Document.objects.filter(type="charter", docevent__telechatdocevent__telechat_date=date).select_related("group").distinct() - charters = charters.filter(group__state__slug__in=["proposed","active"]) - for c in charters: - if c.latest_event(TelechatDocEvent, type="scheduled_for_telechat").telechat_date != date: - continue + iana_state = doc.get_state("draft-iana-review") + if iana_state and iana_state.slug in ("not-ok", "changed", "need-rev"): + docinfo['iana-review-state'] = str(iana_state) - c.group.txt_link = settings.CHARTER_TXT_URL + "%s-%s.txt" % (c.canonical_name(), c.rev) + if doc.get_state_slug("draft-iesg") == "lc": + e = doc.latest_event(LastCallDocEvent, type="sent_last_call") + if e: + docinfo['lastcall-expires'] = e.expires.strftime("%Y-%m-%d") - section_key = "s" + get_wg_section(c.group) - if section_key not in res: - res[section_key] = [] - # Cleanup - Older view code wants obj, newer wants doc. Older code should be moved forward - res[section_key].append({'obj': c.group, 'doc': c}) - return res + docinfo['consensus'] = None + e = doc.latest_event(ConsensusDocEvent, type="changed_consensus") + if e: + docinfo['consensus'] = e.consensus + elif doc.type_id == 'conflrev': + docinfo['rev'] = doc.rev + td = doc.relateddocument_set.get(relationship__slug='conflrev').target.document + docinfo['target-docname'] = td.canonical_name() + docinfo['target-title'] = td.title + docinfo['target-rev'] = td.rev + docinfo['intended-std-level'] = str(td.intended_std_level) + docinfo['stream'] = str(td.stream) + else: + # XXX check this -- is there nothing to set for + # all other documents here? + pass -def agenda_management_issues(date): - return TelechatAgendaItem.objects.filter(type=3).order_by('id') + s["docs"].append(docinfo) -def _agenda_json(request, date=None): - if not date: - date = TelechatDates.objects.all()[0].date1 - next_agenda = True - else: - y,m,d = date.split("-") - date = datetime.date(int(y), int(m), int(d)) - next_agenda = None + return HttpResponse(json.dumps(res, indent=2), mimetype='text/plain') - data = {'telechat-date':str(date), - 'as-of':str(datetime.datetime.utcnow()), - 'sections':{}} - data['sections']['1'] = {'title':"Administrivia"} - data['sections']['1.1'] = {'title':"Roll Call"} - data['sections']['1.2'] = {'title':"Bash the Agenda"} - data['sections']['1.3'] = {'title':"Approval of the Minutes of Past Telechats"} - data['sections']['1.4'] = {'title':"List of Remaining Action Items from Last Telechat"} - data['sections']['2'] = {'title':"Protocol Actions"} - data['sections']['2.1'] = {'title':"WG Submissions"} - data['sections']['2.1.1'] = {'title':"New Items", 'docs':[]} - data['sections']['2.1.2'] = {'title':"Returning Items", 'docs':[]} - data['sections']['2.2'] = {'title':"Individual Submissions"} - data['sections']['2.2.1'] = {'title':"New Items", 'docs':[]} - data['sections']['2.2.2'] = {'title':"Returning Items", 'docs':[]} - data['sections']['2.3'] = {'title':"Individual Submissions"} - data['sections']['2.3.1'] = {'title':"New Items", 'docs':[]} - data['sections']['2.3.2'] = {'title':"Returning Items", 'docs':[]} - data['sections']['3'] = {'title':"Document Actions"} - data['sections']['3.1'] = {'title':"WG Submissions"} - data['sections']['3.1.1'] = {'title':"New Items", 'docs':[]} - data['sections']['3.1.2'] = {'title':"Returning Items", 'docs':[]} - data['sections']['3.2'] = {'title':"Individual Submissions Via AD"} - data['sections']['3.2.1'] = {'title':"New Items", 'docs':[]} - data['sections']['3.2.2'] = {'title':"Returning Items", 'docs':[]} - data['sections']['3.3'] = {'title':"Status Changes"} - data['sections']['3.3.1'] = {'title':"New Items", 'docs':[]} - data['sections']['3.3.2'] = {'title':"Returning Items", 'docs':[]} - data['sections']['3.4'] = {'title':"IRTF and Independent Submission Stream Documents"} - data['sections']['3.4.1'] = {'title':"New Items", 'docs':[]} - data['sections']['3.4.2'] = {'title':"Returning Items", 'docs':[]} - data['sections']['4'] = {'title':"Working Group Actions"} - data['sections']['4.1'] = {'title':"WG Creation"} - data['sections']['4.1.1'] = {'title':"Proposed for IETF Review", 'wgs':[]} - data['sections']['4.1.2'] = {'title':"Proposed for Approval", 'wgs':[]} - data['sections']['4.2'] = {'title':"WG Rechartering"} - data['sections']['4.2.1'] = {'title':"Under Evaluation for IETF Review", 'wgs':[]} - data['sections']['4.2.2'] = {'title':"Proposed for Approval", 'wgs':[]} - data['sections']['5'] = {'title':"IAB News We Can Use"} - data['sections']['6'] = {'title':"Management Issues"} - data['sections']['7'] = {'title':"Working Group News"} - - docs = agenda_docs(date, next_agenda) - for section in docs.keys(): - # in case the document is in a state that does not have an agenda section - if section != 's': - s = str(".".join(list(section)[1:])) - if s[0:1] == '4': - # ignore these; not sure why they are included by agenda_docs - pass - else: - if len(docs[section]) != 0: - # If needed, add a "For Action" section to agenda - if s[4:5] == '3': - data['sections'][s] = {'title':"For Action", 'docs':[]} - - for obj in docs[section]: - d = obj['obj'] - docinfo = {'docname':d.canonical_name(), - 'title':d.title, - 'ad':d.ad.name} - if d.note: - docinfo['note'] = d.note - defer = d.active_defer_event() - if defer: - docinfo['defer-by'] = defer.by.name - docinfo['defer-at'] = str(defer.time) - if d.type_id == "draft": - docinfo['rev'] = d.rev - docinfo['intended-std-level'] = str(d.intended_std_level) - if d.rfc_number(): - docinfo['rfc-number'] = d.rfc_number() - - iana_state = d.get_state("draft-iana-review") - if iana_state and iana_state.slug in ("not-ok", "changed", "need-rev"): - docinfo['iana-review-state'] = str(iana_state) - - if d.get_state_slug("draft-iesg") == "lc": - e = d.latest_event(LastCallDocEvent, type="sent_last_call") - if e: - docinfo['lastcall-expires'] = e.expires.strftime("%Y-%m-%d") - - docinfo['consensus'] = None - e = d.latest_event(ConsensusDocEvent, type="changed_consensus") - if e: - docinfo['consensus'] = e.consensus - elif d.type_id == 'conflrev': - docinfo['rev'] = d.rev - td = d.relateddocument_set.get(relationship__slug='conflrev').target.document - docinfo['target-docname'] = td.canonical_name() - docinfo['target-title'] = td.title - docinfo['target-rev'] = td.rev - docinfo['intended-std-level'] = str(td.intended_std_level) - docinfo['stream'] = str(td.stream) - else: - # XXX check this -- is there nothing to set for - # all other documents here? - pass - data['sections'][s]['docs'] += [docinfo, ] - - wgs = agenda_wg_actions(date) - for section in wgs.keys(): - # in case the charter is in a state that does not have an agenda section - if section != 's': - s = str(".".join(list(section)[1:])) - if s[0:1] != '4': - # ignore these; not sure why they are included by agenda_wg_actions - pass - else: - if len(wgs[section]) != 0: - for obj in wgs[section]: - wg = obj['obj'] - doc = obj['doc'] - wginfo = {'docname': doc.canonical_name(), - 'rev': doc.rev, - 'wgname': doc.group.name, - 'acronym': doc.group.acronym, - 'ad': doc.group.ad.name} - data['sections'][s]['wgs'] += [wginfo, ] - - mgmt = agenda_management_issues(date) - num = 0 - for m in mgmt: - num += 1 - data['sections']["6.%d" % num] = {'title':m.title} - - return data - -def _agenda_data(request, date=None): - if not date: - date = TelechatDates.objects.all()[0].date1 - next_agenda = True - else: - y,m,d = date.split("-") - date = datetime.date(int(y), int(m), int(d)) - next_agenda = None - #date = "2006-03-16" - docs = agenda_docs(date, next_agenda) - mgmt = agenda_management_issues(date) - wgs = agenda_wg_actions(date) - data = {'date':str(date), 'docs':docs,'mgmt':mgmt,'wgs':wgs} - for key, filename in {'action_items':settings.IESG_TASK_FILE, - 'roll_call':settings.IESG_ROLL_CALL_FILE, - 'minutes':settings.IESG_MINUTES_FILE}.items(): - try: - f = codecs.open(filename, 'r', 'utf-8', 'replace') - text = f.read().strip() - f.close() - data[key] = text - except IOError: - data[key] = "(Error reading "+key+")" - return data - -@vary_on_cookie def agenda(request, date=None): - data = _agenda_data(request, date) - data['private'] = 'private' in request.REQUEST - data['settings'] = settings - return render_to_response("iesg/agenda.html", data, context_instance=RequestContext(request)) + data = agenda_data(date) -def agenda_txt(request): - data = _agenda_data(request) - return render_to_response("iesg/agenda.txt", data, context_instance=RequestContext(request), mimetype="text/plain") + if has_role(request.user, ["Area Director", "IAB Chair", "Secretariat"]): + data["sections"]["1.1"]["title"] = data["sections"]["1.1"]["title"].replace("Roll Call", 'Roll Call') + data["sections"]["1.3"]["title"] = data["sections"]["1.3"]["title"].replace("Minutes", 'Minutes') -def agenda_json(request): - response = HttpResponse(mimetype='text/plain') - response.write(json.dumps(_agenda_json(request), indent=2)) - return response + return render_to_response("iesg/agenda.html", { + "date": data["date"], + "sections": sorted(data["sections"].iteritems()), + "settings": settings, + }, context_instance=RequestContext(request)) -def agenda_scribe_template(request): - date = TelechatDates.objects.all()[0].date1 - docs = agenda_docs(date, True) - return render_to_response('iesg/scribe_template.html', {'date':str(date), 'docs':docs, 'USE_DB_REDESIGN_PROXY_CLASSES': settings.USE_DB_REDESIGN_PROXY_CLASSES}, context_instance=RequestContext(request) ) +def agenda_txt(request, date=None): + data = agenda_data(date) + return render_to_response("iesg/agenda.txt", { + "date": data["date"], + "sections": sorted(data["sections"].iteritems()), + }, context_instance=RequestContext(request), mimetype="text/plain") -def _agenda_moderator_package(request): - data = _agenda_data(request) - data['ad_names'] = [str(x) for x in IESGLogin.active_iesg()] - data['ad_names'].sort(key=lambda x: x.split(' ')[-1]) - return render_to_response("iesg/moderator_package.html", data, context_instance=RequestContext(request)) +def agenda_scribe_template(request, date=None): + data = agenda_data(date) + sections = sorted((num, section) for num, section in data["sections"].iteritems() if "2" <= num < "4") + appendix_docs = [] + for num, section in sections: + if "docs" in section: + # why are we here including documents that have no discuss/comment? + appendix_docs.extend(section["docs"]) + return render_to_response("iesg/scribe_template.html", { + "date": data["date"], + "sections": sections, + "appendix_docs": appendix_docs, + }, context_instance=RequestContext(request) ) -@group_required('Area_Director','Secretariat') -def agenda_moderator_package(request): - return _agenda_moderator_package(request) +@role_required('Area Director', 'Secretariat') +def agenda_moderator_package(request, date=None): + """Output telechat agenda with one page per section, with each + document in its own section.""" + data = agenda_data(date) -def agenda_moderator_package_test(request): - if request.META['REMOTE_ADDR'] == "127.0.0.1": - return _agenda_moderator_package(request) - else: - return HttpResponseForbidden() + def leaf_section(num, section): + return not (num == "1" + or "2" <= num < "5" and "docs" not in section + or (num == "6" and "6.1" not in data["sections"])) -def _agenda_package(request): - data = _agenda_data(request) - return render_to_response("iesg/agenda_package.txt", data, context_instance=RequestContext(request), mimetype='text/plain') + # sort and prune non-leaf headlines + sections = sorted((num, section) for num, section in data["sections"].iteritems() + if leaf_section(num, section)) -@group_required('Area_Director','Secretariat') -def agenda_package(request): - return _agenda_package(request) + # add parents field to each section + for num, s in sections: + s["parents"] = [] + split = num.split(".") + + for i in xrange(num.count(".")): + parent_num = ".".join(split[:i + 1]) + parent = data["sections"].get(parent_num) + if parent: + s["parents"].append((parent_num, parent)) + + + # put each document in its own section + flattened_sections = [] + for num, s in sections: + if "2" <= num < "5" and "docs" in s and s["docs"]: + for i, d in enumerate(s["docs"], start=1): + flattened_sections.append((num, { + "title": s["title"] + " (%s of %s)" % (i, len(s["docs"])), + "doc": d, + "parents": s["parents"], + })) + else: + flattened_sections.append((num, s)) + + # add ads + data["sections"]["7"]["ads"] = sorted(Person.objects.filter(role__name="ad", role__group__state="active"), + key=lambda p: p.name_parts()[3]) + + return render_to_response("iesg/moderator_package.html", { + "date": data["date"], + "sections": flattened_sections, + }, context_instance=RequestContext(request)) + +@role_required('Area Director', 'Secretariat') +def agenda_package(request, date=None): + data = agenda_data(date) + return render_to_response("iesg/agenda_package.txt", { + "date": data["date"], + "sections": sorted(data["sections"].iteritems()), + "roll_call": data["sections"]["1.1"]["text"], + "minutes": data["sections"]["1.3"]["text"], + "management_items": [(num, section) for num, section in data["sections"].iteritems() if "6" < num < "7"], + }, context_instance=RequestContext(request), mimetype='text/plain') -def agenda_package_test(request): - if request.META['REMOTE_ADDR'] == "127.0.0.1": - return _agenda_package(request) - else: - return HttpResponseForbidden() def agenda_documents_txt(request): - dates = TelechatDates.objects.all()[0].dates() + dates = list(TelechatDate.objects.active().order_by('date').values_list("date", flat=True)[:4]) + docs = [] - for date in dates: - from ietf.doc.models import TelechatDocEvent - for d in Document.objects.filter(docevent__telechatdocevent__telechat_date=date).distinct(): - if d.latest_event(TelechatDocEvent, type="scheduled_for_telechat").telechat_date == date: - docs.append(d) - t = loader.get_template('iesg/agenda_documents.txt') - c = Context({'docs':docs,'special_stream_list':['ise','irtf']}) - return HttpResponse(t.render(c), mimetype='text/plain') + for d in Document.objects.filter(docevent__telechatdocevent__telechat_date__in=dates).distinct(): + date = d.telechat_date() + if date in dates: + d.computed_telechat_date = date + docs.append(d) + docs.sort(key=lambda d: d.computed_telechat_date) + + # output table + rows = [] + rows.append("# Fields: telechat date, filename (draft-foo-bar or rfc1234), intended status, rfc editor submission flag (0=no, 1=yes), area acronym, AD name, version") + for d in docs: + row = ( + d.computed_telechat_date.isoformat(), + d.name, + unicode(d.intended_std_level), + "1" if d.stream_id in ("ise", "irtf") else "0", + unicode(d.area_acronym()).lower(), + d.ad.plain_name() if d.ad else "None Assigned", + d.rev, + ) + rows.append("\t".join(row)) + return HttpResponse(u"\n".join(rows), mimetype='text/plain') class RescheduleForm(forms.Form): telechat_date = forms.TypedChoiceField(coerce=lambda x: datetime.datetime.strptime(x, '%Y-%m-%d').date(), empty_value=None, required=False) @@ -513,7 +312,7 @@ class RescheduleForm(forms.Form): self.fields['telechat_date'].choices = choices -def handle_reschedule_form(request, doc, dates): +def handle_reschedule_form(request, doc, dates, status): initial = dict(telechat_date=doc.telechat_date()) formargs = dict(telechat_dates=dates, @@ -522,12 +321,13 @@ def handle_reschedule_form(request, doc, dates): if request.method == 'POST': form = RescheduleForm(request.POST, **formargs) if form.is_valid(): - login = request.user.get_profile() - update_telechat(request, doc, login, + update_telechat(request, doc, request.user.get_profile(), form.cleaned_data['telechat_date'], False if form.cleaned_data['clear_returning_item'] else None) doc.time = datetime.datetime.now() doc.save() + + status["changed"] = True else: form = RescheduleForm(**formargs) @@ -535,100 +335,111 @@ def handle_reschedule_form(request, doc, dates): return form def agenda_documents(request): - dates = TelechatDates.objects.all()[0].dates() - from ietf.doc.models import TelechatDocEvent - docs = [] - for d in Document.objects.filter(docevent__telechatdocevent__telechat_date__in=dates).distinct(): - if d.latest_event(TelechatDocEvent, type="scheduled_for_telechat").telechat_date in dates: - docs.append(d) + dates = list(TelechatDate.objects.active().order_by('date').values_list("date", flat=True)[:4]) - e = d.latest_event(type="started_iesg_process") - d.balloting_started = e.time if e else datetime.datetime.min - docs.sort(key=lambda d: d.balloting_started) - for i in docs: - i.reschedule_form = handle_reschedule_form(request, i, dates) + docs_by_date = dict((d, []) for d in dates) + for doc in Document.objects.filter(docevent__telechatdocevent__telechat_date__in=dates).select_related("stream", "group").distinct(): + d = doc.latest_event(TelechatDocEvent, type="scheduled_for_telechat").telechat_date + if d in docs_by_date: + docs_by_date[d].append(doc) - # some may have been taken off the schedule by the reschedule form - docs = [d for d in docs if d.telechat_date()] + reschedule_status = { "changed": False } + + for i in itertools.chain(*docs_by_date.values()): + i.reschedule_form = handle_reschedule_form(request, i, dates, reschedule_status) + + if reschedule_status["changed"]: + # if any were changed, redirect so the browser history is preserved + return redirect("ietf.iesg.views.agenda_documents") telechats = [] for date in dates: - matches = filter(lambda x: x.telechat_date() == date, docs) - res = {} - for i in matches: - section_key = "s" + get_doc_section(i) - if section_key not in res: - res[section_key] = [] - if i.type_id=='draft': - if i.get_state_slug()!="rfc": - i.iprUrl = "/ipr/search?option=document_search&id_document_tag=" + str(i.name) - else: - i.iprUrl = "/ipr/search?option=rfc_search&rfc_search=" + str(i.rfc_number()) - i.iprCount = len(i.ipr()) - res[section_key].append(i) - telechats.append({'date':date, 'docs':res}) - return direct_to_template(request, 'iesg/agenda_documents_redesign.html', {'telechats':telechats, 'hide_telechat_date':True}) + sections = agenda_sections() + fill_in_agenda_docs(date, sections, docs_by_date[d]) + + telechats.append({ + "date":date, + "sections": sorted((num, section) for num, section in sections.iteritems() + if "2" <= num < "5") + }) + return direct_to_template(request, 'iesg/agenda_documents.html', { 'telechats':telechats }) + +def telechat_docs_tarfile(request, date): + date = get_agenda_date(date) + + docs = [] + for d in Document.objects.filter(docevent__telechatdocevent__telechat_date=date).distinct(): + if d.latest_event(TelechatDocEvent, type="scheduled_for_telechat").telechat_date == date: + docs.append(d) -def telechat_docs_tarfile(request,year,month,day): - from tempfile import mkstemp - date=datetime.date(int(year),int(month),int(day)) - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - from ietf.doc.models import TelechatDocEvent - docs = [] - for d in IDInternal.objects.filter(docevent__telechatdocevent__telechat_date=date).distinct(): - if d.latest_event(TelechatDocEvent, type="scheduled_for_telechat").telechat_date == date: - docs.append(d) - else: - docs= IDInternal.objects.filter(telechat_date=date, primary_flag=1, agenda=1) response = HttpResponse(mimetype='application/octet-stream') - response['Content-Disposition'] = 'attachment; filename=telechat-%s-%s-%s-docs.tgz'%(year, month, day) - tarstream = tarfile.open('','w:gz',response) - mfh, mfn = mkstemp() - manifest = open(mfn, "w") + response['Content-Disposition'] = 'attachment; filename=telechat-%s-docs.tgz' % date.isoformat() + + tarstream = tarfile.open('', 'w:gz', response) + + manifest = StringIO.StringIO() + for doc in docs: - doc_path = os.path.join(settings.INTERNET_DRAFT_PATH, doc.draft.filename+"-"+doc.draft.revision_display()+".txt") + doc_path = os.path.join(doc.get_file_path(), doc.name + "-" + doc.rev + ".txt") if os.path.exists(doc_path): try: - tarstream.add(doc_path, str(doc.draft.filename+"-"+doc.draft.revision_display()+".txt")) - manifest.write("Included: "+doc_path+"\n") - except Exception, e: - manifest.write(("Failed (%s): "%e)+doc_path+"\n") + tarstream.add(doc_path, str(doc.name + "-" + doc.rev + ".txt")) + manifest.write("Included: %s\n" % doc_path) + except Exception as e: + manifest.write("Failed (%s): %s\n" % (e, doc_path)) else: - manifest.write("Not found: "+doc_path+"\n") - manifest.close() - tarstream.add(mfn, "manifest.txt") + manifest.write("Not found: %s\n" % doc_path) + + manifest.seek(0) + t = tarfile.TarInfo(name="manifest.txt") + t.size = len(manifest.buf) + t.mtime = time.time() + tarstream.addfile(t, manifest) + tarstream.close() - os.unlink(mfn) + return response def discusses(request): - res = [] + possible_docs = Document.objects.filter(models.Q(states__type="draft-iesg", + states__slug__in=IESG_BALLOT_ACTIVE_STATES) | + models.Q(states__type="charter", + states__slug__in=("intrev", "iesgrev")) | + models.Q(states__type__in=("statchg", "conflrev"), + states__slug__in=("iesgeval", "defer")), + docevent__ballotpositiondocevent__pos__blocking=True) + possible_docs = possible_docs.select_related("stream", "group", "ad").distinct() - for d in IDInternal.objects.filter(states__type="draft-iesg", states__slug__in=("pub-req", "ad-eval", "review-e", "lc-req", "lc", "writeupw", "goaheadw", "iesg-eva", "defer", "watching"), docevent__ballotpositiondocevent__pos="discuss").distinct(): - found = False - for p in d.positions.all(): - if p.discuss: - found = True - break - - if not found: + docs = [] + for doc in possible_docs: + ballot = doc.active_ballot() + if not ballot: continue - if d.rfc_flag: - doc = RfcWrapper(d) - else: - doc = IdWrapper(draft=d) + blocking_positions = [p for p in ballot.all_positions() if p.pos.blocking] - if doc.in_ietf_process() and doc.ietf_process.has_active_iesg_ballot(): - res.append(doc) + if not blocking_positions: + continue - return direct_to_template(request, 'iesg/discusses.html', {'docs':res}) + augment_events_with_revision(doc, blocking_positions) + + doc.by_me = bool([p for p in blocking_positions if user_is_person(request.user, p.ad)]) + doc.for_me = user_is_person(request.user, doc.ad) + doc.milestones = doc.groupmilestone_set.filter(state="active").order_by("time").select_related("group") + doc.blocking_positions = blocking_positions + + docs.append(doc) + + # latest first + docs.sort(key=lambda d: min(p.time for p in d.blocking_positions), reverse=True) + + return direct_to_template(request, 'iesg/discusses.html', { 'docs': docs }) @role_required('Area Director', 'Secretariat') def milestones_needing_review(request): # collect milestones, grouped on AD and group ads = {} - for m in GroupMilestone.objects.filter(state="review").exclude(group__state="concluded", group__ad=None).distinct().select_related("group", "group__ad"): + for m in GroupMilestone.objects.filter(state="review").exclude(group__state="concluded").exclude(group__ad=None).distinct().select_related("group", "group__ad"): groups = ads.setdefault(m.group.ad, {}) milestones = groups.setdefault(m.group, []) milestones.append(m) @@ -645,162 +456,3 @@ def milestones_needing_review(request): ), context_instance=RequestContext(request)) -def parse_wg_action_file(path): - f = open(path, 'rU') - - line = f.readline() - while line and not line.strip(): - line = f.readline() - - # name - m = re.search(r'([^\(]*) \(', line) - if not m: - return None - name = m.group(1) - - # acronym - m = re.search(r'\((\w+)\)', line) - if not m: - return None - acronym = m.group(1) - - # date - line = f.readline() - m = re.search(r'(\d{4})-(\d{2})-(\d{2})', line) - while line and not m: - line = f.readline() - m = re.search(r'(\d{4})-(\d{2})-(\d{2})', line) - - last_updated = None - if m: - try: - last_updated = datetime.date(int(m.group(1)), int(m.group(2)), int(m.group(3))) - except: - pass - - # token - line = f.readline() - while line and not 'area director' in line.lower(): - line = f.readline() - - line = f.readline() - line = f.readline() - m = re.search(r'\s*(\w+)\s*', line) - token = "" - if m: - token = m.group(1) - - return dict(filename=os.path.basename(path), name=name, acronym=acronym, - status_date=last_updated, token=token) - -def get_possible_wg_actions(): - res = [] - charters = glob.glob(os.path.join(settings.IESG_WG_EVALUATION_DIR, '*-charter.txt')) - for path in charters: - d = parse_wg_action_file(path) - if d: - if not d['status_date']: - d['status_date'] = datetime.date(1900,1,1) - res.append(d) - - res.sort(key=lambda x: x['status_date']) - - return res - - -@group_required('Area_Director', 'Secretariat') -def working_group_actions(request): - current_items = WGAction.objects.order_by('status_date').select_related() - - if request.method == 'POST' and has_role(request.user, 'Secretariat'): - filename = request.POST.get('filename') - if filename and filename in os.listdir(settings.IESG_WG_EVALUATION_DIR): - if 'delete' in request.POST: - os.unlink(os.path.join(settings.IESG_WG_EVALUATION_DIR, filename)) - if 'add' in request.POST: - d = parse_wg_action_file(os.path.join(settings.IESG_WG_EVALUATION_DIR, filename)) - qstr = "?" + "&".join("%s=%s" % t for t in d.iteritems()) - return HttpResponseRedirect(urlreverse('iesg_add_working_group_action') + qstr) - - - skip = [c.group_acronym.acronym for c in current_items] - possible_items = filter(lambda x: x['acronym'] not in skip, - get_possible_wg_actions()) - - return render_to_response("iesg/working_group_actions.html", - dict(current_items=current_items, - possible_items=possible_items), - context_instance=RequestContext(request)) - -class EditWGActionForm(forms.ModelForm): - token_name = forms.ChoiceField(required=True) - telechat_date = forms.TypedChoiceField(coerce=lambda x: datetime.datetime.strptime(x, '%Y-%m-%d').date(), empty_value=None, required=False) - - class Meta: - model = WGAction - fields = ['status_date', 'token_name', 'category', 'note'] - - def __init__(self, *args, **kwargs): - super(self.__class__, self).__init__(*args, **kwargs) - - # token name choices - self.fields['token_name'].choices = [("", "(None)")] + [(p.plain_name(), p.plain_name()) for p in IESGLogin.active_iesg().order_by('first_name')] - - # telechat choices - dates = TelechatDates.objects.all()[0].dates() - init = kwargs['initial']['telechat_date'] - if init and init not in dates: - dates.insert(0, init) - - choices = [("", "(not on agenda)")] - for d in dates: - choices.append((d, d.strftime("%Y-%m-%d"))) - - self.fields['telechat_date'].choices = choices - - -@group_required('Secretariat') -def edit_working_group_action(request, wga_id): - if wga_id != None: - wga = get_object_or_404(WGAction, pk=wga_id) - else: - wga = WGAction() - try: - wga.group_acronym = Acronym.objects.get(acronym=request.GET.get('acronym')) - except Acronym.DoesNotExist: - pass - - wga.token_name = request.GET.get('token') - try: - d = datetime.datetime.strptime(request.GET.get('status_date'), '%Y-%m-%d').date() - except: - d = datetime.date.today() - wga.status_date = d - wga.telechat_date = TelechatDates.objects.all()[0].date1 - wga.agenda = True - - initial = dict(telechat_date=wga.telechat_date if wga.agenda else None) - - if request.method == 'POST': - if "delete" in request.POST: - wga.delete() - return HttpResponseRedirect(urlreverse('iesg_working_group_actions')) - - form = EditWGActionForm(request.POST, instance=wga, initial=initial) - if form.is_valid(): - form.save(commit=False) - wga.agenda = bool(form.cleaned_data['telechat_date']) - if wga.category in (11, 21): - wga.agenda = False - if wga.agenda: - wga.telechat_date = form.cleaned_data['telechat_date'] - wga.save() - return HttpResponseRedirect(urlreverse('iesg_working_group_actions')) - else: - form = EditWGActionForm(instance=wga, initial=initial) - - - return render_to_response("iesg/edit_working_group_action.html", - dict(wga=wga, - form=form), - context_instance=RequestContext(request)) diff --git a/ietf/ietfauth/__init__.py b/ietf/ietfauth/__init__.py index a4b306690..e69de29bb 100644 --- a/ietf/ietfauth/__init__.py +++ b/ietf/ietfauth/__init__.py @@ -1,2 +0,0 @@ -# Copyright The IETF Trust 2007, All Rights Reserved - diff --git a/ietf/ietfauth/auth.py b/ietf/ietfauth/auth.py deleted file mode 100644 index 029a0b557..000000000 --- a/ietf/ietfauth/auth.py +++ /dev/null @@ -1,115 +0,0 @@ -# Portions Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -# All rights reserved. Contact: Pasi Eronen -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# -# * Neither the name of the Nokia Corporation and/or its -# subsidiary(-ies) nor the names of its contributors may be used -# to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# Copyright The IETF Trust 2007, All Rights Reserved - -from django.contrib.auth.backends import RemoteUserBackend -from django.contrib.auth.models import Group -from ietf.idtracker.models import IESGLogin, Role -from ietf.ietfauth.models import IetfUserProfile - -from ietf.utils import log - -AUTOMATIC_GROUPS = ["Area_Director", "Secretariat", "IETF_Chair", - "IAB_Chair", "IRTF_Chair", ] - -class IetfUserBackend(RemoteUserBackend): - - def find_groups(username): - """ - Role/Group: - Area_Director currently sitting AD - IETF_Chair currently sitting IETF Chair - IAB_Chair currently sitting IAB Chair - IRTF_Chair currently sitting IRTF Chair - Secretariat secretariat staff - - Roles/Groups NOT YET IMPLEMENTED - WG_Chair currently sitting chair of some WG - IESG_Liaison non-ADs on iesg@ietf.org and telechats - Session_Chair chairing a non-WG session in IETF meeting - Ex_Area_Director past AD - """ - # Any group name added by this method should be added to the - # AUTOMATIC_GROUPS list - groups = [] - try: - login = IESGLogin.objects.get(login_name=username) - if login.user_level == 1: - groups.append("Area_Director") - elif login.user_level == 0: - groups.append("Secretariat") - if login.person: - for role in login.person.role_set.all(): - if role.id == Role.IETF_CHAIR: - groups.append("IETF_Chair") - elif role.id == Role.IAB_CHAIR: - groups.append("IAB_Chair") - elif role.id == Role.IRTF_CHAIR: - groups.append("IRTF_Chair") - except IESGLogin.DoesNotExist: - pass - # - # Additional sources of group memberships: - # - wg_password table - # - other Roles - # - the /etc/.../*.perms files - return groups - - find_groups = staticmethod(find_groups) - - def authenticate(self, remote_user): - user = RemoteUserBackend.authenticate(self, remote_user) - if not user: - return user - - # Create profile if it doesn't exist - try: - profile = user.get_profile() - except IetfUserProfile.DoesNotExist: - profile = IetfUserProfile(user=user) - profile.save() - - # Remove any automatic groups, the proper ones will be retrieved by - # find_groups - groups = [group for group in user.groups.exclude(name__in=AUTOMATIC_GROUPS)] - - # Update group memberships - group_names = IetfUserBackend.find_groups(user.username) - for group_name in group_names: - # Create groups as needed - group,created = Group.objects.get_or_create(name=group_name) - if created: - log("IetfUserBackend created Group '%s'" % (group_name,)) - groups.append(group) - user.groups = groups - return user diff --git a/ietf/ietfauth/decorators.py b/ietf/ietfauth/decorators.py deleted file mode 100644 index a30cbb01b..000000000 --- a/ietf/ietfauth/decorators.py +++ /dev/null @@ -1,35 +0,0 @@ -# Portion Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -# All rights reserved. Contact: Pasi Eronen -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# -# * Neither the name of the Nokia Corporation and/or its -# subsidiary(-ies) nor the names of its contributors may be used -# to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# REDESIGN: backwards compatibility, to be deleted -from ietf.ietfauth.utils import role_required, has_role, passes_test_decorator -group_required = lambda *group_names: role_required(*[n.replace("Area_Director", "Area Director") for n in group_names]) diff --git a/ietf/ietfauth/forms.py b/ietf/ietfauth/forms.py index 0b895efe8..94cc54d1e 100644 --- a/ietf/ietfauth/forms.py +++ b/ietf/ietfauth/forms.py @@ -10,7 +10,8 @@ from django.contrib.sites.models import Site from django.utils.translation import ugettext_lazy as _ from ietf.utils.mail import send_mail -from ietf.person.models import Person, Email +from ietf.person.models import Person, Email, Alias +from ietf.group.models import Role class RegistrationForm(forms.Form): @@ -167,7 +168,6 @@ class PersonForm(ModelForm): request = None new_emails = [] class Meta: - from ietf.person.models import Person model = Person exclude = ('time','user') @@ -193,8 +193,6 @@ class PersonForm(ModelForm): send_mail(self.request, to_email, from_email, subject, 'registration/add_email_email.txt', context) def save(self, force_insert=False, force_update=False, commit=True): - from ietf.group.models import Role - from ietf.person.models import Alias m = super(PersonForm, self).save(commit=False) self.new_emails = [v for k,v in self.data.items() if k[:10] == u'new_email_' and u'@' in v] diff --git a/ietf/ietfauth/models.py b/ietf/ietfauth/models.py index b302d38a6..137941ffa 100644 --- a/ietf/ietfauth/models.py +++ b/ietf/ietfauth/models.py @@ -1,136 +1 @@ -# Portions Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -# All rights reserved. Contact: Pasi Eronen -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# -# * Neither the name of the Nokia Corporation and/or its -# subsidiary(-ies) nor the names of its contributors may be used -# to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# Copyright The IETF Trust 2007, All Rights Reserved - from django.db import models -from django.contrib.auth.models import User -from ietf.idtracker.models import PersonOrOrgInfo, IESGLogin -from ietf.utils.admin import admin_link - -def find_person(username): - try: - person = IESGLogin.objects.get(login_name=username).person - return person - except IESGLogin.DoesNotExist, PersonOrOrgInfo.DoesNotExist: - pass - # try LegacyWgPassword next - try: - return LegacyWgPassword.objects.get(login_name=username).person - except LegacyWgPassword.DoesNotExist, PersonOrOrgInfo.DoesNotExist: - pass - # try LegacyLiaisonUser next - try: - return LegacyLiaisonUser.objects.get(login_name=username).person - except LegacyLiaisonUser.DoesNotExist, PersonOrOrgInfo.DoesNotExist: - pass - return None - -class IetfUserProfile(models.Model): - user = models.ForeignKey(User,unique=True) - - def person(self): - return find_person(self.user.username) - - def iesg_login_id(self): - person = self.person() - if not person: - return None - try: - return person.iesglogin_set.all()[0].id - except: - return None - - def email(self): - # quick hack to bind new and old schema together for the time being - try: - l = IESGLogin.objects.get(login_name=self.user.username) - if l.person: - person = l.person - else: - person = PersonOrOrgInfo.objects.get(first_name=l.first_name, - last_name=l.last_name) - except IESGLogin.DoesNotExist, PersonOrOrgInfo.DoesNotExist: - person = None - from ietf.person.models import Email - return Email.objects.get(address=person.email()[1]) - - def __str__(self): - return "IetfUserProfile(%s)" % (self.user,) - - -###################################################### -# legacy per-tool access tables. -# ietf.idtracker.models.IESGLogin is in the same vein. - -class LegacyLiaisonUser(models.Model): - USER_LEVEL_CHOICES = ( - (0, 'Secretariat'), - (1, 'IESG'), - (2, 'ex-IESG'), - (3, 'Level 3'), - (4, 'Comment Only(?)'), - ) - person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag', primary_key=True) - login_name = models.CharField(max_length=255) - password = models.CharField(max_length=25, blank=True, editable=False) - user_level = models.IntegerField(null=True, blank=True, choices=USER_LEVEL_CHOICES) - comment = models.TextField(blank=True,null=True) - def __str__(self): - return self.login_name - class Meta: - db_table = 'users' - ordering = ['login_name'] - person_link = admin_link('person') - -class LegacyWgPassword(models.Model): - person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag', primary_key=True) - password = models.CharField(blank=True, null=True,max_length=255) - secrete_question_id = models.IntegerField(null=True, blank=True) - secrete_answer = models.CharField(blank=True, null=True, max_length=255) - is_tut_resp = models.IntegerField(null=True, blank=True) - irtf_id = models.IntegerField(null=True, blank=True) - comment = models.TextField(blank=True,null=True) - login_name = models.CharField(blank=True, max_length=100) - def __str__(self): - return self.login_name - class Meta: - db_table = 'wg_password' - ordering = ['login_name'] - person_link = admin_link('person') - -# changes done by convert-096.py:changed maxlength to max_length -# removed core -# removed edit_inline -# removed max_num_in_admin -# removed num_in_admin -# removed raw_id_admin diff --git a/ietf/ietfauth/tests.py b/ietf/ietfauth/tests.py index 293949342..bd7eb75d3 100644 --- a/ietf/ietfauth/tests.py +++ b/ietf/ietfauth/tests.py @@ -30,76 +30,46 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -import unittest -from django.conf import settings -from django.contrib.auth.models import User -from django.test.client import Client -from ietf.utils.test_utils import SimpleUrlTestCase, RealDatabaseTest -from ietf.idtracker.models import Role from urlparse import urlsplit -class IetfAuthUrlTestCase(SimpleUrlTestCase): - def testUrls(self): - self.doTestUrls(__file__) +from django.contrib.auth.models import User +from django.core.urlresolvers import reverse as urlreverse -# this test case should really work on a test database instead of the -# real one -class IetfAuthTestCase(unittest.TestCase,RealDatabaseTest): - def setUp(self): - self.setUpRealDatabase() - def tearDown(self): - self.tearDownRealDatabase() +from ietf.utils.test_utils import TestCase, login_testing_unauthorized +from ietf.utils.test_data import make_test_data - def _doLogin(self, username): - c = Client() - response = c.get('/accounts/login/', {}, False, REMOTE_USER=username) - self.assertEquals(response.status_code, 302) - nexturl = urlsplit(response['Location']) - self.assertEquals(nexturl[2], "/accounts/loggedin/") +class IetfAuthTests(TestCase): + def test_index(self): + self.assertEqual(self.client.get(urlreverse("ietf.ietfauth.views.index")).status_code, 200) - response = c.get(nexturl[2], {}, False, REMOTE_USER=username) - self.assertEquals(response.status_code, 302) - nexturl = urlsplit(response['Location']) - self.assertEquals(nexturl[2], "/accounts/profile/") + def test_login(self): + make_test_data() - response = c.get(nexturl[2], {}, False, REMOTE_USER=username) - self.assertEquals(response.status_code, 200) - self.assert_("User name" in response.content) - return response + # try logging in with a next + r = self.client.get('/accounts/login/?next=/foobar', REMOTE_USER="plain") + self.assertEqual(r.status_code, 302) + self.assertEqual(urlsplit(r["Location"])[2], "/accounts/loggedin/") - def testLogin(self): - TEST_USERNAME = '__testuser' - print " Testing login with "+TEST_USERNAME + r = self.client.get('/accounts/loggedin/?next=/foobar', REMOTE_USER="plain") + self.assertEqual(r.status_code, 302) + self.assertEqual(urlsplit(r["Location"])[2], "/foobar") - # Delete test user (if it exists) - try: - testuser = User.objects.get(username=TEST_USERNAME) - testuser.delete() - except User.DoesNotExist: - pass + # try again without a next + r = self.client.get('/accounts/login/', REMOTE_USER="plain") + r = self.client.get('/accounts/loggedin/', REMOTE_USER="plain") + self.assertEqual(r.status_code, 302) + self.assertEqual(urlsplit(r["Location"])[2], "/accounts/profile/") - self._doLogin(TEST_USERNAME) - - # Delete test user after test - testuser = User.objects.get(username=TEST_USERNAME) - testuser.delete() - print "OK" + def test_profile(self): + url = urlreverse('ietf.ietfauth.views.profile') + login_testing_unauthorized(self, "plain", url) - def testGroups(self): - print " Testing group assignment" - username = Role.objects.get(id=Role.IETF_CHAIR).person.iesglogin_set.all()[0].login_name - print " (with username "+str(username)+")" - - self._doLogin(username) - - user = User.objects.get(username=username) - groups = [x.name for x in user.groups.all()] - self.assert_("Area_Director" in groups) - self.assert_("IETF_Chair" in groups) + # get + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + self.assertTrue("plain" in r.content) - print "OK" + # post + # ... fill in -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - del IetfAuthTestCase.testLogin - # this test doesn't make any sense anymore - del IetfAuthTestCase.testGroups + # we're missing tests of the other views diff --git a/ietf/ietfauth/testurl.list b/ietf/ietfauth/testurl.list deleted file mode 100644 index 13099f975..000000000 --- a/ietf/ietfauth/testurl.list +++ /dev/null @@ -1 +0,0 @@ -302 /accounts/profile/ diff --git a/ietf/ietfauth/urls.py b/ietf/ietfauth/urls.py index 68d62bebe..4fd239d20 100644 --- a/ietf/ietfauth/urls.py +++ b/ietf/ietfauth/urls.py @@ -1,18 +1,14 @@ # Copyright The IETF Trust 2007, 2009, All Rights Reserved from django.conf.urls.defaults import patterns, url -from ietf.ietfauth import views -urlpatterns = patterns('', - (r'^$', views.index, None, 'account_index'), - (r'^login/$', views.ietf_login), - (r'^loggedin/$', views.ietf_loggedin), - (r'^profile/$', views.profile), -# (r'^login/(?P[a-z0-9.@]+)/(?P.+)$', views.url_login), - (r'^testemail/$', views.test_email), -) - -urlpatterns += patterns('ietf.ietfauth.views', +urlpatterns = patterns('ietf.ietfauth.views', + url(r'^$', 'index', name='account_index'), + url(r'^login/$', 'ietf_login'), + url(r'^loggedin/$', 'ietf_loggedin'), + url(r'^profile/$', 'profile'), +# (r'^login/(?P[a-z0-9.@]+)/(?P.+)$', 'url_login'), + url(r'^testemail/$', 'test_email'), url(r'^create/$', 'create_account', name='create_account'), url(r'^confirm/(?P[\w.@+-]+)/(?P[\d]+)/(?P[\w]+)/(?P[a-f0-9]+)/$', 'confirm_account', name='confirm_account'), url(r'^reset/$', 'password_reset_view', name='password_reset'), diff --git a/ietf/ietfauth/views.py b/ietf/ietfauth/views.py index 141237075..c7c74fc1a 100644 --- a/ietf/ietfauth/views.py +++ b/ietf/ietfauth/views.py @@ -34,6 +34,7 @@ import datetime import hashlib +import json from django.conf import settings from django.template import RequestContext @@ -43,10 +44,12 @@ from django.contrib.auth import REDIRECT_FIELD_NAME, authenticate, login from django.contrib.auth.decorators import login_required from django.contrib.auth.models import User from django.utils.http import urlquote -from django.utils import simplejson as json from django.utils.translation import ugettext as _ +from django.core.exceptions import ValidationError, NON_FIELD_ERRORS -from ietf.ietfauth.forms import RegistrationForm, PasswordForm, RecoverPasswordForm, TestEmailForm +from ietf.person.models import Person, Email, Alias +from ietf.group.models import Role +from ietf.ietfauth.forms import RegistrationForm, PasswordForm, RecoverPasswordForm, TestEmailForm, PersonForm def index(request): return render_to_response('registration/index.html', context_instance=RequestContext(request)) @@ -62,8 +65,8 @@ def url_login(request, user, passwd): def ietf_login(request): if not request.user.is_authenticated(): - # This probably means an exception occured inside IetfUserBackend return HttpResponse("Not authenticated?", status=500) + redirect_to = request.REQUEST.get(REDIRECT_FIELD_NAME, '') request.session.set_test_cookie() return HttpResponseRedirect('/accounts/loggedin/?%s=%s' % (REDIRECT_FIELD_NAME, urlquote(redirect_to))) @@ -79,10 +82,6 @@ def ietf_loggedin(request): @login_required def profile(request): - from ietf.person.models import Person, Email, Alias - from ietf.group.models import Role - from ietf.ietfauth.forms import PersonForm - roles = [] person = None try: @@ -119,8 +118,6 @@ def profile(request): context_instance=RequestContext(request)) def confirm_new_email(request, username, date, email, hash): - from ietf.person.models import Person, Email, Alias - from django.core.exceptions import ValidationError, NON_FIELD_ERRORS valid = hashlib.md5('%s%s%s%s' % (settings.SECRET_KEY, date, email, username)).hexdigest() == hash if not valid: raise Http404 @@ -233,24 +230,15 @@ def ajax_check_username(request): return HttpResponse(json.dumps({'error': error}), mimetype='text/plain') def test_email(request): + """Set email address to which email generated in the system will be sent.""" if settings.SERVER_MODE == "production": - raise Http404() + raise Http404 - # note that the cookie set here is only used when running in + # Note that the cookie set here is only used when running in # "test" mode, normally you run the server in "development" mode, - # in which case email is sent out as usual; for development, put - # this - # - # EMAIL_HOST = 'localhost' - # EMAIL_PORT = 1025 - # EMAIL_HOST_USER = None - # EMAIL_HOST_PASSWORD = None - # EMAIL_COPY_TO = "" - # - # in your settings.py and start a little debug email server in a - # console with the following (it receives and prints messages) - # - # python -m smtpd -n -c DebuggingServer localhost:1025 + # in which case email is sent out as usual; for development, you + # can easily start a little email debug server with Python, see + # the instructions in utils/mail.py. cookie = None diff --git a/ietf/ietfworkflows/.gitignore b/ietf/ietfworkflows/.gitignore deleted file mode 100644 index a74b07aee..000000000 --- a/ietf/ietfworkflows/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/*.pyc diff --git a/ietf/ietfworkflows/__init__.py b/ietf/ietfworkflows/__init__.py deleted file mode 100644 index e8d53c9a3..000000000 --- a/ietf/ietfworkflows/__init__.py +++ /dev/null @@ -1,18 +0,0 @@ -# coding: latin-1 - -from types import ModuleType -import urls, models, views, forms, accounts - -# These people will be sent a stack trace if there's an uncaught exception in -# code any of the modules imported above: -DEBUG_EMAILS = [ - ('Emilio A. Sánchez', 'esanchez@yaco.es'), -] - -for k in locals().keys(): - m = locals()[k] - if isinstance(m, ModuleType): - if hasattr(m, "DEBUG_EMAILS"): - DEBUG_EMAILS += list(getattr(m, "DEBUG_EMAILS")) - setattr(m, "DEBUG_EMAILS", DEBUG_EMAILS) - diff --git a/ietf/ietfworkflows/accounts.py b/ietf/ietfworkflows/accounts.py deleted file mode 100644 index c687bda85..000000000 --- a/ietf/ietfworkflows/accounts.py +++ /dev/null @@ -1,132 +0,0 @@ -from django.conf import settings - -from django.db.models import Q - -from ietf.ietfworkflows.streams import get_streamed_draft -from ietf.group.models import Role - - -def get_person_for_user(user): - try: - return user.get_profile().person() - except: - return None - - -def is_secretariat(user): - if not user or not user.is_authenticated(): - return False - return bool(user.groups.filter(name='Secretariat')) - - -def is_wgchair(person): - return bool(person.wgchair_set.all()) - -def is_wgchairREDESIGN(person): - return bool(Role.objects.filter(name="chair", group__type="wg", group__state="active", person=person)) - -def is_rgchairREDESIGN(person): - return bool(Role.objects.filter(name="chair", group__type="rg", group__state="active", person=person)) - -def is_wgdelegate(person): - return bool(person.wgdelegate_set.all()) - -def is_wgdelegateREDESIGN(person): - return bool(Role.objects.filter(name="delegate", group__type="wg", group__state="active", person=person)) - -def is_rgdelegateREDESIGN(person): - return bool(Role.objects.filter(name="delegate", group__type="rg", group__state="active", person=person)) - -def is_delegate_of_stream(user, stream): - if is_secretariat(user): - return True - person = get_person_for_user(user) - return stream.check_delegate(person) - -def is_delegate_of_streamREDESIGN(user, stream): - if is_secretariat(user): - return True - return user.is_authenticated() and bool(Role.objects.filter(group__acronym=stream.slug, name="delegate", person__user=user)) - - -def is_chair_of_stream(user, stream): - if is_secretariat(user): - return True - person = get_person_for_user(user) - return stream.check_chair(person) - -def is_chair_of_streamREDESIGN(user, stream): - if is_secretariat(user): - return True - if isinstance(user, basestring): - return False - return user.is_authenticated() and bool(Role.objects.filter(group__acronym=stream.slug, name="chair", person__user=user)) - -def is_authorized_in_draft_stream(user, draft): - if is_secretariat(user): - return True - person = get_person_for_user(user) - if not person: - return False - streamed = get_streamed_draft(draft) - if not streamed or not streamed.stream: - return False - # Check if the person is chair of the stream - if is_chair_of_stream(user, streamed.stream): - return True - # Check if the person is delegate of the stream - if is_delegate_of_stream(user, streamed.stream): - return True - # Check if the person is chair of the related group - chairs = streamed.stream.get_chairs_for_document(draft) - if chairs and person in [i.person for i in chairs]: - return True - # Check if the person is authorized by a delegate system - delegates = streamed.stream.get_delegates_for_document(draft) - return bool(person in delegates) - -def is_authorized_in_draft_streamREDESIGN(user, draft): - if is_secretariat(user): - return True - - from ietf.doc.models import Document - - if not super(Document, draft).stream: - return False - - # must be a chair or delegate of the stream group (or draft group) - group_req = Q(group__acronym=super(Document, draft).stream.slug) - if draft.group and super(Document, draft).stream.slug in ["ietf", "irtf"]: - group_req |= Q(group=draft.group) - - return user.is_authenticated() and bool(Role.objects.filter(name__in=("chair", "secr", "delegate"), person__user=user).filter(group_req)) - - -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - from ietf.liaisons.accounts import is_secretariat, get_person_for_user - is_wgdelegate = is_wgdelegateREDESIGN - is_wgchair = is_wgchairREDESIGN - is_rgdelegate = is_rgdelegateREDESIGN - is_rgchair = is_rgchairREDESIGN - is_chair_of_stream = is_chair_of_streamREDESIGN - is_delegate_of_stream = is_delegate_of_streamREDESIGN - is_authorized_in_draft_stream = is_authorized_in_draft_streamREDESIGN - - -def can_edit_state(user, draft): - return (is_secretariat(user) or - is_authorized_in_draft_stream(user, draft)) - - -def can_edit_stream(user, draft): - return is_secretariat(user) - -def can_adopt(user, draft): - if settings.USE_DB_REDESIGN_PROXY_CLASSES and (not draft.stream_id or draft.stream_id in ["ietf", "irtf"]) and draft.group.type_id == "individ": - person = get_person_for_user(user) - if not person: - return False - return is_wgchair(person) or is_rgchair(person) or is_wgdelegate(person) or is_rgdelegate() or is_secretariat(user) - else: - return is_secretariat(user) - diff --git a/ietf/ietfworkflows/constants.py b/ietf/ietfworkflows/constants.py deleted file mode 100644 index d29a1164f..000000000 --- a/ietf/ietfworkflows/constants.py +++ /dev/null @@ -1,13 +0,0 @@ -# Required states -CALL_FOR_ADOPTION = 'Call For Adoption By WG Issued' -WG_DOCUMENT = 'WG Document' -SUBMITTED_TO_IESG = 'Submitted to IESG for Publication' - -REQUIRED_STATES = ( - CALL_FOR_ADOPTION, - WG_DOCUMENT, - SUBMITTED_TO_IESG, - ) - -# IETF Stream -IETF_STREAM = 'IETF' diff --git a/ietf/ietfworkflows/fixtures/.gitignore b/ietf/ietfworkflows/fixtures/.gitignore deleted file mode 100644 index a74b07aee..000000000 --- a/ietf/ietfworkflows/fixtures/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/*.pyc diff --git a/ietf/ietfworkflows/fixtures/initial_data.xml b/ietf/ietfworkflows/fixtures/initial_data.xml deleted file mode 100644 index 51e06c12f..000000000 --- a/ietf/ietfworkflows/fixtures/initial_data.xml +++ /dev/null @@ -1,686 +0,0 @@ - - - - Default WG Workflow - 11 - - - IAB Workflow - - - - IRTF Workflow - - - - ISE Workflow - - - - Active IAB Document - 2 - - - - Active RG Document - 3 - - - - Adopted by a WG - 1 - - - - Adopted for WG Info Only - 1 - - - - Approved by IAB, To Be Sent to RFC Editor - 2 - - - - Awaiting IRSG Reviews - 3 - - - - Call For Adoption By WG Issued - 1 - - - - Candidate IAB Document - 2 - - - - Candidate RG Document - 3 - - - - Community Review - 2 - - - - Dead IAB Document - 2 - - - - Dead IRTF Document - 3 - - - - Dead WG Document - 1 - - - - Document on Hold Based On IESG Request - 3 - - - - Document on Hold Based On IESG Request - 4 - - - - Finding Reviewers - 4 - - - - IAB Review - 2 - - - - In IESG Review - 3 - - - - In IESG Review - 4 - - - - In IRSG Poll - 3 - - - - In ISE Review - 4 - - - - In RG Last Call - 3 - - - - In WG Last Call - 1 - - - - No Longer In Independent Submission Stream - 4 - - - - Parked IAB Document - 2 - - - - Parked RG Document - 3 - - - - Parked WG Document - 1 - - - - Response to Review Needed - 4 - - - - Sent to a Different Organization for Publication - 2 - - - - Sent to the RFC Editor - 2 - - - - Sent to the RFC Editor - 4 - - - - Sent to the RFC Editor - 3 - - - - Submission Received - 4 - - - - Submitted to IESG for Publication - 1 - - - - Waiting for Document Shepherd - 3 - - - - Waiting for IRTF Chair - 3 - - - - Waiting for WG Chair Go-Ahead - 1 - - - - WG Consensus: Waiting for Write-Up - 1 - - - - WG Document - 1 - - - - Wait for go-ahead - 1 - 18 - - - - - Reach consensus - 1 - 19 - - - - - Adopt - 1 - 12 - - - - - Adopt for WG info only - 1 - 13 - - - - - Develop - 1 - 14 - - - - - Park - 1 - 15 - - - - - Die - 1 - 16 - - - - - Submit to IESG - 1 - 20 - - - - - Raise last call - 1 - 17 - - - - - Revised I-D Needed - 3 - - - - Shepherd Needed - 3 - - - - Waiting for Dependency on Other Document - 3 - - - - Revised I-D Needed - 2 - - - - Document Shepherd Followup - 2 - - - - Editor Needed - 3 - - - - Awaiting Reviews - 2 - - - - Waiting for Partner Feedback - 2 - - - - Other - see Comment Log - 1 - - - - Editor Needed - 2 - - - - Doc Shepherd Follow-Up Underway - 1 - - - - Revised I-D Needed - Issue raised by IESG - 1 - - - - Awaiting Expert Review/Resolution of Issues Raised - 1 - - - - Awaiting External Review/Resolution of Issues Raised - 1 - - - - Awaiting Merge with Other Document - 1 - - - - Author or Editor Needed - 1 - - - - Waiting for Referenced Document - 1 - - - - Revised I-D Needed - Issue raised by AD - 1 - - - - Revised I-D Needed - Issue raised by WGLC - 1 - - - - Waiting for Referencing Document - 1 - - - - IESG Review Completed - 3 - - - - Waiting for Dependency on Other Document - 4 - - - - Awaiting Reviews - 4 - - - - Revised I-D Needed - 4 - - - - IESG Review Completed - 4 - - - - - - - - - - - - - - - - - - - - IETF - group.ietfwg - chairs - 1 - - - IAB - - - 2 - - - IRTF - - - 3 - - - ISE - - - 4 - - - 11 - <a href="http://tools.ietf.org/html/rfc6174#section-4.2.1" target="_blank">4.2.1. Call for Adoption by WG Issued</a> - - - The "Call for Adoption by WG Issued" state should be used to indicate - when an I-D is being considered for adoption by an IETF WG. An I-D - that is in this state is actively being considered for adoption and - has not yet achieved consensus, preference, or selection in the WG. - - This state may be used to describe an I-D that someone has asked a WG - to consider for adoption, if the WG Chair has agreed with the - request. This state may also be used to identify an I-D that a WG - Chair asked an author to write specifically for consideration as a - candidate WG item [WGDTSPEC], and/or an I-D that is listed as a - 'candidate draft' in the WG's charter. - - Under normal conditions, it should not be possible for an I-D to be - in the "Call for Adoption by WG Issued" state in more than one - working group at the same time. This said, it is not uncommon for - authors to "shop" their I-Ds to more than one WG at a time, with the - hope of getting their documents adopted somewhere. - - After this state is implemented in the Datatracker, an I-D that is in - the "Call for Adoption by WG Issued" state will not be able to be - "shopped" to any other WG without the consent of the WG Chairs and - the responsible ADs impacted by the shopping. - - Note that Figure 1 includes an arc leading from this state to outside - of the WG state machine. This illustrates that some I-Ds that are - considered do not get adopted as WG drafts. An I-D that is not - adopted as a WG draft will transition out of the WG state machine and - revert back to having no stream-specific state; however, the status - change history log of the I-D will record that the I-D was previously - in the "Call for Adoption by WG Issued" state. - - 1 - - - 12 - <a href="http://tools.ietf.org/html/rfc6174#section-4.2.2" target="_blank">4.2.2. Adopted by a WG</a> - - - The "Adopted by a WG" state describes an individual submission I-D - that an IETF WG has agreed to adopt as one of its WG drafts. - - WG Chairs who use this state will be able to clearly indicate when - their WGs adopt individual submission I-Ds. This will facilitate the - Datatracker's ability to correctly capture "Replaces" information for - WG drafts and correct "Replaced by" information for individual - submission I-Ds that have been replaced by WG drafts. - - This state is needed because the Datatracker uses the filename of an - I-D as a key to search its database for status information about the - I-D, and because the filename of a WG I-D is supposed to be different - from the filename of an individual submission I-D. - The filename of an individual submission I-D will typically be - formatted as 'draft-author-wgname-topic-nn'. - - The filename of a WG document is supposed to be formatted as 'draft- - ietf-wgname-topic-nn'. - - An individual I-D that is adopted by a WG may take weeks or months to - be resubmitted by the author as a new (version-00) WG draft. If the - "Adopted by a WG" state is not used, the Datatracker has no way to - determine that an I-D has been adopted until a new version of the I-D - is submitted to the WG by the author and until the I-D is approved - for posting by a WG Chair. - - 2 - - - 13 - <a href="http://tools.ietf.org/html/rfc6174#section-4.2.3" target="_blank">4.2.3. Adopted for WG Info Only</a> - - - The "Adopted for WG Info Only" state describes a document that - contains useful information for the WG that adopted it, but the - document is not intended to be published as an RFC. The WG will not - actively develop the contents of the I-D or progress it for - publication as an RFC. The only purpose of the I-D is to provide - information for internal use by the WG. - - 3 - - - 14 - <a href="http://tools.ietf.org/html/rfc6174#section-4.2.4" target="_blank">4.2.4. WG Document</a> - - - The "WG Document" state describes an I-D that has been adopted by an - IETF WG and is being actively developed. - - A WG Chair may transition an I-D into the "WG Document" state at any - time as long as the I-D is not being considered or developed in any - other WG. - - Alternatively, WG Chairs may rely upon new functionality to be added - to the Datatracker to automatically move version-00 drafts into the - "WG Document" state as described in Section 4.1. - - Under normal conditions, it should not be possible for an I-D to be - in the "WG Document" state in more than one WG at a time. This said, - I-Ds may be transferred from one WG to another with the consent of - the WG Chairs and the responsible ADs. - - - 4 - - - 15 - <a href="http://tools.ietf.org/html/rfc6174#section-4.2.5" target="_blank">4.2.5. Parked WG Document</a> - - - A "Parked WG Document" is an I-D that has lost its author or editor, - is waiting for another document to be written or for a review to be - completed, or cannot be progressed by the working group for some - other reason. - - Some of the annotation tags described in Section 4.3 may be used in - conjunction with this state to indicate why an I-D has been parked, - and/or what may need to happen for the I-D to be un-parked. - - Parking a WG draft will not prevent it from expiring; however, this - state can be used to indicate why the I-D has stopped progressing in - the WG. - - A "Parked WG Document" that is not expired may be transferred from - one WG to another with the consent of the WG Chairs and the - responsible ADs. - - - 5 - - - 16 - <a href="http://tools.ietf.org/html/rfc6174#section-4.2.6" target="_blank">4.2.6. Dead WG Document</a> - - - A "Dead WG Document" is an I-D that has been abandoned. Note that - 'Dead' is not always a final state for a WG I-D. If consensus is - subsequently achieved, a "Dead WG Document" may be resurrected. A - "Dead WG Document" that is not resurrected will eventually expire. - - Note that an I-D that is declared to be "Dead" in one WG and that is - not expired may be transferred to a non-dead state in another WG with - the consent of the WG Chairs and the responsible ADs. - - - 6 - - - 17 - <a href="http://tools.ietf.org/html/rfc6174#section-4.2.7" target="_blank">4.2.7. In WG Last Call</a> - - - A document "In WG Last Call" is an I-D for which a WG Last Call - (WGLC) has been issued and is in progress. - - Note that conducting a WGLC is an optional part of the IETF WG - process, per Section 7.4 of RFC 2418 [RFC2418]. - - If a WG Chair decides to conduct a WGLC on an I-D, the "In WG Last - Call" state can be used to track the progress of the WGLC. The Chair - may configure the Datatracker to send a WGLC message to one or more - mailing lists when the Chair moves the I-D into this state. The WG - Chair may also be able to select a different set of mailing lists for - a different document undergoing a WGLC; some documents may deserve - coordination with other WGs. - - A WG I-D in this state should remain "In WG Last Call" until the WG - Chair moves it to another state. The WG Chair may configure the - Datatracker to send an e-mail after a specified period of time to - remind or 'nudge' the Chair to conclude the WGLC and to determine the - next state for the document. - - It is possible for one WGLC to lead into another WGLC for the same - document. For example, an I-D that completed a WGLC as an - "Informational" document may need another WGLC if a decision is taken - to convert the I-D into a Standards Track document. - - - 7 - - - 18 - <a href="http://tools.ietf.org/html/rfc6174#section-4.2.8" target="_blank">4.2.8. Waiting for WG Chair Go-Ahead</a> - - - A WG Chair may wish to place an I-D that receives a lot of comments - during a WGLC into the "Waiting for WG Chair Go-Ahead" state. This - state describes an I-D that has undergone a WGLC; however, the Chair - is not yet ready to call consensus on the document. - - If comments from the WGLC need to be responded to, or a revision to - the I-D is needed, the Chair may place an I-D into this state until - all of the WGLC comments are adequately addressed and the (possibly - revised) document is in the I-D repository. - - - 8 - - - 19 - <a href="http://tools.ietf.org/html/rfc6174#section-4.2.9" target="_blank">4.2.9. WG Consensus: Waiting for Writeup</a> - - - A document in the "WG Consensus: Waiting for Writeup" state has - essentially completed its development within the working group, and - is nearly ready to be sent to the IESG for publication. The last - thing to be done is the preparation of a protocol writeup by a - Document Shepherd. The IESG requires that a document shepherd - writeup be completed before publication of the I-D is requested. The - IETF document shepherding process and the role of a WG Document - Shepherd is described in RFC 4858 [RFC4858] - - A WG Chair may call consensus on an I-D without a formal WGLC and - transition an I-D that was in the "WG Document" state directly into - this state. - - The name of this state includes the words "Waiting for Writeup" - because a good document shepherd writeup takes time to prepare. - - - 9 - - - 20 - <a href="http://tools.ietf.org/html/rfc6174#section-4.2.10" target="_blank">4.2.10. Submitted to IESG for Publication</a> - - - This state describes a WG document that has been submitted to the - IESG for publication and that has not been sent back to the working - group for revision. - - An I-D in this state may be under review by the IESG, it may have - been approved and be in the RFC Editor's queue, or it may have been - published as an RFC. Other possibilities exist too. The document - may be "Dead" (in the IESG state machine) or in a "Do Not Publish" - state. - - - 10 - - diff --git a/ietf/ietfworkflows/forms.py b/ietf/ietfworkflows/forms.py deleted file mode 100644 index 6532f144b..000000000 --- a/ietf/ietfworkflows/forms.py +++ /dev/null @@ -1,363 +0,0 @@ -import datetime - -from django.conf import settings -from django import forms -from django.template.loader import render_to_string -from workflows.models import State -from workflows.utils import set_workflow_for_object - -from ietf.idtracker.models import PersonOrOrgInfo, IETFWG, InternetDraft -from ietf.wgchairs.accounts import get_person_for_user -from ietf.ietfworkflows.models import Stream, StreamDelegate -from ietf.ietfworkflows.utils import (get_workflow_for_draft, get_workflow_for_wg, - get_state_for_draft, get_state_by_name, - update_state, FOLLOWUP_TAG, - get_annotation_tags_for_draft, - update_tags, update_stream) -from ietf.ietfworkflows.accounts import is_secretariat -from ietf.ietfworkflows.streams import (get_stream_from_draft, get_streamed_draft, - get_stream_by_name, set_stream_for_draft) -from ietf.ietfworkflows.constants import CALL_FOR_ADOPTION, IETF_STREAM -from ietf.doc.utils import get_tags_for_stream_id -from ietf.doc.models import save_document_in_history, DocEvent, Document -from ietf.name.models import DocTagName, StreamName, RoleName -from ietf.group.models import Group, GroupStateTransitions, Role -from ietf.group.utils import save_group_in_history -from ietf.person.models import Person, Email - -class StreamDraftForm(forms.Form): - - can_cancel = False - template = None - - def __init__(self, *args, **kwargs): - self.draft = kwargs.pop('draft', None) - self.user = kwargs.pop('user', None) - self.person = get_person_for_user(self.user) - self.workflow = get_workflow_for_draft(self.draft) - self.message = {} - super(StreamDraftForm, self).__init__(*args, **kwargs) - - def get_message(self): - return self.message - - def set_message(self, msg_type, msg_value): - self.message = {'type': msg_type, - 'value': msg_value, - } - - def __unicode__(self): - return render_to_string(self.template, {'form': self}) - - -class NoWorkflowStateForm(StreamDraftForm): - comment = forms.CharField(widget=forms.Textarea, required=False) - weeks = forms.IntegerField(required=False) - group = forms.ChoiceField(required=False) - - template = 'ietfworkflows/noworkflow_state_form.html' - - def __init__(self, *args, **kwargs): - super(NoWorkflowStateForm, self).__init__(*args, **kwargs) - self.groups = None - if is_secretariat(self.user): - groups = IETFWG.objects.all().order_by('group_acronym__acronym') - else: - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - groups = IETFWG.objects.filter(type__in=["wg", "rg"], state="active", role__name__in=("chair", "secr", "delegate"), role__person__user=self.user).order_by('acronym').distinct() - else: - groups = set([i.group_acronym for i in self.person.wgchair_set.all()]).union(set([i.wg for i in self.person.wgdelegate_set.all()])) - groups = list(groups) - groups.sort(lambda x, y: cmp(x.group_acronym.acronym, y.group_acronym.acronym)) - self.groups = groups - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - self.fields['group'].choices = [(i.pk, '%s - %s' % (i.acronym, i.name)) for i in self.groups] - else: - self.fields['group'].choices = [(i.pk, '%s - %s' % (i.group_acronym.acronym, i.group_acronym.name)) for i in self.groups] - - def save(self): - comment = self.cleaned_data.get('comment').strip() - weeks = self.cleaned_data.get('weeks') - group = IETFWG.objects.get(pk=self.cleaned_data.get('group')) - estimated_date = None - if weeks: - now = datetime.date.today() - estimated_date = now + datetime.timedelta(weeks=weeks) - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - # do changes on real Document object instead of proxy to avoid trouble - doc = Document.objects.get(pk=self.draft.pk) - save_document_in_history(doc) - - doc.time = datetime.datetime.now() - - if group.type.slug == "rg": - new_stream = StreamName.objects.get(slug="irtf") - else: - new_stream = StreamName.objects.get(slug="ietf") - - if doc.stream != new_stream: - e = DocEvent(type="changed_stream") - e.time = doc.time - e.by = self.user.get_profile() - e.doc = doc - e.desc = u"Changed to %s" % new_stream.name - if doc.stream: - e.desc += u" from %s" % doc.stream.name - e.save() - doc.stream = new_stream - - if doc.group.pk != group.pk: - e = DocEvent(type="changed_group") - e.time = doc.time - e.by = self.user.get_profile() - e.doc = doc - e.desc = u"Changed group to %s (%s)" % (group.name, group.acronym.upper()) - if doc.group.type_id != "individ": - e.desc += " from %s (%s)" % (doc.group.name, doc.group.acronym) - e.save() - doc.group_id = group.pk - - doc.save() - self.draft = InternetDraft.objects.get(pk=doc.pk) # make sure proxy object is updated - else: - workflow = get_workflow_for_wg(wg) - set_workflow_for_object(self.draft, workflow) - stream = get_stream_by_name(IETF_STREAM) - streamed = get_streamed_draft(self.draft) - if not streamed: - set_stream_for_draft(self.draft, stream) - streamed = get_streamed_draft(self.draft) - streamed.stream = stream - streamed.group = wg - streamed.save() - - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - from ietf.doc.models import State - if self.draft.stream_id == "irtf": - to_state = State.objects.get(used=True, slug="active", type="draft-stream-irtf") - else: - to_state = State.objects.get(used=True, slug="c-adopt", type="draft-stream-%s" % self.draft.stream_id) - else: - to_state = get_state_by_name(CALL_FOR_ADOPTION) - update_state(self.request, self.draft, - comment=comment, - person=self.person, - to_state=to_state, - added_tags=[], - removed_tags=[], - estimated_date=estimated_date) - - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - if comment: - e = DocEvent(type="added_comment") - e.time = self.draft.time - e.by = self.person - e.doc_id = self.draft.pk - e.desc = comment - e.save() - -class DraftTagsStateForm(StreamDraftForm): - - new_state = forms.ChoiceField(label='State') - weeks = forms.IntegerField(label='Expected weeks in state',required=False) - comment = forms.CharField(widget=forms.Textarea, required=False) - tags = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple, required=False) - - template = 'ietfworkflows/state_form.html' - - def __init__(self, *args, **kwargs): - super(DraftTagsStateForm, self).__init__(*args, **kwargs) - self.state = get_state_for_draft(self.draft) - self.fields['new_state'].choices = self.get_states() - self.fields['new_state'].initial = self.state.pk if self.state else None - if self.draft.stream_id == 'ietf': - self.fields['new_state'].help_text = "Only select 'Submitted to IESG for Publication' to correct errors. Use the document's main page to request publication." - if self.is_bound: - for key, value in self.data.items(): - if key.startswith('transition_'): - new_state = self.get_new_state(key) - if new_state: - self.data = self.data.copy() - self.data.update({'new_state': new_state.id}) - if key.startswith('new_state_'): # hack to get value from submit buttons - self.data = self.data.copy() - self.data['new_state'] = key.replace('new_state_', '') - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - possible_tags = get_tags_for_stream_id(self.draft.stream_id) - if self.draft.stream_id == "ietf" and self.draft.group: - unused_tags = self.draft.group.unused_tags.values_list("slug", flat=True) - possible_tags = [t for t in possible_tags if t not in unused_tags] - self.available_tags = DocTagName.objects.filter(slug__in=possible_tags) - self.tags = self.draft.tags.filter(slug__in=possible_tags) - else: - self.available_tags = self.workflow.get_tags() - self.tags = [i.annotation_tag for i in get_annotation_tags_for_draft(self.draft)] - - self.fields['tags'].choices = [(i.pk, i.name) for i in self.available_tags] - self.fields['tags'].initial = [i.pk for i in self.tags] - - def get_new_state(self, key): - transition_id = key.replace('transition_', '') - transition = self.get_transitions().filter(id=transition_id) - if transition: - return transition[0].destination - return None - - def get_transitions(self): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - return [] - return self.state.transitions.filter(workflow=self.workflow) - - def get_next_states(self): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - if not self.draft.stream_id: - return [] - - from ietf.doc.models import State - state_type = "draft-stream-%s" % self.draft.stream_id - s = self.draft.get_state(state_type) - next_states = [] - if s: - next_states = s.next_states.all() - - if self.draft.stream_id == "ietf" and self.draft.group: - transitions = self.draft.group.groupstatetransitions_set.filter(state=s) - if transitions: - next_states = transitions[0].next_states.all() - else: - # return the initial state - states = State.objects.filter(used=True, type=state_type).order_by('order') - if states: - next_states = states[:1] - - unused = [] - if self.draft.group: - unused = self.draft.group.unused_states.values_list("pk", flat=True) - return [n for n in next_states if n.pk not in unused] - - return [] - - - def get_states(self): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - if not self.draft.stream_id: - return [] - - from ietf.doc.models import State - states = State.objects.filter(used=True, type="draft-stream-%s" % self.draft.stream_id) - if self.draft.stream_id == "ietf" and self.draft.group: - unused_states = self.draft.group.unused_states.values_list("pk", flat=True) - states = [s for s in states if s.pk not in unused_states] - return [(i.pk, i.name) for i in states] - - return [(i.pk, i.name) for i in self.workflow.get_states()] - - def save_tags(self,send_email=True): - comment = self.cleaned_data.get('comment') - new_tags = self.cleaned_data.get('tags') - - set_tags = [tag for tag in self.available_tags if str(tag.pk) in new_tags and tag not in self.tags] - reset_tags = [tag for tag in self.available_tags if str(tag.pk) not in new_tags and tag in self.tags] - followup = bool([tag for tag in set_tags if tag.name == FOLLOWUP_TAG]) - extra_notify = [] - if followup: - try: - shepherd = self.draft.shepherd - if shepherd: - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - extra_notify = [shepherd.formatted_email()] - else: - extra_notify = ['%s <%s>' % shepherd.email()] - except PersonOrOrgInfo.DoesNotExist: - pass - if not set_tags and not reset_tags: - return - update_tags(self.request, self.draft, - comment=comment, - person=self.person, - set_tags=set_tags, - reset_tags=reset_tags, - extra_notify=extra_notify, - send_email=send_email) - - def save_state(self): - comment = self.cleaned_data.get('comment') - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - from ietf.doc.models import State - state = State.objects.get(pk=self.cleaned_data.get('new_state')) - - old_state = self.draft.get_state("draft-stream-%s" % self.draft.stream_id) - if state==old_state: - self.save_tags() - return - - self.save_tags(False) - new_tags = self.cleaned_data.get('tags') - - set_tags = [tag for tag in self.available_tags if str(tag.pk) in new_tags and tag not in self.tags] - reset_tags = [tag for tag in self.available_tags if str(tag.pk) not in new_tags and tag in self.tags] - - weeks = self.cleaned_data.get('weeks') - estimated_date = None - if weeks: - now = datetime.date.today() - estimated_date = now + datetime.timedelta(weeks=weeks) - - update_state(self.request, self.draft, - comment=comment, - person=self.person, - to_state=state, - estimated_date=estimated_date, - added_tags=set_tags, - removed_tags=reset_tags) - - def save(self): - self.save_state() - - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - comment = self.cleaned_data.get('comment').strip() - if comment: - e = DocEvent(type="added_comment") - e.time = datetime.datetime.now() - e.by = self.person - e.doc_id = self.draft.pk - e.desc = comment - e.save() - - -class StreamDelegatesForm(forms.Form): - email = forms.EmailField() - - def __init__(self, *args, **kwargs): - self.stream = kwargs.pop('stream') - super(StreamDelegatesForm, self).__init__(*args, **kwargs) - - def get_person(self, email): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - persons = Person.objects.filter(email__address=email).distinct() - else: - persons = PersonOrOrgInfo.objects.filter(emailaddress__address=email).distinct() - if not persons: - return None - return persons[0] - - def clean_email(self): - email = self.cleaned_data.get('email') - self.person = self.get_person(email) - if not self.person: - raise forms.ValidationError('There is no user with this email in the system') - return email - - def save(self): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - stream_group = Group.objects.get(acronym=self.stream.slug) - save_group_in_history(stream_group) - Role.objects.get_or_create(person=self.person, - group=stream_group, - name=RoleName.objects.get(slug="delegate"), - email=Email.objects.get(address=self.cleaned_data.get('email'))) - return - - StreamDelegate.objects.get_or_create( - person=self.person, - stream=self.stream) diff --git a/ietf/ietfworkflows/migrations/.gitignore b/ietf/ietfworkflows/migrations/.gitignore deleted file mode 100644 index a74b07aee..000000000 --- a/ietf/ietfworkflows/migrations/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/*.pyc diff --git a/ietf/ietfworkflows/migrations/0001_initial.py b/ietf/ietfworkflows/migrations/0001_initial.py deleted file mode 100644 index 7d9f29e4f..000000000 --- a/ietf/ietfworkflows/migrations/0001_initial.py +++ /dev/null @@ -1,148 +0,0 @@ - -from south.db import db -from django.db import models -from ietf.ietfworkflows.models import * - -class Migration: - - def forwards(self, orm): - - # Adding model 'WGWorkflow' - db.create_table('ietfworkflows_wgworkflow', ( - ('workflow_ptr', orm['ietfworkflows.WGWorkflow:workflow_ptr']), - )) - db.send_create_signal('ietfworkflows', ['WGWorkflow']) - - # Adding model 'ObjectWorkflowHistoryEntry' - db.create_table('ietfworkflows_objectworkflowhistoryentry', ( - ('id', orm['ietfworkflows.ObjectWorkflowHistoryEntry:id']), - ('content_type', orm['ietfworkflows.ObjectWorkflowHistoryEntry:content_type']), - ('content_id', orm['ietfworkflows.ObjectWorkflowHistoryEntry:content_id']), - ('from_state', orm['ietfworkflows.ObjectWorkflowHistoryEntry:from_state']), - ('to_state', orm['ietfworkflows.ObjectWorkflowHistoryEntry:to_state']), - ('transition_date', orm['ietfworkflows.ObjectWorkflowHistoryEntry:transition_date']), - ('comment', orm['ietfworkflows.ObjectWorkflowHistoryEntry:comment']), - )) - db.send_create_signal('ietfworkflows', ['ObjectWorkflowHistoryEntry']) - - # Adding model 'ObjectAnnotationTagHistoryEntry' - db.create_table('ietfworkflows_objectannotationtaghistoryentry', ( - ('id', orm['ietfworkflows.ObjectAnnotationTagHistoryEntry:id']), - ('content_type', orm['ietfworkflows.ObjectAnnotationTagHistoryEntry:content_type']), - ('content_id', orm['ietfworkflows.ObjectAnnotationTagHistoryEntry:content_id']), - ('setted', orm['ietfworkflows.ObjectAnnotationTagHistoryEntry:setted']), - ('unsetted', orm['ietfworkflows.ObjectAnnotationTagHistoryEntry:unsetted']), - ('change_date', orm['ietfworkflows.ObjectAnnotationTagHistoryEntry:change_date']), - ('comment', orm['ietfworkflows.ObjectAnnotationTagHistoryEntry:comment']), - )) - db.send_create_signal('ietfworkflows', ['ObjectAnnotationTagHistoryEntry']) - - # Adding model 'AnnotationTag' - db.create_table('ietfworkflows_annotationtag', ( - ('id', orm['ietfworkflows.AnnotationTag:id']), - ('name', orm['ietfworkflows.AnnotationTag:name']), - ('workflow', orm['ietfworkflows.AnnotationTag:workflow']), - ('permission', orm['ietfworkflows.AnnotationTag:permission']), - )) - db.send_create_signal('ietfworkflows', ['AnnotationTag']) - - # Adding model 'AnnotationTagObjectRelation' - db.create_table('ietfworkflows_annotationtagobjectrelation', ( - ('id', orm['ietfworkflows.AnnotationTagObjectRelation:id']), - ('content_type', orm['ietfworkflows.AnnotationTagObjectRelation:content_type']), - ('content_id', orm['ietfworkflows.AnnotationTagObjectRelation:content_id']), - ('annotation_tag', orm['ietfworkflows.AnnotationTagObjectRelation:annotation_tag']), - )) - db.send_create_signal('ietfworkflows', ['AnnotationTagObjectRelation']) - - - - def backwards(self, orm): - - # Deleting model 'WGWorkflow' - db.delete_table('ietfworkflows_wgworkflow') - - # Deleting model 'ObjectWorkflowHistoryEntry' - db.delete_table('ietfworkflows_objectworkflowhistoryentry') - - # Deleting model 'ObjectAnnotationTagHistoryEntry' - db.delete_table('ietfworkflows_objectannotationtaghistoryentry') - - # Deleting model 'AnnotationTag' - db.delete_table('ietfworkflows_annotationtag') - - # Deleting model 'AnnotationTagObjectRelation' - db.delete_table('ietfworkflows_annotationtagobjectrelation') - - - - models = { - 'contenttypes.contenttype': { - 'Meta': {'unique_together': "(('app_label', 'model'),)", 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - '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'}) - }, - 'ietfworkflows.annotationtag': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'annotation_tags'", 'to': "orm['workflows.Workflow']"}) - }, - 'ietfworkflows.annotationtagobjectrelation': { - 'annotation_tag': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.AnnotationTag']"}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'annotation_tags'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'ietfworkflows.objectannotationtaghistoryentry': { - 'change_date': ('django.db.models.fields.DateTimeField', [], {}), - 'comment': ('django.db.models.fields.TextField', [], {}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'annotation_tags_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'setted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'unsetted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.objectworkflowhistoryentry': { - 'comment': ('django.db.models.fields.TextField', [], {}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'from_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'to_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'transition_date': ('django.db.models.fields.DateTimeField', [], {}) - }, - 'ietfworkflows.wgworkflow': { - 'workflow_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['workflows.Workflow']", 'unique': 'True', 'primary_key': 'True'}) - }, - 'permissions.permission': { - 'codename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'content_types': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}) - }, - 'workflows.state': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'transitions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['workflows.Transition']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'states'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.transition': { - 'condition': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), - 'destination': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'destination_state'", 'null': 'True', 'to': "orm['workflows.State']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.workflow': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'initial_state': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_state'", 'null': 'True', 'to': "orm['workflows.State']"}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['permissions.Permission']", 'symmetrical': 'False'}) - } - } - - complete_apps = ['ietfworkflows'] diff --git a/ietf/ietfworkflows/migrations/0002_add_selected_states_and_tags.py b/ietf/ietfworkflows/migrations/0002_add_selected_states_and_tags.py deleted file mode 100644 index 7545559b7..000000000 --- a/ietf/ietfworkflows/migrations/0002_add_selected_states_and_tags.py +++ /dev/null @@ -1,107 +0,0 @@ - -from south.db import db -from django.db import models -from ietf.ietfworkflows.models import * - -class Migration: - - def forwards(self, orm): - - # Adding ManyToManyField 'WGWorkflow.selected_tags' - db.create_table('ietfworkflows_wgworkflow_selected_tags', ( - ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), - ('wgworkflow', models.ForeignKey(orm.WGWorkflow, null=False)), - ('annotationtag', models.ForeignKey(orm.AnnotationTag, null=False)) - )) - - # Adding ManyToManyField 'WGWorkflow.selected_states' - db.create_table('ietfworkflows_wgworkflow_selected_states', ( - ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), - ('wgworkflow', models.ForeignKey(orm.WGWorkflow, null=False)), - ('state', models.ForeignKey(orm['workflows.State'], null=False)) - )) - - - - def backwards(self, orm): - - # Dropping ManyToManyField 'WGWorkflow.selected_tags' - db.delete_table('ietfworkflows_wgworkflow_selected_tags') - - # Dropping ManyToManyField 'WGWorkflow.selected_states' - db.delete_table('ietfworkflows_wgworkflow_selected_states') - - - - models = { - 'contenttypes.contenttype': { - 'Meta': {'unique_together': "(('app_label', 'model'),)", 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - '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'}) - }, - 'ietfworkflows.annotationtag': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'annotation_tags'", 'to': "orm['workflows.Workflow']"}) - }, - 'ietfworkflows.annotationtagobjectrelation': { - 'annotation_tag': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.AnnotationTag']"}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'annotation_tags'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'ietfworkflows.objectannotationtaghistoryentry': { - 'change_date': ('django.db.models.fields.DateTimeField', [], {}), - 'comment': ('django.db.models.fields.TextField', [], {}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'annotation_tags_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'setted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'unsetted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.objectworkflowhistoryentry': { - 'comment': ('django.db.models.fields.TextField', [], {}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'from_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'to_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'transition_date': ('django.db.models.fields.DateTimeField', [], {}) - }, - 'ietfworkflows.wgworkflow': { - 'selected_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['workflows.State']"}), - 'selected_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['ietfworkflows.AnnotationTag']"}), - 'workflow_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['workflows.Workflow']", 'unique': 'True', 'primary_key': 'True'}) - }, - 'permissions.permission': { - 'codename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'content_types': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}) - }, - 'workflows.state': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'transitions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['workflows.Transition']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'states'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.transition': { - 'condition': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), - 'destination': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'destination_state'", 'null': 'True', 'to': "orm['workflows.State']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.workflow': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'initial_state': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_state'", 'null': 'True', 'to': "orm['workflows.State']"}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['permissions.Permission']", 'symmetrical': 'False'}) - } - } - - complete_apps = ['ietfworkflows'] diff --git a/ietf/ietfworkflows/migrations/0003_add_person_to_history.py b/ietf/ietfworkflows/migrations/0003_add_person_to_history.py deleted file mode 100644 index 85f634656..000000000 --- a/ietf/ietfworkflows/migrations/0003_add_person_to_history.py +++ /dev/null @@ -1,119 +0,0 @@ - -from south.db import db -from django.db import models -from ietf.ietfworkflows.models import * - -class Migration: - - def forwards(self, orm): - - # Adding field 'ObjectWorkflowHistoryEntry.person' - db.add_column('ietfworkflows_objectworkflowhistoryentry', 'person', orm['ietfworkflows.objectworkflowhistoryentry:person']) - - # Adding field 'ObjectAnnotationTagHistoryEntry.person' - db.add_column('ietfworkflows_objectannotationtaghistoryentry', 'person', orm['ietfworkflows.objectannotationtaghistoryentry:person']) - - - - def backwards(self, orm): - - # Deleting field 'ObjectWorkflowHistoryEntry.person' - db.delete_column('ietfworkflows_objectworkflowhistoryentry', 'person_id') - - # Deleting field 'ObjectAnnotationTagHistoryEntry.person' - db.delete_column('ietfworkflows_objectannotationtaghistoryentry', 'person_id') - - - - models = { - 'contenttypes.contenttype': { - 'Meta': {'unique_together': "(('app_label', 'model'),)", 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - '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'}) - }, - 'idtracker.personororginfo': { - 'Meta': {'db_table': "'person_or_org_info'"}, - 'address_type': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'created_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'date_created': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}), - 'date_modified': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'first_name_key': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'last_name_key': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'middle_initial': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'middle_initial_key': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'modified_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'name_prefix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'name_suffix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'person_or_org_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'record_type': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.annotationtag': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'annotation_tags'", 'to': "orm['workflows.Workflow']"}) - }, - 'ietfworkflows.annotationtagobjectrelation': { - 'annotation_tag': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.AnnotationTag']"}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'annotation_tags'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'ietfworkflows.objectannotationtaghistoryentry': { - 'change_date': ('django.db.models.fields.DateTimeField', [], {}), - 'comment': ('django.db.models.fields.TextField', [], {}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'annotation_tags_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}), - 'setted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'unsetted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.objectworkflowhistoryentry': { - 'comment': ('django.db.models.fields.TextField', [], {}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'from_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}), - 'to_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'transition_date': ('django.db.models.fields.DateTimeField', [], {}) - }, - 'ietfworkflows.wgworkflow': { - 'selected_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['workflows.State']", 'symmetrical': 'False'}), - 'selected_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['ietfworkflows.AnnotationTag']", 'symmetrical': 'False'}), - 'workflow_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['workflows.Workflow']", 'unique': 'True', 'primary_key': 'True'}) - }, - 'permissions.permission': { - 'codename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'content_types': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}) - }, - 'workflows.state': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'transitions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['workflows.Transition']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'states'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.transition': { - 'condition': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), - 'destination': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'destination_state'", 'null': 'True', 'to': "orm['workflows.State']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.workflow': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'initial_state': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_state'", 'null': 'True', 'to': "orm['workflows.State']"}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['permissions.Permission']", 'symmetrical': 'False'}) - } - } - - complete_apps = ['ietfworkflows'] diff --git a/ietf/ietfworkflows/migrations/0004_add_object_state_dates.py b/ietf/ietfworkflows/migrations/0004_add_object_state_dates.py deleted file mode 100644 index c71d2a08e..000000000 --- a/ietf/ietfworkflows/migrations/0004_add_object_state_dates.py +++ /dev/null @@ -1,132 +0,0 @@ - -from south.db import db -from django.db import models -from ietf.ietfworkflows.models import * - -class Migration: - - def forwards(self, orm): - - # Adding model 'StateObjectRelationMetadata' - db.create_table('ietfworkflows_stateobjectrelationmetadata', ( - ('id', orm['ietfworkflows.stateobjectrelationmetadata:id']), - ('relation', orm['ietfworkflows.stateobjectrelationmetadata:relation']), - ('from_date', orm['ietfworkflows.stateobjectrelationmetadata:from_date']), - ('estimated_date', orm['ietfworkflows.stateobjectrelationmetadata:estimated_date']), - )) - db.send_create_signal('ietfworkflows', ['StateObjectRelationMetadata']) - - - - def backwards(self, orm): - - # Deleting model 'StateObjectRelationMetadata' - db.delete_table('ietfworkflows_stateobjectrelationmetadata') - - - - models = { - 'contenttypes.contenttype': { - 'Meta': {'unique_together': "(('app_label', 'model'),)", 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - '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'}) - }, - 'idtracker.personororginfo': { - 'Meta': {'db_table': "'person_or_org_info'"}, - 'address_type': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'created_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'date_created': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}), - 'date_modified': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'first_name_key': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'last_name_key': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'middle_initial': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'middle_initial_key': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'modified_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'name_prefix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'name_suffix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'person_or_org_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'record_type': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.annotationtag': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'annotation_tags'", 'to': "orm['workflows.Workflow']"}) - }, - 'ietfworkflows.annotationtagobjectrelation': { - 'annotation_tag': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.AnnotationTag']"}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'annotation_tags'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'ietfworkflows.objectannotationtaghistoryentry': { - 'change_date': ('django.db.models.fields.DateTimeField', [], {}), - 'comment': ('django.db.models.fields.TextField', [], {}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'annotation_tags_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}), - 'setted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'unsetted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.objectworkflowhistoryentry': { - 'comment': ('django.db.models.fields.TextField', [], {}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'from_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}), - 'to_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'transition_date': ('django.db.models.fields.DateTimeField', [], {}) - }, - 'ietfworkflows.stateobjectrelationmetadata': { - 'estimated_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), - 'from_date': ('django.db.models.fields.DateTimeField', [], {}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'relation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.StateObjectRelation']"}) - }, - 'ietfworkflows.wgworkflow': { - 'selected_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['workflows.State']", 'symmetrical': 'False'}), - 'selected_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['ietfworkflows.AnnotationTag']", 'symmetrical': 'False'}), - 'workflow_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['workflows.Workflow']", 'unique': 'True', 'primary_key': 'True'}) - }, - 'permissions.permission': { - 'codename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'content_types': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}) - }, - 'workflows.state': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'transitions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['workflows.Transition']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'states'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.stateobjectrelation': { - 'Meta': {'unique_together': "(('content_type', 'content_id', 'state'),)"}, - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'state_object'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) - }, - 'workflows.transition': { - 'condition': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), - 'destination': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'destination_state'", 'null': 'True', 'to': "orm['workflows.State']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.workflow': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'initial_state': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_state'", 'null': 'True', 'to': "orm['workflows.State']"}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['permissions.Permission']", 'symmetrical': 'False'}) - } - } - - complete_apps = ['ietfworkflows'] diff --git a/ietf/ietfworkflows/migrations/0005_add_streams.py b/ietf/ietfworkflows/migrations/0005_add_streams.py deleted file mode 100644 index 1e3de388c..000000000 --- a/ietf/ietfworkflows/migrations/0005_add_streams.py +++ /dev/null @@ -1,209 +0,0 @@ - -from south.db import db -from django.db import models -from ietf.ietfworkflows.models import * - -class Migration: - - def forwards(self, orm): - - # Adding model 'StreamedID' - db.create_table('ietfworkflows_streamedid', ( - ('id', orm['ietfworkflows.streamedid:id']), - ('draft', orm['ietfworkflows.streamedid:draft']), - ('stream', orm['ietfworkflows.streamedid:stream']), - )) - db.send_create_signal('ietfworkflows', ['StreamedID']) - - # Adding model 'Stream' - db.create_table('ietfworkflows_stream', ( - ('id', orm['ietfworkflows.stream:id']), - ('name', orm['ietfworkflows.stream:name']), - ('with_groups', orm['ietfworkflows.stream:with_groups']), - ('group_model', orm['ietfworkflows.stream:group_model']), - ('group_chair_model', orm['ietfworkflows.stream:group_chair_model']), - ('workflow', orm['ietfworkflows.stream:workflow']), - )) - db.send_create_signal('ietfworkflows', ['Stream']) - - - - def backwards(self, orm): - - # Deleting model 'StreamedID' - db.delete_table('ietfworkflows_streamedid') - - # Deleting model 'Stream' - db.delete_table('ietfworkflows_stream') - - - - models = { - 'contenttypes.contenttype': { - 'Meta': {'unique_together': "(('app_label', 'model'),)", 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - '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'}) - }, - 'idtracker.acronym': { - 'Meta': {'db_table': "'acronym'"}, - 'acronym': ('django.db.models.fields.CharField', [], {'max_length': '12'}), - 'acronym_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name_key': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'idtracker.idintendedstatus': { - 'Meta': {'db_table': "'id_intended_status'"}, - 'intended_status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'intended_status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.idstatus': { - 'Meta': {'db_table': "'id_status'"}, - 'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.internetdraft': { - 'Meta': {'db_table': "'internet_drafts'"}, - 'abstract': ('django.db.models.fields.TextField', [], {}), - 'b_approve_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'b_discussion_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'b_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'dunn_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True'}), - 'expired_tombstone': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'extension_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'file_type': ('django.db.models.fields.CharField', [], {'max_length': '20'}), - 'filename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), - 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Acronym']", 'db_column': "'group_acronym_id'"}), - 'id_document_key': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'id_document_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'intended_status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDIntendedStatus']"}), - 'last_modified_date': ('django.db.models.fields.DateField', [], {}), - 'lc_changes': ('django.db.models.fields.CharField', [], {'max_length': '3', 'null': 'True'}), - 'lc_expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'lc_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'local_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), - 'replaced_by': ('django.db.models.fields.related.ForeignKey', ["orm['idtracker.InternetDraft']"], {'related_name': "'replaces_set'", 'null': 'True', 'db_column': "'replaced_by'", 'blank': 'True'}), - 'review_by_rfc_editor': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'revision': ('django.db.models.fields.CharField', [], {'max_length': '2'}), - 'revision_date': ('django.db.models.fields.DateField', [], {}), - 'rfc_number': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), - 'shepherd': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'null': 'True', 'blank': 'True'}), - 'start_date': ('django.db.models.fields.DateField', [], {}), - 'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDStatus']"}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'id_document_name'"}), - 'txt_page_count': ('django.db.models.fields.IntegerField', [], {}), - 'wgreturn_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}) - }, - 'idtracker.personororginfo': { - 'Meta': {'db_table': "'person_or_org_info'"}, - 'address_type': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'created_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'date_created': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}), - 'date_modified': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'first_name_key': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'last_name_key': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'middle_initial': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'middle_initial_key': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'modified_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'name_prefix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'name_suffix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'person_or_org_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'record_type': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.annotationtag': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'annotation_tags'", 'to': "orm['workflows.Workflow']"}) - }, - 'ietfworkflows.annotationtagobjectrelation': { - 'annotation_tag': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.AnnotationTag']"}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'annotation_tags'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'ietfworkflows.objectannotationtaghistoryentry': { - 'change_date': ('django.db.models.fields.DateTimeField', [], {}), - 'comment': ('django.db.models.fields.TextField', [], {}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'annotation_tags_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}), - 'setted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'unsetted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.objectworkflowhistoryentry': { - 'comment': ('django.db.models.fields.TextField', [], {}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'from_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}), - 'to_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'transition_date': ('django.db.models.fields.DateTimeField', [], {}) - }, - 'ietfworkflows.stateobjectrelationmetadata': { - 'estimated_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), - 'from_date': ('django.db.models.fields.DateTimeField', [], {}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'relation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.StateObjectRelation']"}) - }, - 'ietfworkflows.stream': { - 'group_chair_model': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), - 'group_model': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'with_groups': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.WGWorkflow']"}) - }, - 'ietfworkflows.streamedid': { - 'draft': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['idtracker.InternetDraft']", 'unique': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.Stream']"}) - }, - 'ietfworkflows.wgworkflow': { - 'selected_states': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['workflows.State']", 'null': 'True', 'blank': 'True'}), - 'selected_tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['ietfworkflows.AnnotationTag']", 'null': 'True', 'blank': 'True'}), - 'workflow_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['workflows.Workflow']", 'unique': 'True', 'primary_key': 'True'}) - }, - 'permissions.permission': { - 'codename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'content_types': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}) - }, - 'workflows.state': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'transitions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['workflows.Transition']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'states'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.stateobjectrelation': { - 'Meta': {'unique_together': "(('content_type', 'content_id', 'state'),)"}, - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'state_object'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) - }, - 'workflows.transition': { - 'condition': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), - 'destination': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'destination_state'", 'null': 'True', 'to': "orm['workflows.State']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.workflow': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'initial_state': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_state'", 'null': 'True', 'to': "orm['workflows.State']"}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['permissions.Permission']", 'symmetrical': 'False'}) - } - } - - complete_apps = ['ietfworkflows'] diff --git a/ietf/ietfworkflows/migrations/0006_add_group_to_streamed_id.py b/ietf/ietfworkflows/migrations/0006_add_group_to_streamed_id.py deleted file mode 100644 index 9460f0ac6..000000000 --- a/ietf/ietfworkflows/migrations/0006_add_group_to_streamed_id.py +++ /dev/null @@ -1,198 +0,0 @@ - -from south.db import db -from django.db import models -from ietf.ietfworkflows.models import * - -class Migration: - - def forwards(self, orm): - - # Adding field 'StreamedID.content_type' - db.add_column('ietfworkflows_streamedid', 'content_type', orm['ietfworkflows.streamedid:content_type']) - - # Adding field 'StreamedID.content_id' - db.add_column('ietfworkflows_streamedid', 'content_id', orm['ietfworkflows.streamedid:content_id']) - - - - def backwards(self, orm): - - # Deleting field 'StreamedID.content_type' - db.delete_column('ietfworkflows_streamedid', 'content_type_id') - - # Deleting field 'StreamedID.content_id' - db.delete_column('ietfworkflows_streamedid', 'content_id') - - - - models = { - 'contenttypes.contenttype': { - 'Meta': {'unique_together': "(('app_label', 'model'),)", 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - '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'}) - }, - 'idtracker.acronym': { - 'Meta': {'db_table': "'acronym'"}, - 'acronym': ('django.db.models.fields.CharField', [], {'max_length': '12'}), - 'acronym_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name_key': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'idtracker.idintendedstatus': { - 'Meta': {'db_table': "'id_intended_status'"}, - 'intended_status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'intended_status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.idstatus': { - 'Meta': {'db_table': "'id_status'"}, - 'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.internetdraft': { - 'Meta': {'db_table': "'internet_drafts'"}, - 'abstract': ('django.db.models.fields.TextField', [], {}), - 'b_approve_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'b_discussion_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'b_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'dunn_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True'}), - 'expired_tombstone': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'extension_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'file_type': ('django.db.models.fields.CharField', [], {'max_length': '20'}), - 'filename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), - 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Acronym']", 'db_column': "'group_acronym_id'"}), - 'id_document_key': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'id_document_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'intended_status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDIntendedStatus']"}), - 'last_modified_date': ('django.db.models.fields.DateField', [], {}), - 'lc_changes': ('django.db.models.fields.CharField', [], {'max_length': '3', 'null': 'True'}), - 'lc_expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'lc_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'local_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), - 'replaced_by': ('django.db.models.fields.related.ForeignKey', ["orm['idtracker.InternetDraft']"], {'related_name': "'replaces_set'", 'null': 'True', 'db_column': "'replaced_by'", 'blank': 'True'}), - 'review_by_rfc_editor': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'revision': ('django.db.models.fields.CharField', [], {'max_length': '2'}), - 'revision_date': ('django.db.models.fields.DateField', [], {}), - 'rfc_number': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), - 'shepherd': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'null': 'True', 'blank': 'True'}), - 'start_date': ('django.db.models.fields.DateField', [], {}), - 'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDStatus']"}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'id_document_name'"}), - 'txt_page_count': ('django.db.models.fields.IntegerField', [], {}), - 'wgreturn_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}) - }, - 'idtracker.personororginfo': { - 'Meta': {'db_table': "'person_or_org_info'"}, - 'address_type': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'created_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'date_created': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}), - 'date_modified': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'first_name_key': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'last_name_key': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'middle_initial': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'middle_initial_key': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'modified_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'name_prefix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'name_suffix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'person_or_org_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'record_type': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.annotationtag': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'annotation_tags'", 'to': "orm['workflows.Workflow']"}) - }, - 'ietfworkflows.annotationtagobjectrelation': { - 'annotation_tag': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.AnnotationTag']"}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'annotation_tags'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'ietfworkflows.objectannotationtaghistoryentry': { - 'change_date': ('django.db.models.fields.DateTimeField', [], {}), - 'comment': ('django.db.models.fields.TextField', [], {}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'annotation_tags_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}), - 'setted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'unsetted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.objectworkflowhistoryentry': { - 'comment': ('django.db.models.fields.TextField', [], {}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'from_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}), - 'to_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'transition_date': ('django.db.models.fields.DateTimeField', [], {}) - }, - 'ietfworkflows.stateobjectrelationmetadata': { - 'estimated_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), - 'from_date': ('django.db.models.fields.DateTimeField', [], {}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'relation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.StateObjectRelation']"}) - }, - 'ietfworkflows.stream': { - 'group_chair_model': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), - 'group_model': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'with_groups': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.WGWorkflow']"}) - }, - 'ietfworkflows.streamedid': { - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'streamed_id'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'draft': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['idtracker.InternetDraft']", 'unique': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.Stream']"}) - }, - 'ietfworkflows.wgworkflow': { - 'selected_states': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['workflows.State']", 'null': 'True', 'blank': 'True'}), - 'selected_tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['ietfworkflows.AnnotationTag']", 'null': 'True', 'blank': 'True'}), - 'workflow_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['workflows.Workflow']", 'unique': 'True', 'primary_key': 'True'}) - }, - 'permissions.permission': { - 'codename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'content_types': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}) - }, - 'workflows.state': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'transitions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['workflows.Transition']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'states'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.stateobjectrelation': { - 'Meta': {'unique_together': "(('content_type', 'content_id', 'state'),)"}, - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'state_object'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) - }, - 'workflows.transition': { - 'condition': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), - 'destination': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'destination_state'", 'null': 'True', 'to': "orm['workflows.State']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.workflow': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'initial_state': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_state'", 'null': 'True', 'to': "orm['workflows.State']"}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['permissions.Permission']", 'symmetrical': 'False'}) - } - } - - complete_apps = ['ietfworkflows'] diff --git a/ietf/ietfworkflows/migrations/0007_do_stream_optional.py b/ietf/ietfworkflows/migrations/0007_do_stream_optional.py deleted file mode 100644 index bcb758aab..000000000 --- a/ietf/ietfworkflows/migrations/0007_do_stream_optional.py +++ /dev/null @@ -1,194 +0,0 @@ - -from south.db import db -from django.db import models -from ietf.ietfworkflows.models import * - -class Migration: - - def forwards(self, orm): - - # Changing field 'StreamedID.stream' - # (to signature: django.db.models.fields.related.ForeignKey(to=orm['ietfworkflows.Stream'], null=True, blank=True)) - db.alter_column('ietfworkflows_streamedid', 'stream_id', orm['ietfworkflows.streamedid:stream']) - - - - def backwards(self, orm): - - # Changing field 'StreamedID.stream' - # (to signature: django.db.models.fields.related.ForeignKey(to=orm['ietfworkflows.Stream'])) - db.alter_column('ietfworkflows_streamedid', 'stream_id', orm['ietfworkflows.streamedid:stream']) - - - - models = { - 'contenttypes.contenttype': { - 'Meta': {'unique_together': "(('app_label', 'model'),)", 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - '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'}) - }, - 'idtracker.acronym': { - 'Meta': {'db_table': "'acronym'"}, - 'acronym': ('django.db.models.fields.CharField', [], {'max_length': '12'}), - 'acronym_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name_key': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'idtracker.idintendedstatus': { - 'Meta': {'db_table': "'id_intended_status'"}, - 'intended_status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'intended_status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.idstatus': { - 'Meta': {'db_table': "'id_status'"}, - 'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.internetdraft': { - 'Meta': {'db_table': "'internet_drafts'"}, - 'abstract': ('django.db.models.fields.TextField', [], {}), - 'b_approve_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'b_discussion_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'b_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'dunn_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True'}), - 'expired_tombstone': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'extension_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'file_type': ('django.db.models.fields.CharField', [], {'max_length': '20'}), - 'filename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), - 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Acronym']", 'db_column': "'group_acronym_id'"}), - 'id_document_key': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'id_document_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'intended_status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDIntendedStatus']"}), - 'last_modified_date': ('django.db.models.fields.DateField', [], {}), - 'lc_changes': ('django.db.models.fields.CharField', [], {'max_length': '3', 'null': 'True'}), - 'lc_expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'lc_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'local_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), - 'replaced_by': ('django.db.models.fields.related.ForeignKey', ["orm['idtracker.InternetDraft']"], {'related_name': "'replaces_set'", 'null': 'True', 'db_column': "'replaced_by'", 'blank': 'True'}), - 'review_by_rfc_editor': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'revision': ('django.db.models.fields.CharField', [], {'max_length': '2'}), - 'revision_date': ('django.db.models.fields.DateField', [], {}), - 'rfc_number': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), - 'shepherd': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'null': 'True', 'blank': 'True'}), - 'start_date': ('django.db.models.fields.DateField', [], {}), - 'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDStatus']"}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'id_document_name'"}), - 'txt_page_count': ('django.db.models.fields.IntegerField', [], {}), - 'wgreturn_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}) - }, - 'idtracker.personororginfo': { - 'Meta': {'db_table': "'person_or_org_info'"}, - 'address_type': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'created_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'date_created': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}), - 'date_modified': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'first_name_key': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'last_name_key': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'middle_initial': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'middle_initial_key': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'modified_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'name_prefix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'name_suffix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'person_or_org_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'record_type': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.annotationtag': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'annotation_tags'", 'to': "orm['workflows.Workflow']"}) - }, - 'ietfworkflows.annotationtagobjectrelation': { - 'annotation_tag': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.AnnotationTag']"}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'annotation_tags'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'ietfworkflows.objectannotationtaghistoryentry': { - 'change_date': ('django.db.models.fields.DateTimeField', [], {}), - 'comment': ('django.db.models.fields.TextField', [], {}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'annotation_tags_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}), - 'setted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'unsetted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.objectworkflowhistoryentry': { - 'comment': ('django.db.models.fields.TextField', [], {}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'from_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}), - 'to_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'transition_date': ('django.db.models.fields.DateTimeField', [], {}) - }, - 'ietfworkflows.stateobjectrelationmetadata': { - 'estimated_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), - 'from_date': ('django.db.models.fields.DateTimeField', [], {}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'relation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.StateObjectRelation']"}) - }, - 'ietfworkflows.stream': { - 'group_chair_model': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), - 'group_model': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'with_groups': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.WGWorkflow']"}) - }, - 'ietfworkflows.streamedid': { - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'streamed_id'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'draft': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['idtracker.InternetDraft']", 'unique': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.Stream']", 'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.wgworkflow': { - 'selected_states': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['workflows.State']", 'null': 'True', 'blank': 'True'}), - 'selected_tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['ietfworkflows.AnnotationTag']", 'null': 'True', 'blank': 'True'}), - 'workflow_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['workflows.Workflow']", 'unique': 'True', 'primary_key': 'True'}) - }, - 'permissions.permission': { - 'codename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'content_types': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}) - }, - 'workflows.state': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'transitions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['workflows.Transition']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'states'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.stateobjectrelation': { - 'Meta': {'unique_together': "(('content_type', 'content_id', 'state'),)"}, - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'state_object'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) - }, - 'workflows.transition': { - 'condition': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), - 'destination': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'destination_state'", 'null': 'True', 'to': "orm['workflows.State']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.workflow': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'initial_state': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_state'", 'null': 'True', 'to': "orm['workflows.State']"}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['permissions.Permission']", 'symmetrical': 'False'}) - } - } - - complete_apps = ['ietfworkflows'] diff --git a/ietf/ietfworkflows/migrations/0008_refactor_history_entries.py b/ietf/ietfworkflows/migrations/0008_refactor_history_entries.py deleted file mode 100644 index 40bc6f36d..000000000 --- a/ietf/ietfworkflows/migrations/0008_refactor_history_entries.py +++ /dev/null @@ -1,267 +0,0 @@ - -from south.db import db -from django.db import models -from ietf.ietfworkflows.models import * - -class Migration: - - def forwards(self, orm): - - # Deleting model 'objectworkflowhistoryentry' - db.delete_table('ietfworkflows_objectworkflowhistoryentry') - - # Deleting model 'objectannotationtaghistoryentry' - db.delete_table('ietfworkflows_objectannotationtaghistoryentry') - - # Adding model 'ObjectAnnotationTagHistoryEntry' - db.create_table('ietfworkflows_objectannotationtaghistoryentry', ( - ('objecthistoryentry_ptr', orm['ietfworkflows.objectannotationtaghistoryentry:objecthistoryentry_ptr']), - ('setted', orm['ietfworkflows.objectannotationtaghistoryentry:setted']), - ('unsetted', orm['ietfworkflows.objectannotationtaghistoryentry:unsetted']), - )) - db.send_create_signal('ietfworkflows', ['ObjectAnnotationTagHistoryEntry']) - - # Adding model 'ObjectHistoryEntry' - db.create_table('ietfworkflows_objecthistoryentry', ( - ('id', orm['ietfworkflows.objecthistoryentry:id']), - ('content_type', orm['ietfworkflows.objecthistoryentry:content_type']), - ('content_id', orm['ietfworkflows.objecthistoryentry:content_id']), - ('date', orm['ietfworkflows.objecthistoryentry:date']), - ('comment', orm['ietfworkflows.objecthistoryentry:comment']), - ('person', orm['ietfworkflows.objecthistoryentry:person']), - )) - db.send_create_signal('ietfworkflows', ['ObjectHistoryEntry']) - - # Adding model 'ObjectStreamHistoryEntry' - db.create_table('ietfworkflows_objectstreamhistoryentry', ( - ('objecthistoryentry_ptr', orm['ietfworkflows.objectstreamhistoryentry:objecthistoryentry_ptr']), - ('from_stream', orm['ietfworkflows.objectstreamhistoryentry:from_stream']), - ('to_stream', orm['ietfworkflows.objectstreamhistoryentry:to_stream']), - )) - db.send_create_signal('ietfworkflows', ['ObjectStreamHistoryEntry']) - - # Adding model 'ObjectWorkflowHistoryEntry' - db.create_table('ietfworkflows_objectworkflowhistoryentry', ( - ('objecthistoryentry_ptr', orm['ietfworkflows.objectworkflowhistoryentry:objecthistoryentry_ptr']), - ('from_state', orm['ietfworkflows.objectworkflowhistoryentry:from_state']), - ('to_state', orm['ietfworkflows.objectworkflowhistoryentry:to_state']), - )) - db.send_create_signal('ietfworkflows', ['ObjectWorkflowHistoryEntry']) - - - def backwards(self, orm): - - # Deleting model 'ObjectAnnotationTagHistoryEntry' - db.delete_table('ietfworkflows_objectannotationtaghistoryentry') - - # Deleting model 'ObjectHistoryEntry' - db.delete_table('ietfworkflows_objecthistoryentry') - - # Deleting model 'ObjectStreamHistoryEntry' - db.delete_table('ietfworkflows_objectstreamhistoryentry') - - # Deleting model 'ObjectWorkflowHistoryEntry' - db.delete_table('ietfworkflows_objectworkflowhistoryentry') - - # Adding model 'objectworkflowhistoryentry' - db.create_table('ietfworkflows_objectworkflowhistoryentry', ( - ('comment', orm['ietfworkflows.objectworkflowhistoryentry:comment']), - ('from_state', orm['ietfworkflows.objectworkflowhistoryentry:from_state']), - ('to_state', orm['ietfworkflows.objectworkflowhistoryentry:to_state']), - ('content_type', orm['ietfworkflows.objectworkflowhistoryentry:content_type']), - ('person', orm['ietfworkflows.objectworkflowhistoryentry:person']), - ('content_id', orm['ietfworkflows.objectworkflowhistoryentry:content_id']), - ('id', orm['ietfworkflows.objectworkflowhistoryentry:id']), - ('transition_date', orm['ietfworkflows.objectworkflowhistoryentry:transition_date']), - )) - db.send_create_signal('ietfworkflows', ['objectworkflowhistoryentry']) - - # Adding model 'objectannotationtaghistoryentry' - db.create_table('ietfworkflows_objectannotationtaghistoryentry', ( - ('comment', orm['ietfworkflows.objectannotationtaghistoryentry:comment']), - ('person', orm['ietfworkflows.objectannotationtaghistoryentry:person']), - ('unsetted', orm['ietfworkflows.objectannotationtaghistoryentry:unsetted']), - ('content_type', orm['ietfworkflows.objectannotationtaghistoryentry:content_type']), - ('change_date', orm['ietfworkflows.objectannotationtaghistoryentry:change_date']), - ('setted', orm['ietfworkflows.objectannotationtaghistoryentry:setted']), - ('content_id', orm['ietfworkflows.objectannotationtaghistoryentry:content_id']), - ('id', orm['ietfworkflows.objectannotationtaghistoryentry:id']), - )) - db.send_create_signal('ietfworkflows', ['objectannotationtaghistoryentry']) - - - - models = { - 'contenttypes.contenttype': { - 'Meta': {'unique_together': "(('app_label', 'model'),)", 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - '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'}) - }, - 'idtracker.acronym': { - 'Meta': {'db_table': "'acronym'"}, - 'acronym': ('django.db.models.fields.CharField', [], {'max_length': '12'}), - 'acronym_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name_key': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'idtracker.idintendedstatus': { - 'Meta': {'db_table': "'id_intended_status'"}, - 'intended_status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'intended_status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.idstatus': { - 'Meta': {'db_table': "'id_status'"}, - 'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.internetdraft': { - 'Meta': {'db_table': "'internet_drafts'"}, - 'abstract': ('django.db.models.fields.TextField', [], {}), - 'b_approve_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'b_discussion_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'b_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'dunn_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True'}), - 'expired_tombstone': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'extension_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'file_type': ('django.db.models.fields.CharField', [], {'max_length': '20'}), - 'filename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), - 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Acronym']", 'db_column': "'group_acronym_id'"}), - 'id_document_key': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'id_document_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'intended_status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDIntendedStatus']"}), - 'last_modified_date': ('django.db.models.fields.DateField', [], {}), - 'lc_changes': ('django.db.models.fields.CharField', [], {'max_length': '3', 'null': 'True'}), - 'lc_expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'lc_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'local_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), - 'replaced_by': ('django.db.models.fields.related.ForeignKey', ["orm['idtracker.InternetDraft']"], {'related_name': "'replaces_set'", 'null': 'True', 'db_column': "'replaced_by'", 'blank': 'True'}), - 'review_by_rfc_editor': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'revision': ('django.db.models.fields.CharField', [], {'max_length': '2'}), - 'revision_date': ('django.db.models.fields.DateField', [], {}), - 'rfc_number': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), - 'shepherd': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'null': 'True', 'blank': 'True'}), - 'start_date': ('django.db.models.fields.DateField', [], {}), - 'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDStatus']"}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'id_document_name'"}), - 'txt_page_count': ('django.db.models.fields.IntegerField', [], {}), - 'wgreturn_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}) - }, - 'idtracker.personororginfo': { - 'Meta': {'db_table': "'person_or_org_info'"}, - 'address_type': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'created_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'date_created': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}), - 'date_modified': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'first_name_key': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'last_name_key': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'middle_initial': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'middle_initial_key': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'modified_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'name_prefix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'name_suffix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'person_or_org_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'record_type': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.annotationtag': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'annotation_tags'", 'to': "orm['workflows.Workflow']"}) - }, - 'ietfworkflows.annotationtagobjectrelation': { - 'annotation_tag': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.AnnotationTag']"}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'annotation_tags'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'ietfworkflows.objectannotationtaghistoryentry': { - 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), - 'setted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'unsetted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.objecthistoryentry': { - 'comment': ('django.db.models.fields.TextField', [], {}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}) - }, - 'ietfworkflows.objectstreamhistoryentry': { - 'from_stream': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), - 'to_stream': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.objectworkflowhistoryentry': { - 'from_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), - 'to_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'ietfworkflows.stateobjectrelationmetadata': { - 'estimated_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), - 'from_date': ('django.db.models.fields.DateTimeField', [], {}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'relation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.StateObjectRelation']"}) - }, - 'ietfworkflows.stream': { - 'group_chair_model': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), - 'group_model': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'with_groups': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.WGWorkflow']"}) - }, - 'ietfworkflows.streamedid': { - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'streamed_id'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'draft': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['idtracker.InternetDraft']", 'unique': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.Stream']", 'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.wgworkflow': { - 'selected_states': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['workflows.State']", 'null': 'True', 'blank': 'True'}), - 'selected_tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['ietfworkflows.AnnotationTag']", 'null': 'True', 'blank': 'True'}), - 'workflow_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['workflows.Workflow']", 'unique': 'True', 'primary_key': 'True'}) - }, - 'permissions.permission': { - 'codename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'content_types': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}) - }, - 'workflows.state': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'transitions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['workflows.Transition']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'states'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.stateobjectrelation': { - 'Meta': {'unique_together': "(('content_type', 'content_id', 'state'),)"}, - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'state_object'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) - }, - 'workflows.transition': { - 'condition': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), - 'destination': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'destination_state'", 'null': 'True', 'to': "orm['workflows.State']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.workflow': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'initial_state': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_state'", 'null': 'True', 'to': "orm['workflows.State']"}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['permissions.Permission']", 'symmetrical': 'False'}) - } - } - - complete_apps = ['ietfworkflows'] diff --git a/ietf/ietfworkflows/migrations/0009_allow_null_in_from_date.py b/ietf/ietfworkflows/migrations/0009_allow_null_in_from_date.py deleted file mode 100644 index b2c19c982..000000000 --- a/ietf/ietfworkflows/migrations/0009_allow_null_in_from_date.py +++ /dev/null @@ -1,197 +0,0 @@ - -from south.db import db -from django.db import models -from ietf.ietfworkflows.models import * - -class Migration: - - def forwards(self, orm): - - # Changing field 'StateObjectRelationMetadata.from_date' - # (to signature: django.db.models.fields.DateTimeField(null=True, blank=True)) - db.alter_column('ietfworkflows_stateobjectrelationmetadata', 'from_date', orm['ietfworkflows.stateobjectrelationmetadata:from_date']) - - - - def backwards(self, orm): - - # Changing field 'StateObjectRelationMetadata.from_date' - # (to signature: django.db.models.fields.DateTimeField()) - db.alter_column('ietfworkflows_stateobjectrelationmetadata', 'from_date', orm['ietfworkflows.stateobjectrelationmetadata:from_date']) - - - - models = { - 'contenttypes.contenttype': { - 'Meta': {'unique_together': "(('app_label', 'model'),)", 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - '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'}) - }, - 'idtracker.acronym': { - 'Meta': {'db_table': "'acronym'"}, - 'acronym': ('django.db.models.fields.CharField', [], {'max_length': '12'}), - 'acronym_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name_key': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'idtracker.idintendedstatus': { - 'Meta': {'db_table': "'id_intended_status'"}, - 'intended_status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'intended_status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.idstatus': { - 'Meta': {'db_table': "'id_status'"}, - 'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.internetdraft': { - 'Meta': {'db_table': "'internet_drafts'"}, - 'abstract': ('django.db.models.fields.TextField', [], {}), - 'b_approve_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'b_discussion_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'b_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'dunn_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True'}), - 'expired_tombstone': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'extension_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'file_type': ('django.db.models.fields.CharField', [], {'max_length': '20'}), - 'filename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), - 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Acronym']", 'db_column': "'group_acronym_id'"}), - 'id_document_key': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'id_document_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'intended_status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDIntendedStatus']"}), - 'last_modified_date': ('django.db.models.fields.DateField', [], {}), - 'lc_changes': ('django.db.models.fields.CharField', [], {'max_length': '3', 'null': 'True'}), - 'lc_expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'lc_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'local_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), - 'replaced_by': ('django.db.models.fields.related.ForeignKey', ["orm['idtracker.InternetDraft']"], {'related_name': "'replaces_set'", 'null': 'True', 'db_column': "'replaced_by'", 'blank': 'True'}), - 'review_by_rfc_editor': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'revision': ('django.db.models.fields.CharField', [], {'max_length': '2'}), - 'revision_date': ('django.db.models.fields.DateField', [], {}), - 'rfc_number': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), - 'shepherd': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'null': 'True', 'blank': 'True'}), - 'start_date': ('django.db.models.fields.DateField', [], {}), - 'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDStatus']"}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'id_document_name'"}), - 'txt_page_count': ('django.db.models.fields.IntegerField', [], {}), - 'wgreturn_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}) - }, - 'idtracker.personororginfo': { - 'Meta': {'db_table': "'person_or_org_info'"}, - 'address_type': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'created_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'date_created': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}), - 'date_modified': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'first_name_key': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'last_name_key': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'middle_initial': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'middle_initial_key': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'modified_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'name_prefix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'name_suffix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'person_or_org_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'record_type': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.annotationtag': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'annotation_tags'", 'to': "orm['workflows.Workflow']"}) - }, - 'ietfworkflows.annotationtagobjectrelation': { - 'annotation_tag': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.AnnotationTag']"}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'annotation_tags'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'ietfworkflows.objectannotationtaghistoryentry': { - 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), - 'setted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'unsetted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.objecthistoryentry': { - 'comment': ('django.db.models.fields.TextField', [], {}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}) - }, - 'ietfworkflows.objectstreamhistoryentry': { - 'from_stream': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), - 'to_stream': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.objectworkflowhistoryentry': { - 'from_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), - 'to_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'ietfworkflows.stateobjectrelationmetadata': { - 'estimated_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), - 'from_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'relation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.StateObjectRelation']"}) - }, - 'ietfworkflows.stream': { - 'group_chair_model': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), - 'group_model': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'with_groups': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.WGWorkflow']"}) - }, - 'ietfworkflows.streamedid': { - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'streamed_id'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'draft': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['idtracker.InternetDraft']", 'unique': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.Stream']", 'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.wgworkflow': { - 'selected_states': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['workflows.State']", 'null': 'True', 'blank': 'True'}), - 'selected_tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['ietfworkflows.AnnotationTag']", 'null': 'True', 'blank': 'True'}), - 'workflow_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['workflows.Workflow']", 'unique': 'True', 'primary_key': 'True'}) - }, - 'permissions.permission': { - 'codename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'content_types': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}) - }, - 'workflows.state': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'transitions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['workflows.Transition']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'states'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.stateobjectrelation': { - 'Meta': {'unique_together': "(('content_type', 'content_id', 'state'),)"}, - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'state_object'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) - }, - 'workflows.transition': { - 'condition': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), - 'destination': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'destination_state'", 'null': 'True', 'to': "orm['workflows.State']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.workflow': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'initial_state': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_state'", 'null': 'True', 'to': "orm['workflows.State']"}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['permissions.Permission']", 'symmetrical': 'False'}) - } - } - - complete_apps = ['ietfworkflows'] diff --git a/ietf/ietfworkflows/migrations/0010_add_state_definitions.py b/ietf/ietfworkflows/migrations/0010_add_state_definitions.py deleted file mode 100644 index 503943c56..000000000 --- a/ietf/ietfworkflows/migrations/0010_add_state_definitions.py +++ /dev/null @@ -1,207 +0,0 @@ - -from south.db import db -from django.db import models -from ietf.ietfworkflows.models import * - -class Migration: - - def forwards(self, orm): - - # Adding model 'StateDescription' - db.create_table('ietfworkflows_statedescription', ( - ('id', orm['ietfworkflows.statedescription:id']), - ('state', orm['ietfworkflows.statedescription:state']), - ('definition', orm['ietfworkflows.statedescription:definition']), - ('order', orm['ietfworkflows.statedescription:order']), - )) - db.send_create_signal('ietfworkflows', ['StateDescription']) - - - - def backwards(self, orm): - - # Deleting model 'StateDescription' - db.delete_table('ietfworkflows_statedescription') - - - - models = { - 'contenttypes.contenttype': { - 'Meta': {'unique_together': "(('app_label', 'model'),)", 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - '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'}) - }, - 'idtracker.acronym': { - 'Meta': {'db_table': "'acronym'"}, - 'acronym': ('django.db.models.fields.CharField', [], {'max_length': '12'}), - 'acronym_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name_key': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'idtracker.idintendedstatus': { - 'Meta': {'db_table': "'id_intended_status'"}, - 'intended_status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'intended_status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.idstatus': { - 'Meta': {'db_table': "'id_status'"}, - 'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.internetdraft': { - 'Meta': {'db_table': "'internet_drafts'"}, - 'abstract': ('django.db.models.fields.TextField', [], {}), - 'b_approve_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'b_discussion_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'b_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'dunn_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True'}), - 'expired_tombstone': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'extension_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'file_type': ('django.db.models.fields.CharField', [], {'max_length': '20'}), - 'filename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), - 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Acronym']", 'db_column': "'group_acronym_id'"}), - 'id_document_key': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'id_document_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'intended_status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDIntendedStatus']"}), - 'last_modified_date': ('django.db.models.fields.DateField', [], {}), - 'lc_changes': ('django.db.models.fields.CharField', [], {'max_length': '3', 'null': 'True'}), - 'lc_expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'lc_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'local_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), - 'replaced_by': ('django.db.models.fields.related.ForeignKey', ["orm['idtracker.InternetDraft']"], {'related_name': "'replaces_set'", 'null': 'True', 'db_column': "'replaced_by'", 'blank': 'True'}), - 'review_by_rfc_editor': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'revision': ('django.db.models.fields.CharField', [], {'max_length': '2'}), - 'revision_date': ('django.db.models.fields.DateField', [], {}), - 'rfc_number': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), - 'shepherd': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'null': 'True', 'blank': 'True'}), - 'start_date': ('django.db.models.fields.DateField', [], {}), - 'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDStatus']"}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'id_document_name'"}), - 'txt_page_count': ('django.db.models.fields.IntegerField', [], {}), - 'wgreturn_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}) - }, - 'idtracker.personororginfo': { - 'Meta': {'db_table': "'person_or_org_info'"}, - 'address_type': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'created_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'date_created': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}), - 'date_modified': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'first_name_key': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'last_name_key': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'middle_initial': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'middle_initial_key': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'modified_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'name_prefix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'name_suffix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'person_or_org_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'record_type': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.annotationtag': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'annotation_tags'", 'to': "orm['workflows.Workflow']"}) - }, - 'ietfworkflows.annotationtagobjectrelation': { - 'annotation_tag': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.AnnotationTag']"}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'annotation_tags'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'ietfworkflows.objectannotationtaghistoryentry': { - 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), - 'setted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'unsetted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.objecthistoryentry': { - 'comment': ('django.db.models.fields.TextField', [], {}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}) - }, - 'ietfworkflows.objectstreamhistoryentry': { - 'from_stream': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), - 'to_stream': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.objectworkflowhistoryentry': { - 'from_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), - 'to_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'ietfworkflows.statedescription': { - 'definition': ('django.db.models.fields.TextField', [], {}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'order': ('django.db.models.fields.PositiveIntegerField', [], {}), - 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) - }, - 'ietfworkflows.stateobjectrelationmetadata': { - 'estimated_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), - 'from_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'relation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.StateObjectRelation']"}) - }, - 'ietfworkflows.stream': { - 'group_chair_model': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), - 'group_model': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'with_groups': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.WGWorkflow']"}) - }, - 'ietfworkflows.streamedid': { - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'streamed_id'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'draft': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['idtracker.InternetDraft']", 'unique': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.Stream']", 'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.wgworkflow': { - 'selected_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['workflows.State']", 'null': 'True', 'blank': 'True'}), - 'selected_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['ietfworkflows.AnnotationTag']", 'null': 'True', 'blank': 'True'}), - 'workflow_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['workflows.Workflow']", 'unique': 'True', 'primary_key': 'True'}) - }, - 'permissions.permission': { - 'codename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'content_types': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}) - }, - 'workflows.state': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'transitions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['workflows.Transition']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'states'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.stateobjectrelation': { - 'Meta': {'unique_together': "(('content_type', 'content_id', 'state'),)"}, - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'state_object'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) - }, - 'workflows.transition': { - 'condition': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), - 'destination': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'destination_state'", 'null': 'True', 'to': "orm['workflows.State']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.workflow': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'initial_state': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_state'", 'null': 'True', 'to': "orm['workflows.State']"}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['permissions.Permission']", 'symmetrical': 'False'}) - } - } - - complete_apps = ['ietfworkflows'] diff --git a/ietf/ietfworkflows/migrations/0011_remove_group_from_stream.py b/ietf/ietfworkflows/migrations/0011_remove_group_from_stream.py deleted file mode 100644 index 5705f7ef8..000000000 --- a/ietf/ietfworkflows/migrations/0011_remove_group_from_stream.py +++ /dev/null @@ -1,205 +0,0 @@ - -from south.db import db -from django.db import models -from ietf.ietfworkflows.models import * - -class Migration: - - def forwards(self, orm): - - # Deleting field 'StreamedID.content_type' - db.delete_column('ietfworkflows_streamedid', 'content_type_id') - - # Deleting field 'StreamedID.content_id' - db.delete_column('ietfworkflows_streamedid', 'content_id') - - - - def backwards(self, orm): - - # Adding field 'StreamedID.content_type' - db.add_column('ietfworkflows_streamedid', 'content_type', orm['ietfworkflows.streamedid:content_type']) - - # Adding field 'StreamedID.content_id' - db.add_column('ietfworkflows_streamedid', 'content_id', orm['ietfworkflows.streamedid:content_id']) - - - - models = { - 'contenttypes.contenttype': { - 'Meta': {'unique_together': "(('app_label', 'model'),)", 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - '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'}) - }, - 'idtracker.acronym': { - 'Meta': {'db_table': "'acronym'"}, - 'acronym': ('django.db.models.fields.CharField', [], {'max_length': '12'}), - 'acronym_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name_key': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'idtracker.idintendedstatus': { - 'Meta': {'db_table': "'id_intended_status'"}, - 'intended_status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'intended_status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.idstatus': { - 'Meta': {'db_table': "'id_status'"}, - 'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.internetdraft': { - 'Meta': {'db_table': "'internet_drafts'"}, - 'abstract': ('django.db.models.fields.TextField', [], {}), - 'b_approve_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'b_discussion_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'b_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'dunn_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True'}), - 'expired_tombstone': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'extension_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'file_type': ('django.db.models.fields.CharField', [], {'max_length': '20'}), - 'filename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), - 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Acronym']", 'db_column': "'group_acronym_id'"}), - 'id_document_key': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'id_document_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'intended_status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDIntendedStatus']"}), - 'last_modified_date': ('django.db.models.fields.DateField', [], {}), - 'lc_changes': ('django.db.models.fields.CharField', [], {'max_length': '3', 'null': 'True'}), - 'lc_expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'lc_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'local_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), - 'replaced_by': ('django.db.models.fields.related.ForeignKey', ["orm['idtracker.InternetDraft']"], {'related_name': "'replaces_set'", 'null': 'True', 'db_column': "'replaced_by'", 'blank': 'True'}), - 'review_by_rfc_editor': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'revision': ('django.db.models.fields.CharField', [], {'max_length': '2'}), - 'revision_date': ('django.db.models.fields.DateField', [], {}), - 'rfc_number': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), - 'shepherd': ('django.db.models.fields.related.ForeignKey', ["orm['idtracker.PersonOrOrgInfo']"], {'null': 'True', 'blank': 'True'}), - 'start_date': ('django.db.models.fields.DateField', [], {}), - 'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDStatus']"}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'id_document_name'"}), - 'txt_page_count': ('django.db.models.fields.IntegerField', [], {}), - 'wgreturn_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}) - }, - 'idtracker.personororginfo': { - 'Meta': {'db_table': "'person_or_org_info'"}, - 'address_type': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'created_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'date_created': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}), - 'date_modified': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'first_name_key': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'last_name_key': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'middle_initial': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'middle_initial_key': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'modified_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'name_prefix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'name_suffix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'person_or_org_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'record_type': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.annotationtag': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'annotation_tags'", 'to': "orm['workflows.Workflow']"}) - }, - 'ietfworkflows.annotationtagobjectrelation': { - 'annotation_tag': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.AnnotationTag']"}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'annotation_tags'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'ietfworkflows.objectannotationtaghistoryentry': { - 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), - 'setted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'unsetted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.objecthistoryentry': { - 'comment': ('django.db.models.fields.TextField', [], {}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}) - }, - 'ietfworkflows.objectstreamhistoryentry': { - 'from_stream': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), - 'to_stream': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.objectworkflowhistoryentry': { - 'from_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), - 'to_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'ietfworkflows.statedescription': { - 'definition': ('django.db.models.fields.TextField', [], {}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'order': ('django.db.models.fields.PositiveIntegerField', [], {}), - 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) - }, - 'ietfworkflows.stateobjectrelationmetadata': { - 'estimated_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), - 'from_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'relation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.StateObjectRelation']"}) - }, - 'ietfworkflows.stream': { - 'group_chair_model': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), - 'group_model': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'with_groups': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.WGWorkflow']"}) - }, - 'ietfworkflows.streamedid': { - 'draft': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['idtracker.InternetDraft']", 'unique': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.Stream']", 'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.wgworkflow': { - 'selected_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['workflows.State']", 'null': 'True', 'blank': 'True'}), - 'selected_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['ietfworkflows.AnnotationTag']", 'null': 'True', 'blank': 'True'}), - 'workflow_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['workflows.Workflow']", 'unique': 'True', 'primary_key': 'True'}) - }, - 'permissions.permission': { - 'codename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'content_types': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}) - }, - 'workflows.state': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'transitions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['workflows.Transition']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'states'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.stateobjectrelation': { - 'Meta': {'unique_together': "(('content_type', 'content_id', 'state'),)"}, - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'state_object'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) - }, - 'workflows.transition': { - 'condition': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), - 'destination': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'destination_state'", 'null': 'True', 'to': "orm['workflows.State']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.workflow': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'initial_state': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_state'", 'null': 'True', 'to': "orm['workflows.State']"}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['permissions.Permission']", 'symmetrical': 'False'}) - } - } - - complete_apps = ['ietfworkflows'] diff --git a/ietf/ietfworkflows/migrations/0012_refactor_stream_group_descrition.py b/ietf/ietfworkflows/migrations/0012_refactor_stream_group_descrition.py deleted file mode 100644 index e5a61fcbd..000000000 --- a/ietf/ietfworkflows/migrations/0012_refactor_stream_group_descrition.py +++ /dev/null @@ -1,222 +0,0 @@ - -from south.db import db -from django.db import models -from ietf.ietfworkflows.models import * - -class Migration: - - def forwards(self, orm): - - # Adding field 'Stream.group_chair_attribute' - db.add_column('ietfworkflows_stream', 'group_chair_attribute', orm['ietfworkflows.stream:group_chair_attribute']) - - # Adding field 'Stream.document_group_attribute' - db.add_column('ietfworkflows_stream', 'document_group_attribute', orm['ietfworkflows.stream:document_group_attribute']) - - # Deleting field 'Stream.group_chair_model' - db.delete_column('ietfworkflows_stream', 'group_chair_model') - - # Deleting field 'Stream.with_groups' - db.delete_column('ietfworkflows_stream', 'with_groups') - - # Deleting field 'Stream.group_model' - db.delete_column('ietfworkflows_stream', 'group_model') - - - - def backwards(self, orm): - - # Deleting field 'Stream.group_chair_attribute' - db.delete_column('ietfworkflows_stream', 'group_chair_attribute') - - # Deleting field 'Stream.document_group_attribute' - db.delete_column('ietfworkflows_stream', 'document_group_attribute') - - # Adding field 'Stream.group_chair_model' - db.add_column('ietfworkflows_stream', 'group_chair_model', orm['ietfworkflows.stream:group_chair_model']) - - # Adding field 'Stream.with_groups' - db.add_column('ietfworkflows_stream', 'with_groups', orm['ietfworkflows.stream:with_groups']) - - # Adding field 'Stream.group_model' - db.add_column('ietfworkflows_stream', 'group_model', orm['ietfworkflows.stream:group_model']) - - - - models = { - 'contenttypes.contenttype': { - 'Meta': {'unique_together': "(('app_label', 'model'),)", 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - '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'}) - }, - 'idtracker.acronym': { - 'Meta': {'db_table': "'acronym'"}, - 'acronym': ('django.db.models.fields.CharField', [], {'max_length': '12'}), - 'acronym_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name_key': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'idtracker.idintendedstatus': { - 'Meta': {'db_table': "'id_intended_status'"}, - 'intended_status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'intended_status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.idstatus': { - 'Meta': {'db_table': "'id_status'"}, - 'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.internetdraft': { - 'Meta': {'db_table': "'internet_drafts'"}, - 'abstract': ('django.db.models.fields.TextField', [], {}), - 'b_approve_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'b_discussion_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'b_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'dunn_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True'}), - 'expired_tombstone': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'extension_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'file_type': ('django.db.models.fields.CharField', [], {'max_length': '20'}), - 'filename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), - 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Acronym']", 'db_column': "'group_acronym_id'"}), - 'id_document_key': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'id_document_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'intended_status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDIntendedStatus']"}), - 'last_modified_date': ('django.db.models.fields.DateField', [], {}), - 'lc_changes': ('django.db.models.fields.CharField', [], {'max_length': '3', 'null': 'True'}), - 'lc_expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'lc_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'local_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), - 'replaced_by': ('django.db.models.fields.related.ForeignKey', ["orm['idtracker.InternetDraft']"], {'related_name': "'replaces_set'", 'null': 'True', 'db_column': "'replaced_by'", 'blank': 'True'}), - 'review_by_rfc_editor': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'revision': ('django.db.models.fields.CharField', [], {'max_length': '2'}), - 'revision_date': ('django.db.models.fields.DateField', [], {}), - 'rfc_number': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), - 'shepherd': ('django.db.models.fields.related.ForeignKey', ["orm['idtracker.PersonOrOrgInfo']"], {'null': 'True', 'blank': 'True'}), - 'start_date': ('django.db.models.fields.DateField', [], {}), - 'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDStatus']"}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'id_document_name'"}), - 'txt_page_count': ('django.db.models.fields.IntegerField', [], {}), - 'wgreturn_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}) - }, - 'idtracker.personororginfo': { - 'Meta': {'db_table': "'person_or_org_info'"}, - 'address_type': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'created_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'date_created': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}), - 'date_modified': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'first_name_key': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'last_name_key': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'middle_initial': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'middle_initial_key': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'modified_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'name_prefix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'name_suffix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'person_or_org_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'record_type': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.annotationtag': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'annotation_tags'", 'to': "orm['workflows.Workflow']"}) - }, - 'ietfworkflows.annotationtagobjectrelation': { - 'annotation_tag': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.AnnotationTag']"}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'annotation_tags'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'ietfworkflows.objectannotationtaghistoryentry': { - 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), - 'setted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'unsetted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.objecthistoryentry': { - 'comment': ('django.db.models.fields.TextField', [], {}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}) - }, - 'ietfworkflows.objectstreamhistoryentry': { - 'from_stream': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), - 'to_stream': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.objectworkflowhistoryentry': { - 'from_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), - 'to_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'ietfworkflows.statedescription': { - 'definition': ('django.db.models.fields.TextField', [], {}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'order': ('django.db.models.fields.PositiveIntegerField', [], {}), - 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) - }, - 'ietfworkflows.stateobjectrelationmetadata': { - 'estimated_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), - 'from_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'relation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.StateObjectRelation']"}) - }, - 'ietfworkflows.stream': { - 'document_group_attribute': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), - 'group_chair_attribute': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.WGWorkflow']"}) - }, - 'ietfworkflows.streamedid': { - 'draft': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['idtracker.InternetDraft']", 'unique': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.Stream']", 'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.wgworkflow': { - 'selected_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['workflows.State']", 'null': 'True', 'blank': 'True'}), - 'selected_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['ietfworkflows.AnnotationTag']", 'null': 'True', 'blank': 'True'}), - 'workflow_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['workflows.Workflow']", 'unique': 'True', 'primary_key': 'True'}) - }, - 'permissions.permission': { - 'codename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'content_types': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}) - }, - 'workflows.state': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'transitions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['workflows.Transition']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'states'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.stateobjectrelation': { - 'Meta': {'unique_together': "(('content_type', 'content_id', 'state'),)"}, - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'state_object'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) - }, - 'workflows.transition': { - 'condition': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), - 'destination': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'destination_state'", 'null': 'True', 'to': "orm['workflows.State']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.workflow': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'initial_state': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_state'", 'null': 'True', 'to': "orm['workflows.State']"}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['permissions.Permission']", 'symmetrical': 'False'}) - } - } - - complete_apps = ['ietfworkflows'] diff --git a/ietf/ietfworkflows/migrations/0013_add_stream_delegates.py b/ietf/ietfworkflows/migrations/0013_add_stream_delegates.py deleted file mode 100644 index 2647539a7..000000000 --- a/ietf/ietfworkflows/migrations/0013_add_stream_delegates.py +++ /dev/null @@ -1,208 +0,0 @@ - -from south.db import db -from django.db import models -from ietf.ietfworkflows.models import * - -class Migration: - - def forwards(self, orm): - - # Adding model 'StreamDelegate' - db.create_table('ietfworkflows_streamdelegate', ( - ('id', orm['ietfworkflows.streamdelegate:id']), - ('stream', orm['ietfworkflows.streamdelegate:stream']), - ('person', orm['ietfworkflows.streamdelegate:person']), - )) - db.send_create_signal('ietfworkflows', ['StreamDelegate']) - - - - def backwards(self, orm): - - # Deleting model 'StreamDelegate' - db.delete_table('ietfworkflows_streamdelegate') - - - - models = { - 'contenttypes.contenttype': { - 'Meta': {'unique_together': "(('app_label', 'model'),)", 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - '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'}) - }, - 'idtracker.acronym': { - 'Meta': {'db_table': "'acronym'"}, - 'acronym': ('django.db.models.fields.CharField', [], {'max_length': '12'}), - 'acronym_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name_key': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'idtracker.idintendedstatus': { - 'Meta': {'db_table': "'id_intended_status'"}, - 'intended_status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'intended_status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.idstatus': { - 'Meta': {'db_table': "'id_status'"}, - 'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.internetdraft': { - 'Meta': {'db_table': "'internet_drafts'"}, - 'abstract': ('django.db.models.fields.TextField', [], {}), - 'b_approve_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'b_discussion_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'b_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'dunn_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True'}), - 'expired_tombstone': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'extension_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'file_type': ('django.db.models.fields.CharField', [], {'max_length': '20'}), - 'filename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), - 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Acronym']", 'db_column': "'group_acronym_id'"}), - 'id_document_key': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'id_document_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'intended_status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDIntendedStatus']"}), - 'last_modified_date': ('django.db.models.fields.DateField', [], {}), - 'lc_changes': ('django.db.models.fields.CharField', [], {'max_length': '3', 'null': 'True'}), - 'lc_expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'lc_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'local_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), - 'replaced_by': ('django.db.models.fields.related.ForeignKey', ["orm['idtracker.InternetDraft']"], {'related_name': "'replaces_set'", 'null': 'True', 'db_column': "'replaced_by'", 'blank': 'True'}), - 'review_by_rfc_editor': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'revision': ('django.db.models.fields.CharField', [], {'max_length': '2'}), - 'revision_date': ('django.db.models.fields.DateField', [], {}), - 'rfc_number': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), - 'shepherd': ('django.db.models.fields.related.ForeignKey', ["orm['idtracker.PersonOrOrgInfo']"], {'null': 'True', 'blank': 'True'}), - 'start_date': ('django.db.models.fields.DateField', [], {}), - 'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDStatus']"}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'id_document_name'"}), - 'txt_page_count': ('django.db.models.fields.IntegerField', [], {}), - 'wgreturn_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}) - }, - 'idtracker.personororginfo': { - 'Meta': {'db_table': "'person_or_org_info'"}, - 'address_type': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'created_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'date_created': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}), - 'date_modified': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'first_name_key': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'last_name_key': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'middle_initial': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'middle_initial_key': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'modified_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'name_prefix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'name_suffix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'person_or_org_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'record_type': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.annotationtag': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'annotation_tags'", 'to': "orm['workflows.Workflow']"}) - }, - 'ietfworkflows.annotationtagobjectrelation': { - 'annotation_tag': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.AnnotationTag']"}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'annotation_tags'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'ietfworkflows.objectannotationtaghistoryentry': { - 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), - 'setted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'unsetted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.objecthistoryentry': { - 'comment': ('django.db.models.fields.TextField', [], {}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}) - }, - 'ietfworkflows.objectstreamhistoryentry': { - 'from_stream': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), - 'to_stream': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.objectworkflowhistoryentry': { - 'from_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), - 'to_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'ietfworkflows.statedescription': { - 'definition': ('django.db.models.fields.TextField', [], {}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'order': ('django.db.models.fields.PositiveIntegerField', [], {}), - 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) - }, - 'ietfworkflows.stateobjectrelationmetadata': { - 'estimated_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), - 'from_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'relation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.StateObjectRelation']"}) - }, - 'ietfworkflows.stream': { - 'document_group_attribute': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), - 'group_chair_attribute': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.WGWorkflow']"}) - }, - 'ietfworkflows.streamdelegate': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}), - 'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.Stream']"}) - }, - 'ietfworkflows.streamedid': { - 'draft': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['idtracker.InternetDraft']", 'unique': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.Stream']", 'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.wgworkflow': { - 'selected_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['workflows.State']", 'null': 'True', 'blank': 'True'}), - 'selected_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['ietfworkflows.AnnotationTag']", 'null': 'True', 'blank': 'True'}), - 'workflow_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['workflows.Workflow']", 'unique': 'True', 'primary_key': 'True'}) - }, - 'permissions.permission': { - 'codename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'content_types': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}) - }, - 'workflows.state': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'transitions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['workflows.Transition']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'states'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.stateobjectrelation': { - 'Meta': {'unique_together': "(('content_type', 'content_id', 'state'),)"}, - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'state_object'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) - }, - 'workflows.transition': { - 'condition': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), - 'destination': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'destination_state'", 'null': 'True', 'to': "orm['workflows.State']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.workflow': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'initial_state': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_state'", 'null': 'True', 'to': "orm['workflows.State']"}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['permissions.Permission']", 'symmetrical': 'False'}) - } - } - - complete_apps = ['ietfworkflows'] diff --git a/ietf/ietfworkflows/migrations/0014_change_alt_streams_states.py b/ietf/ietfworkflows/migrations/0014_change_alt_streams_states.py deleted file mode 100644 index a6ef0232e..000000000 --- a/ietf/ietfworkflows/migrations/0014_change_alt_streams_states.py +++ /dev/null @@ -1,234 +0,0 @@ - -from south.db import db -from django.db import models -from ietf.ietfworkflows.models import * - -class Migration: - - no_dry_run = True - - def forwards(self, orm): - # Remove all 'Published RFC' status - for state in orm['workflows.state'].objects.filter(name='Published RFC'): - state.delete() - - - def backwards(self, orm): - "Write your backwards migration here" - - - models = { - 'contenttypes.contenttype': { - 'Meta': {'unique_together': "(('app_label', 'model'),)", 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - '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'}) - }, - 'idtracker.acronym': { - 'Meta': {'db_table': "'acronym'"}, - 'acronym': ('django.db.models.fields.CharField', [], {'max_length': '12'}), - 'acronym_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name_key': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'idtracker.idintendedstatus': { - 'Meta': {'db_table': "'id_intended_status'"}, - 'intended_status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'intended_status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.idstatus': { - 'Meta': {'db_table': "'id_status'"}, - 'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.internetdraft': { - 'Meta': {'db_table': "'internet_drafts'"}, - 'abstract': ('django.db.models.fields.TextField', [], {}), - 'b_approve_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'b_discussion_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'b_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'dunn_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True'}), - 'expired_tombstone': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'extension_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'file_type': ('django.db.models.fields.CharField', [], {'max_length': '20'}), - 'filename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), - 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Acronym']", 'db_column': "'group_acronym_id'"}), - 'id_document_key': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'id_document_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'intended_status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDIntendedStatus']"}), - 'last_modified_date': ('django.db.models.fields.DateField', [], {}), - 'lc_changes': ('django.db.models.fields.CharField', [], {'max_length': '3', 'null': 'True'}), - 'lc_expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'lc_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'local_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), - 'replaced_by': ('django.db.models.fields.related.ForeignKey', ["orm['idtracker.InternetDraft']"], {'related_name': "'replaces_set'", 'null': 'True', 'db_column': "'replaced_by'", 'blank': 'True'}), - 'review_by_rfc_editor': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'revision': ('django.db.models.fields.CharField', [], {'max_length': '2'}), - 'revision_date': ('django.db.models.fields.DateField', [], {}), - 'rfc_number': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), - 'shepherd': ('django.db.models.fields.related.ForeignKey', ["orm['idtracker.PersonOrOrgInfo']"], {'null': 'True', 'blank': 'True'}), - 'start_date': ('django.db.models.fields.DateField', [], {}), - 'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDStatus']"}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'id_document_name'"}), - 'txt_page_count': ('django.db.models.fields.IntegerField', [], {}), - 'wgreturn_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}) - }, - 'idtracker.personororginfo': { - 'Meta': {'db_table': "'person_or_org_info'"}, - 'address_type': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'created_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'date_created': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}), - 'date_modified': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'first_name_key': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'last_name_key': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'middle_initial': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'middle_initial_key': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'modified_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'name_prefix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'name_suffix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'person_or_org_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'record_type': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.annotationtag': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'annotation_tags'", 'to': "orm['workflows.Workflow']"}) - }, - 'ietfworkflows.annotationtagobjectrelation': { - 'annotation_tag': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.AnnotationTag']"}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'annotation_tags'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'ietfworkflows.objectannotationtaghistoryentry': { - 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), - 'setted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'unsetted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.objecthistoryentry': { - 'comment': ('django.db.models.fields.TextField', [], {}), - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}) - }, - 'ietfworkflows.objectstreamhistoryentry': { - 'from_stream': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), - 'to_stream': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.objectworkflowhistoryentry': { - 'from_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), - 'to_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'ietfworkflows.statedescription': { - 'definition': ('django.db.models.fields.TextField', [], {}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'order': ('django.db.models.fields.PositiveIntegerField', [], {}), - 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) - }, - 'ietfworkflows.stateobjectrelationmetadata': { - 'estimated_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), - 'from_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'relation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.StateObjectRelation']"}) - }, - 'ietfworkflows.stream': { - 'document_group_attribute': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), - 'group_chair_attribute': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.WGWorkflow']"}) - }, - 'ietfworkflows.streamdelegate': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}), - 'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.Stream']"}) - }, - 'ietfworkflows.streamedid': { - 'draft': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['idtracker.InternetDraft']", 'unique': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.Stream']", 'null': 'True', 'blank': 'True'}) - }, - 'ietfworkflows.wgworkflow': { - 'selected_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['workflows.State']", 'null': 'True', 'blank': 'True'}), - 'selected_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['ietfworkflows.AnnotationTag']", 'null': 'True', 'blank': 'True'}), - 'workflow_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['workflows.Workflow']", 'unique': 'True', 'primary_key': 'True'}) - }, - 'permissions.permission': { - 'codename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'content_types': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}) - }, - 'permissions.role': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}) - }, - 'workflows.state': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'transitions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['workflows.Transition']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'states'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.stateinheritanceblock': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']"}), - 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) - }, - 'workflows.stateobjectrelation': { - 'Meta': {'unique_together': "(('content_type', 'content_id', 'state'),)"}, - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'state_object'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) - }, - 'workflows.statepermissionrelation': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']"}), - 'role': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Role']"}), - 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) - }, - 'workflows.transition': { - 'condition': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), - 'destination': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'destination_state'", 'null': 'True', 'to': "orm['workflows.State']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.workflow': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'initial_state': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_state'", 'null': 'True', 'to': "orm['workflows.State']"}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['permissions.Permission']", 'symmetrical': 'False'}) - }, - 'workflows.workflowmodelrelation': { - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']", 'unique': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'wmrs'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.workflowobjectrelation': { - 'Meta': {'unique_together': "(('content_type', 'content_id'),)"}, - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_object'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'wors'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.workflowpermissionrelation': { - 'Meta': {'unique_together': "(('workflow', 'permission'),)"}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'permissions'", 'to': "orm['permissions.Permission']"}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.Workflow']"}) - } - } - - complete_apps = ['ietfworkflows', 'workflows'] diff --git a/ietf/ietfworkflows/migrations/__init__.py b/ietf/ietfworkflows/migrations/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/ietf/ietfworkflows/models.py b/ietf/ietfworkflows/models.py deleted file mode 100644 index 5a455a6b3..000000000 --- a/ietf/ietfworkflows/models.py +++ /dev/null @@ -1,268 +0,0 @@ -from django.contrib.contenttypes import generic -from django.contrib.contenttypes.models import ContentType -from django.db import models -from django.utils.translation import ugettext_lazy as _ -from django.conf import settings - -from ietf.idtracker.models import PersonOrOrgInfo, InternetDraft, Role, IRTF -from ietf.utils.admin import admin_link -from workflows.models import Workflow, State, StateObjectRelation -from permissions.models import Permission - - -class ObjectHistoryEntry(models.Model): - content_type = models.ForeignKey(ContentType, verbose_name=_(u"Content type"), related_name="workflow_history", blank=True, null=True) - content_id = models.PositiveIntegerField(_(u"Content id"), blank=True, null=True) - content = generic.GenericForeignKey(ct_field="content_type", fk_field="content_id") - - date = models.DateTimeField(_('Date'), auto_now_add=True) - comment = models.TextField(_('Comment')) - person = models.ForeignKey(PersonOrOrgInfo) - - class Meta: - ordering = ('-date', ) - - def get_real_instance(self): - if hasattr(self, '_real_instance'): - return self._real_instance - for i in ('objectworkflowhistoryentry', 'objectannotationtaghistoryentry', 'objectstreamhistoryentry'): - try: - real_instance = getattr(self, i, None) - if real_instance: - self._real_instance = real_instance - return real_instance - except models.ObjectDoesNotExist: - continue - self._real_instance = self - return self - - -class ObjectWorkflowHistoryEntry(ObjectHistoryEntry): - from_state = models.CharField(_('From state'), max_length=100) - to_state = models.CharField(_('To state'), max_length=100) - - def describe_change(self): - html = '

' - html += 'Changed state %s to %s' % (self.from_state, self.to_state) - html += '

' - return html - - -class ObjectAnnotationTagHistoryEntry(ObjectHistoryEntry): - setted = models.TextField(_('Setted tags'), blank=True, null=True) - unsetted = models.TextField(_('Unsetted tags'), blank=True, null=True) - - def describe_change(self): - html = '' - if self.setted: - html += '

' - html += 'Annotation tags set: ' - html += self.setted - html += '

' - if self.unsetted: - html += '

' - html += 'Annotation tags reset: ' - html += self.unsetted - html += '

' - return html - - -class ObjectStreamHistoryEntry(ObjectHistoryEntry): - from_stream = models.TextField(_('From stream'), blank=True, null=True) - to_stream = models.TextField(_('To stream'), blank=True, null=True) - - def describe_change(self): - html = '

' - html += 'Changed doc from stream %s to %s' % (self.from_stream, self.to_stream) - html += '

' - return html - - -class StateDescription(models.Model): - state = models.ForeignKey(State) - definition = models.TextField() - order = models.PositiveIntegerField() - - class Meta: - ordering = ('order', ) - - def __unicode__(self): - return unicode(self.state) - - -class AnnotationTag(models.Model): - name = models.CharField(_(u"Name"), max_length=100) - workflow = models.ForeignKey(Workflow, verbose_name=_(u"Workflow"), related_name="annotation_tags") - permission = models.ForeignKey(Permission, verbose_name=_(u"Permission"), blank=True, null=True) - - class Meta: - ordering = ('name', ) - - def __unicode__(self): - return self.name - - -class AnnotationTagObjectRelation(models.Model): - content_type = models.ForeignKey(ContentType, verbose_name=_(u"Content type"), related_name="annotation_tags", blank=True, null=True) - content_id = models.PositiveIntegerField(_(u"Content id"), blank=True, null=True) - content = generic.GenericForeignKey(ct_field="content_type", fk_field="content_id") - - annotation_tag = models.ForeignKey(AnnotationTag, verbose_name=_(u"Annotation tag")) - - -class StateObjectRelationMetadata(models.Model): - relation = models.ForeignKey(StateObjectRelation) - from_date = models.DateTimeField(_('Initial date'), blank=True, null=True) - estimated_date = models.DateTimeField(_('Estimated date'), blank=True, null=True) - - -class WGWorkflow(Workflow): - selected_states = models.ManyToManyField(State, blank=True, null=True) - selected_tags = models.ManyToManyField(AnnotationTag, blank=True, null=True) - - class Meta: - verbose_name = 'IETF Workflow' - verbose_name_plural = 'IETF Workflows' - - def get_tags(self): - tags = self.annotation_tags.all() - if tags.count(): - return tags - else: - return self.selected_tags.all() - - def get_states(self): - states = self.states.all() - if states.count(): - return states - else: - return self.selected_states.all() - - -class Stream(models.Model): - name = models.CharField(_(u"Name"), max_length=100) - document_group_attribute = models.CharField(_(u'Document group attribute'), max_length=255, blank=True, null=True) - group_chair_attribute = models.CharField(_(u'Group chair attribute'), max_length=255, blank=True, null=True) - workflow = models.ForeignKey(WGWorkflow) - - def __unicode__(self): - return u'%s stream' % self.name - workflow_link = admin_link('workflow') - - def _irtf_group(self, document): - filename = document.filename.split('-') - if len(filename) > 2 and filename[0] == 'draft' and filename[1] == 'irtf': - try: - return IRTF.objects.get(acronym=filename[2]) - except IRTF.DoesNotExist: - return None - return None - - def _irtf_chairs_for_document(self, document): - group = self._irtf_group(document) - if not group: - return [] - chairs = [i.person for i in group.chairs()] - chairs.append(Role.objects.get(pk=Role.IRTF_CHAIR).person) - return chairs - - def _ietf_delegates_for_document(self, document): - group = self.get_group_for_document(document) - if not group: - return False - return [i.person for i in group.wgdelegate_set.all()] - - def get_group_for_document(self, document): - if hasattr(self, '_%s_group' % self.name.lower()): - return getattr(self, '_%s_group' % self.name.lower())(document) - - if not self.document_group_attribute: - return None - attr = None - obj = document - for attr_name in self.document_group_attribute.split('.'): - attr = getattr(obj, attr_name, None) - if not attr: - return None - if callable(attr): - attr = attr() - obj = attr - return attr - - def get_chairs_for_document(self, document): - if hasattr(self, '_%s_chairs_for_document' % self.name.lower()): - return getattr(self, '_%s_chairs_for_document' % self.name.lower())(document) - - group = self.get_group_for_document(document) - if not group or not self.group_chair_attribute: - return [] - attr = None - obj = group - for attr_name in self.group_chair_attribute.split('.'): - attr = getattr(obj, attr_name, None) - if not attr: - return None - if callable(attr): - attr = attr() - obj = attr - return attr - - def get_delegates_for_document(self, document): - delegates = [] - if hasattr(self, '_%s_delegates_for_document' % self.name.lower()): - delegates = getattr(self, '_%s_delegates_for_document' % self.name.lower())(document) - delegates += [i.person for i in self.streamdelegate_set.all()] - return delegates - - def _ise_chairs_for_document(self, document): - return self._ise_stream_chairs() - - def _ise_stream_chairs(self): - chairs = [] - try: - chairs.append(Role.objects.get(role_name='ISE').person) - except Role.DoesNotExist: - pass - return chairs - - def get_chairs(self): - chairs = [] - if hasattr(self, '_%s_stream_chairs' % self.name.lower()): - chairs += list(getattr(self, '_%s_stream_chairs' % self.name.lower())()) - - role_key = getattr(Role, '%s_CHAIR' % self.name.upper(), None) - if role_key: - try: - chairs.append(Role.objects.get(pk=role_key).person) - except Role.DoesNotExist: - pass - return list(set(chairs)) - - def get_delegates(self): - delegates = [] - if hasattr(self, '_%s_stream_delegates' % self.name.lower()): - delegates += list(getattr(self, '_%s_stream_delegates' % self.name.lower())()) - delegates += [i.person for i in StreamDelegate.objects.filter(stream=self)] - return list(set(delegates)) - - def check_chair(self, person): - return person in self.get_chairs() - - def check_delegate(self, person): - return person in self.get_delegates() - - -class StreamedID(models.Model): - draft = models.OneToOneField(InternetDraft) - stream = models.ForeignKey(Stream, blank=True, null=True) - - def get_group(self): - return self.stream.get_group_for_document(self.draft) - - -class StreamDelegate(models.Model): - stream = models.ForeignKey(Stream) - person = models.ForeignKey(PersonOrOrgInfo) - -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - from ietf.name.proxy import StreamProxy as Stream diff --git a/ietf/ietfworkflows/streams.py b/ietf/ietfworkflows/streams.py deleted file mode 100644 index 9540a2825..000000000 --- a/ietf/ietfworkflows/streams.py +++ /dev/null @@ -1,102 +0,0 @@ -from django.db import models -from django.conf import settings -from ietf.idtracker.models import InternetDraft - -from ietf.idrfc.idrfc_wrapper import IdRfcWrapper, IdWrapper -from ietf.ietfworkflows.models import StreamedID, Stream - - -def get_streamed_draft(draft): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - class Dummy: pass - o = Dummy() - o.draft = draft - o.stream = super(InternetDraft, draft).stream - o.group = draft.group - o.get_group = lambda: draft.group - return o - - if not draft: - return None - try: - return draft.streamedid - except StreamedID.DoesNotExist: - return None - - -def get_stream_from_draft(draft): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - s = super(InternetDraft, draft).stream - if s: - s.with_groups = s.slug in ["ietf", "irtf"] - return s - - streamedid = get_streamed_draft(draft) - if streamedid: - return streamedid.stream - return False - - -def get_stream_by_name(stream_name): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - raise NotImplementedError - - try: - return Stream.objects.get(name=stream_name) - except Stream.DoesNotExist: - return None - - -def get_stream_from_id(stream_id): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - raise NotImplementedError - - try: - return Stream.objects.get(id=stream_id) - except Stream.DoesNotExist: - return None - - -def _set_stream_automatically(draft, stream): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - raise NotImplementedError - (streamed, created) = StreamedID.objects.get_or_create(draft=draft) - if created: - streamed.stream = stream - streamed.save() - return - - -def get_stream_from_wrapper(idrfc_wrapper): - idwrapper = None - if isinstance(idrfc_wrapper, IdRfcWrapper): - idwrapper = idrfc_wrapper.id - elif isinstance(idrfc_wrapper, IdWrapper): - idwrapper = idrfc_wrapper - if not idwrapper: - return None - draft = idwrapper._draft - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - return super(InternetDraft, draft).stream - - stream = get_stream_from_draft(draft) - if stream == False: - stream_id = idwrapper.stream_id() - stream = get_stream_from_id(stream_id) - _set_stream_automatically(draft, stream) - return stream - else: - return stream - return None - - -def set_stream_for_draft(draft, stream): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - raise NotImplementedError - - (streamed, created) = StreamedID.objects.get_or_create(draft=draft) - if streamed.stream != stream: - streamed.stream = stream - streamed.group = None - streamed.save() - return streamed.stream diff --git a/ietf/ietfworkflows/templatetags/.gitignore b/ietf/ietfworkflows/templatetags/.gitignore deleted file mode 100644 index a74b07aee..000000000 --- a/ietf/ietfworkflows/templatetags/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/*.pyc diff --git a/ietf/ietfworkflows/templatetags/__init__.py b/ietf/ietfworkflows/templatetags/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/ietf/ietfworkflows/templatetags/ietf_streams.py b/ietf/ietfworkflows/templatetags/ietf_streams.py deleted file mode 100644 index f9e69803f..000000000 --- a/ietf/ietfworkflows/templatetags/ietf_streams.py +++ /dev/null @@ -1,114 +0,0 @@ -from django import template -from django.conf import settings -from django.core.urlresolvers import reverse as urlreverse - -from ietf.idrfc.idrfc_wrapper import IdRfcWrapper, IdWrapper -from ietf.ietfworkflows.utils import (get_workflow_for_draft, - get_state_for_draft) -from ietf.wgchairs.accounts import (can_manage_shepherd_of_a_document, - can_manage_writeup_of_a_document) -from ietf.ietfworkflows.streams import get_stream_from_wrapper -from ietf.ietfworkflows.models import Stream -from ietf.ietfworkflows.accounts import (can_edit_state, can_edit_stream, - is_chair_of_stream, can_adopt) - -register = template.Library() - - -@register.inclusion_tag('ietfworkflows/stream_state.html', takes_context=True) -def stream_state(context, doc): - data = {} - stream = get_stream_from_wrapper(doc) - data.update({'stream': stream}) - if not stream: - return data - - idwrapper = None - if isinstance(doc, IdRfcWrapper): - idwrapper = doc.id - elif isinstance(doc, IdWrapper): - idwrapper = doc - if not idwrapper: - return data - - draft = getattr(idwrapper, '_draft', None) - if not draft: - return data - - workflow = get_workflow_for_draft(draft) - state = get_state_for_draft(draft) - - data.update({'workflow': workflow, - 'draft': draft, - 'state': state, - 'milestones': draft.groupmilestone_set.filter(state="active") - }) - - return data - - -@register.inclusion_tag('ietfworkflows/workflow_history_entry.html', takes_context=True) -def workflow_history_entry(context, entry): - real_entry = entry.get_real_instance() - return {'entry': real_entry, - 'entry_class': real_entry.__class__.__name__.lower()} - - -@register.inclusion_tag('ietfworkflows/edit_actions.html', takes_context=True) -def edit_actions(context, wrapper): - request = context.get('request', None) - user = request and request.user - if not user: - return {} - idwrapper = None - if isinstance(wrapper, IdRfcWrapper): - idwrapper = wrapper.id - elif isinstance(wrapper, IdWrapper): - idwrapper = wrapper - if not idwrapper: - return None - doc = wrapper - draft = wrapper._draft - - actions = [] - if can_adopt(user, draft): - actions.append(("Adopt in WG", urlreverse('edit_adopt', kwargs=dict(name=doc.draft_name)))) - - if can_edit_state(user, draft): - actions.append(("Change stream state", urlreverse('edit_state', kwargs=dict(name=doc.draft_name)))) - if draft.stream_id in ("iab", "ise", "irtf"): - actions.append(("Request publication", urlreverse('doc_request_publication', kwargs=dict(name=doc.draft_name)))) - - return dict(actions=actions) - - -class StreamListNode(template.Node): - - def __init__(self, user, var_name): - self.user = user - self.var_name = var_name - - def render(self, context): - user = self.user.resolve(context) - streams = [] - for i in Stream.objects.all(): - if "Legacy" in i.name: - continue - if is_chair_of_stream(user, i): - streams.append(i) - context.update({self.var_name: streams}) - return '' - - -@register.tag -def get_user_managed_streams(parser, token): - firstbits = token.contents.split(None, 2) - if len(firstbits) != 3: - raise template.TemplateSyntaxError("'get_user_managed_streams' tag takes three arguments") - user = parser.compile_filter(firstbits[1]) - lastbits_reversed = firstbits[2][::-1].split(None, 2) - if lastbits_reversed[1][::-1] != 'as': - raise template.TemplateSyntaxError("next-to-last argument to 'get_user_managed_stream' tag must" - " be 'as'") - var_name = lastbits_reversed[0][::-1] - return StreamListNode(user, var_name) diff --git a/ietf/ietfworkflows/templatetags/ietf_streams_redesign.py b/ietf/ietfworkflows/templatetags/ietf_streams_redesign.py deleted file mode 100644 index 978e99e74..000000000 --- a/ietf/ietfworkflows/templatetags/ietf_streams_redesign.py +++ /dev/null @@ -1,104 +0,0 @@ -from django import template -from django.conf import settings -from django.core.urlresolvers import reverse as urlreverse - -from ietf.idrfc.idrfc_wrapper import IdRfcWrapper, IdWrapper -from ietf.ietfworkflows.utils import (get_workflow_for_draft, - get_state_for_draft) -from ietf.wgchairs.accounts import (can_manage_shepherd_of_a_document, - can_manage_writeup_of_a_document) -from ietf.ietfworkflows.streams import get_stream_from_wrapper -from ietf.ietfworkflows.models import Stream -from ietf.ietfworkflows.accounts import (can_edit_state, can_edit_stream, - is_chair_of_stream, can_adopt) - -register = template.Library() - - -@register.inclusion_tag('ietfworkflows/stream_state_redesign.html', takes_context=True) -def stream_state(context, doc): - data = {} - stream = doc.stream - data.update({'stream': stream}) - if not stream: - return data - - if doc.type.slug != 'draft': - return data - - state = get_state_for_draft(doc) - - data.update({ - 'state': state, - 'doc': doc, - }) - - return data - - -@register.inclusion_tag('ietfworkflows/workflow_history_entry.html', takes_context=True) -def workflow_history_entry(context, entry): - real_entry = entry.get_real_instance() - return {'entry': real_entry, - 'entry_class': real_entry.__class__.__name__.lower()} - - -@register.inclusion_tag('ietfworkflows/edit_actions.html', takes_context=True) -def edit_actions(context, wrapper): - request = context.get('request', None) - user = request and request.user - if not user: - return {} - idwrapper = None - if isinstance(wrapper, IdRfcWrapper): - idwrapper = wrapper.id - elif isinstance(wrapper, IdWrapper): - idwrapper = wrapper - if not idwrapper: - return None - doc = wrapper - draft = wrapper._draft - - actions = [] - if can_adopt(user, draft): - actions.append(("Adopt in WG", urlreverse('edit_adopt', kwargs=dict(name=doc.draft_name)))) - - if can_edit_state(user, draft): - actions.append(("Change stream state", urlreverse('edit_state', kwargs=dict(name=doc.draft_name)))) - - if can_edit_stream(user, draft): - actions.append(("Change stream", urlreverse('edit_stream', kwargs=dict(name=doc.draft_name)))) - - return dict(actions=actions) - - -class StreamListNode(template.Node): - - def __init__(self, user, var_name): - self.user = user - self.var_name = var_name - - def render(self, context): - user = self.user.resolve(context) - streams = [] - for i in Stream.objects.all(): - if "Legacy" in i.name: - continue - if is_chair_of_stream(user, i): - streams.append(i) - context.update({self.var_name: streams}) - return '' - - -@register.tag -def get_user_managed_streams(parser, token): - firstbits = token.contents.split(None, 2) - if len(firstbits) != 3: - raise template.TemplateSyntaxError("'get_user_managed_streams' tag takes three arguments") - user = parser.compile_filter(firstbits[1]) - lastbits_reversed = firstbits[2][::-1].split(None, 2) - if lastbits_reversed[1][::-1] != 'as': - raise template.TemplateSyntaxError("next-to-last argument to 'get_user_managed_stream' tag must" - " be 'as'") - var_name = lastbits_reversed[0][::-1] - return StreamListNode(user, var_name) diff --git a/ietf/ietfworkflows/tests.py b/ietf/ietfworkflows/tests.py deleted file mode 100644 index 522afc907..000000000 --- a/ietf/ietfworkflows/tests.py +++ /dev/null @@ -1,189 +0,0 @@ -import datetime, os, shutil - -from django.conf import settings -from django.contrib.auth.models import User -from django.core.urlresolvers import reverse as urlreverse -from StringIO import StringIO -from pyquery import PyQuery - -from ietf.utils.test_utils import login_testing_unauthorized -from ietf.utils.test_data import make_test_data -from ietf.utils.mail import outbox -from ietf.utils import TestCase - -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - from ietf.person.models import Person, Email - from ietf.group.models import Group, Role - from ietf.doc.models import Document, State - from ietf.doc.utils import * - from ietf.name.models import DocTagName - -class EditStreamInfoTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] - - def test_adopt_document(self): - draft = make_test_data() - draft.stream = None - draft.group = Group.objects.get(type="individ") - draft.save() - draft.unset_state("draft-stream-ietf") - - url = urlreverse('edit_adopt', kwargs=dict(name=draft.name)) - login_testing_unauthorized(self, "marschairman", url) - - # get - r = self.client.get(url) - self.assertEquals(r.status_code, 200) - q = PyQuery(r.content) - self.assertEquals(len(q('form input[type=submit][value*=adopt]')), 1) - self.assertEquals(len(q('form select[name="group"] option')), 1) # we can only select "mars" - - # adopt in mars WG - mailbox_before = len(outbox) - events_before = draft.docevent_set.count() - r = self.client.post(url, - dict(comment="some comment", - group=Group.objects.get(acronym="mars").pk, - weeks="10")) - self.assertEquals(r.status_code, 302) - - draft = Document.objects.get(pk=draft.pk) - self.assertEquals(draft.group.acronym, "mars") - self.assertEquals(draft.stream_id, "ietf") - self.assertEquals(draft.docevent_set.count() - events_before, 4) - self.assertEquals(len(outbox), mailbox_before + 1) - self.assertTrue("state changed" in outbox[-1]["Subject"].lower()) - self.assertTrue("wgchairman@ietf.org" in unicode(outbox[-1])) - self.assertTrue("wgdelegate@ietf.org" in unicode(outbox[-1])) - - def test_set_tags(self): - draft = make_test_data() - draft.tags = DocTagName.objects.filter(slug="w-expert") - draft.group.unused_tags.add("w-refdoc") - - url = urlreverse('edit_state', kwargs=dict(name=draft.name)) - login_testing_unauthorized(self, "marschairman", url) - - # get - r = self.client.get(url) - self.assertEquals(r.status_code, 200) - q = PyQuery(r.content) - # make sure the unused tags are hidden - unused = draft.group.unused_tags.values_list("slug", flat=True) - for t in q("input[name=tags]"): - self.assertTrue(t.attrib["value"] not in unused) - - # set tags - mailbox_before = len(outbox) - events_before = draft.docevent_set.count() - r = self.client.post(url, - dict(comment="some comment", - weeks="10", - tags=["need-aut", "sheph-u"], - only_tags="1", - # unused but needed for validation - new_state=draft.get_state("draft-stream-%s" % draft.stream_id).pk, - )) - self.assertEquals(r.status_code, 302) - - draft = Document.objects.get(pk=draft.pk) - self.assertEquals(draft.tags.count(), 2) - self.assertEquals(draft.tags.filter(slug="w-expert").count(), 0) - self.assertEquals(draft.tags.filter(slug="need-aut").count(), 1) - self.assertEquals(draft.tags.filter(slug="sheph-u").count(), 1) - self.assertEquals(draft.docevent_set.count() - events_before, 2) - self.assertEquals(len(outbox), mailbox_before + 1) - self.assertTrue("tags changed" in outbox[-1]["Subject"].lower()) - self.assertTrue("wgchairman@ietf.org" in unicode(outbox[-1])) - self.assertTrue("wgdelegate@ietf.org" in unicode(outbox[-1])) - self.assertTrue("plain@example.com" in unicode(outbox[-1])) - - def test_set_state(self): - draft = make_test_data() - - url = urlreverse('edit_state', kwargs=dict(name=draft.name)) - login_testing_unauthorized(self, "marschairman", url) - - # get - r = self.client.get(url) - self.assertEquals(r.status_code, 200) - q = PyQuery(r.content) - # make sure the unused states are hidden - unused = draft.group.unused_states.values_list("pk", flat=True) - for t in q("select[name=new_state]").find("option[name=tags]"): - self.assertTrue(t.attrib["value"] not in unused) - self.assertEquals(len(q('select[name=new_state]')), 1) - - old_state = draft.get_state("draft-stream-%s" % draft.stream_id ) - new_state = State.objects.get(used=True, type="draft-stream-%s" % draft.stream_id, slug="parked") - self.assertTrue(old_state!=new_state) - mailbox_before = len(outbox) - events_before = draft.docevent_set.count() - - # First make sure cancel doesn't change anything - r = self.client.post(url, - dict(comment="some comment", - weeks="10", - tags=[x.pk for x in draft.tags.filter(slug__in=get_tags_for_stream_id(draft.stream_id))], - new_state=new_state.pk, - cancel="1", - )) - self.assertEquals(r.status_code, 302) - - draft = Document.objects.get(pk=draft.pk) - self.assertEquals(draft.get_state("draft-stream-%s" % draft.stream_id), old_state) - - # Set new state - r = self.client.post(url, - dict(comment="some comment", - weeks="10", - tags=[x.pk for x in draft.tags.filter(slug__in=get_tags_for_stream_id(draft.stream_id))], - new_state=new_state.pk, - )) - self.assertEquals(r.status_code, 302) - - draft = Document.objects.get(pk=draft.pk) - self.assertEquals(draft.get_state("draft-stream-%s" % draft.stream_id), new_state) - self.assertEquals(draft.docevent_set.count() - events_before, 2) - reminder = DocReminder.objects.filter(event__doc=draft, type="stream-s") - self.assertEquals(len(reminder), 1) - due = datetime.datetime.now() + datetime.timedelta(weeks=10) - self.assertTrue(due - datetime.timedelta(days=1) <= reminder[0].due <= due + datetime.timedelta(days=1)) - self.assertEquals(len(outbox), mailbox_before + 1) - self.assertTrue("state changed" in outbox[-1]["Subject"].lower()) - self.assertTrue("wgchairman@ietf.org" in unicode(outbox[-1])) - self.assertTrue("wgdelegate@ietf.org" in unicode(outbox[-1])) - - def test_manage_stream_delegates(self): - make_test_data() - - url = urlreverse('stream_delegates', kwargs=dict(stream_name="IETF")) - login_testing_unauthorized(self, "secretary", url) - - # get - r = self.client.get(url) - self.assertEquals(r.status_code, 200) - q = PyQuery(r.content) - self.assertEquals(len(q('input[type=submit][value*=Add]')), 1) - - delegate = Email.objects.get(address="plain@example.com") - - # add delegate - r = self.client.post(url, - dict(email=delegate.address)) - self.assertEquals(r.status_code, 200) - - self.assertEquals(Role.objects.filter(group__acronym="ietf", name="delegate", person__email__address=delegate.address).count(), 1) - - # remove delegate again - r = self.client.post(url, - dict(remove_delegate=[delegate.person.pk], - delete="1")) - self.assertEquals(r.status_code, 200) - - self.assertEquals(Role.objects.filter(group__acronym="ietf", name="delegate", person__email__address=delegate.address).count(), 0) - -if not settings.USE_DB_REDESIGN_PROXY_CLASSES: - # the above tests only work with the new schema - del EditStreamInfoTestCase diff --git a/ietf/ietfworkflows/urls.py b/ietf/ietfworkflows/urls.py deleted file mode 100644 index af7a885d4..000000000 --- a/ietf/ietfworkflows/urls.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright The IETF Trust 2008, All Rights Reserved - -from django.conf.urls.defaults import patterns, url -from django.views.generic.simple import redirect_to - -urlpatterns = patterns('ietf.ietfworkflows.views', - url(r'^(?P[^/]+)/history/$', 'stream_history', name='stream_history'), - url(r'^(?P[^/]+)/edit/adopt/$', 'edit_adopt', name='edit_adopt'), - # FIXME: the name edit_state is far too generic - url(r'^(?P[^/]+)/edit/state/$', 'edit_state', name='edit_state'), - url(r'^(?P[^/]+)/edit/stream/$', redirect_to, { 'url': '/doc/%(name)s/edit/info/'}) , - url(r'^delegates/(?P[^/]+)/$', 'stream_delegates', name='stream_delegates'), -) diff --git a/ietf/ietfworkflows/utils.py b/ietf/ietfworkflows/utils.py deleted file mode 100644 index 137abb765..000000000 --- a/ietf/ietfworkflows/utils.py +++ /dev/null @@ -1,471 +0,0 @@ -import copy -import datetime - -from django.conf import settings -from django.contrib.contenttypes.models import ContentType -from django.core.mail import EmailMessage -from django.template.loader import render_to_string -from django.template.defaultfilters import pluralize - -from workflows.models import State, StateObjectRelation -from workflows.utils import (get_workflow_for_object, set_workflow_for_object, - get_state, set_state) - -from ietf.ietfworkflows.streams import (get_streamed_draft, get_stream_from_draft, - set_stream_for_draft) -from ietf.ietfworkflows.models import (WGWorkflow, AnnotationTagObjectRelation, - AnnotationTag, ObjectAnnotationTagHistoryEntry, - ObjectHistoryEntry, StateObjectRelationMetadata, - ObjectWorkflowHistoryEntry, ObjectStreamHistoryEntry) -from ietf.idtracker.models import InternetDraft -from ietf.utils.mail import send_mail -from ietf.doc.models import Document, DocEvent, save_document_in_history, DocReminder, DocReminderTypeName -from ietf.group.models import Role - -WAITING_WRITEUP = 'WG Consensus: Waiting for Write-Up' -FOLLOWUP_TAG = 'Doc Shepherd Follow-up Underway' - - -def get_default_workflow_for_wg(): - try: - workflow = WGWorkflow.objects.get(name='Default WG Workflow') - return workflow - except WGWorkflow.DoesNotExist: - return None - - -def clone_transition(transition): - new = copy.copy(transition) - new.pk = None - new.save() - - # Reference original initial states - for state in transition.states.all(): - new.states.add(state) - return new - - -def clone_workflow(workflow, name): - new = WGWorkflow.objects.create(name=name, initial_state=workflow.initial_state) - - # Reference default states - for state in workflow.states.all(): - new.selected_states.add(state) - - # Reference default annotation tags - for tag in workflow.annotation_tags.all(): - new.selected_tags.add(tag) - - # Reference cloned transitions - for transition in workflow.transitions.all(): - new.transitions.add(clone_transition(transition)) - return new - - -def get_workflow_for_wg(wg, default=None): - workflow = get_workflow_for_object(wg) - try: - workflow = workflow and workflow.wgworkflow - except WGWorkflow.DoesNotExist: - workflow = None - if not workflow: - if default: - workflow = default - else: - workflow = get_default_workflow_for_wg() - if not workflow: - return None - workflow = clone_workflow(workflow, name='%s workflow' % wg) - set_workflow_for_object(wg, workflow) - return workflow - - -def get_workflow_for_draft(draft): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - return True if get_streamed_draft(draft) else None - - workflow = get_workflow_for_object(draft) - try: - workflow = workflow and workflow.wgworkflow - except WGWorkflow.DoesNotExist: - workflow = None - if not workflow: - streamed_draft = get_streamed_draft(draft) - if not streamed_draft or not streamed_draft.stream: - return None - stream = streamed_draft.stream - if stream.document_group_attribute: - group = streamed_draft.get_group() - if not group: - return None - else: - workflow = get_workflow_for_wg(group, streamed_draft.stream.workflow) - else: - workflow = stream.workflow - set_workflow_for_object(draft, workflow) - return workflow - - -def get_workflow_history_for_draft(draft, entry_type=None): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - from ietf.doc.proxy import ObjectHistoryEntryProxy - return ObjectHistoryEntryProxy.objects.filter(doc=draft).order_by('-time', '-id').select_related('by') - - ctype = ContentType.objects.get_for_model(draft) - filter_param = {'content_type': ctype, - 'content_id': draft.pk} - if entry_type: - filter_param.update({'%s__isnull' % entry_type: False}) - history = ObjectHistoryEntry.objects.filter(**filter_param).\ - select_related('objectworkflowhistoryentry', 'objectannotationtaghistoryentry', - 'objectstreamhistoryentry') - return history - - -def get_annotation_tags_for_draft(draft): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - from ietf.name.proxy import AnnotationTagObjectRelationProxy - from ietf.doc.utils import get_tags_for_stream_id - return AnnotationTagObjectRelationProxy.objects.filter(document=draft.pk, slug__in=get_tags_for_stream_id(draft.stream_id)) - - ctype = ContentType.objects.get_for_model(draft) - tags = AnnotationTagObjectRelation.objects.filter(content_type=ctype, content_id=draft.pk) - return tags - - -def get_state_for_draft(draft): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - return draft.get_state("draft-stream-%s" % draft.stream_id) - return get_state(draft) - - -def get_state_by_name(state_name): - try: - return State.objects.get(used=True, name=state_name) - except State.DoesNotExist: - return None - - -def get_annotation_tag_by_name(tag_name): - try: - return AnnotationTag.objects.get(name=tag_name) - except AnnotationTag.DoesNotExist: - return None - - -def set_tag(obj, tag): - ctype = ContentType.objects.get_for_model(obj) - (relation, created) = AnnotationTagObjectRelation.objects.get_or_create( - content_type=ctype, - content_id=obj.pk, - annotation_tag=tag) - return relation - - -def set_tag_by_name(obj, tag_name): - try: - tag = AnnotationTag.objects.get(name=tag_name) - return set_tag(obj, tag) - except AnnotationTag.DoesNotExist: - return None - - -def reset_tag(obj, tag): - ctype = ContentType.objects.get_for_model(obj) - try: - tag_relation = AnnotationTagObjectRelation.objects.get( - content_type=ctype, - content_id=obj.pk, - annotation_tag=tag) - tag_relation.delete() - return True - except AnnotationTagObjectRelation.DoesNotExist: - return False - - -def reset_tag_by_name(obj, tag_name): - try: - tag = AnnotationTag.objects.get(name=tag_name) - return reset_tag(obj, tag) - except AnnotationTag.DoesNotExist: - return False - - -def set_state_for_draft(draft, state, estimated_date=None): - workflow = get_workflow_for_draft(draft) - if state in workflow.get_states(): - set_state(draft, state) - relation = StateObjectRelation.objects.get( - content_type=ContentType.objects.get_for_model(draft), - content_id=draft.pk) - metadata = StateObjectRelationMetadata.objects.get_or_create(relation=relation)[0] - metadata.from_date = datetime.date.today() - metadata.to_date = estimated_date - metadata.save() - return state - return False - - -def notify_entry(entry, template, extra_notify=[]): - doc = entry.content - wg = doc.group.ietfwg - mail_list = set(['%s <%s>' % i.person.email() for i in wg.wgchair_set.all() if i.person.email()]) - mail_list = mail_list.union(['%s <%s>' % i.person.email() for i in wg.wgdelegate_set.all() if i.person.email()]) - mail_list = mail_list.union(['%s <%s>' % i.person.email() for i in doc.authors.all() if i.person.email()]) - mail_list = mail_list.union(extra_notify) - mail_list = list(mail_list) - - subject = 'Annotation tags have changed for draft %s' % doc - body = render_to_string(template, {'doc': doc, - 'entry': entry, - }) - mail = EmailMessage(subject=subject, - body=body, - to=mail_list, - from_email=settings.DEFAULT_FROM_EMAIL) - # Only send emails if we are not debug mode - if not settings.DEBUG: - mail.send() - return mail - - -def notify_tag_entry(entry, extra_notify=[]): - return notify_entry(entry, 'ietfworkflows/annotation_tags_updated_mail.txt', extra_notify) - - -def notify_state_entry(entry, extra_notify=[]): - return notify_entry(entry, 'ietfworkflows/state_updated_mail.txt', extra_notify) - - -def notify_stream_entry(entry, extra_notify=[]): - return notify_entry(entry, 'ietfworkflows/stream_updated_mail.txt', extra_notify) - -def get_notification_receivers(doc, extra_notify): - persons = set() - res = [] - for r in Role.objects.filter(group=doc.group, name__in=("chair", "delegate")): - res.append(u'"%s" <%s>' % (r.person.plain_name(), r.email.address)) - persons.add(r.person) - - for email in doc.authors.all(): - if email.person not in persons: - res.append(email.formatted_email()) - persons.add(email.person) - - for x in extra_notify: - if not x in res: - res.append(x) - - return res - -def get_pubreq_receivers(doc, extra_notify): - res = [u'"IESG Secretary" ', ] - - for r in Role.objects.filter(person=doc.group.ad,name__slug='ad'): - res.append(u'"%s" <%s>' % (r.person.plain_name(), r.email.address)) - - for x in extra_notify: - if not x in res: - res.append(x) - - return res - -def get_pubreq_cc_receivers(doc): - res = [] - - for r in Role.objects.filter(group=doc.group, name__in=("chair", "delegate")): - res.append(u'"%s" <%s>' % (r.person.plain_name(), r.email.address)) - - return res - -def update_tags(request, obj, comment, person, set_tags=[], reset_tags=[], extra_notify=[], send_email=True): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - doc = Document.objects.get(pk=obj.pk) - save_document_in_history(doc) - - obj.tags.remove(*reset_tags) - obj.tags.add(*set_tags) - - doc.time = datetime.datetime.now() - - e = DocEvent(type="changed_document", time=doc.time, by=person, doc=doc) - l = [] - if set_tags: - l.append(u"Annotation tag%s %s set." % (pluralize(set_tags), ", ".join(x.name for x in set_tags))) - if reset_tags: - l.append(u"Annotation tag%s %s cleared." % (pluralize(reset_tags), ", ".join(x.name for x in reset_tags))) - e.desc = " ".join(l) - e.save() - - if send_email: - receivers = get_notification_receivers(doc, extra_notify) - send_mail(request, receivers, settings.DEFAULT_FROM_EMAIL, - u"Annotations tags changed for draft %s" % doc.name, - 'ietfworkflows/annotation_tags_updated_mail.txt', - dict(doc=doc, - entry=dict(setted=", ".join(x.name for x in set_tags), - unsetted=", ".join(x.name for x in reset_tags), - change_date=doc.time, - person=person, - comment=comment))) - return - - ctype = ContentType.objects.get_for_model(obj) - setted = [] - resetted = [] - for tag in set_tags: - if isinstance(tag, basestring): - if set_tag_by_name(obj, tag): - setted.append(tag) - else: - if set_tag(obj, tag): - setted.append(tag.name) - for tag in reset_tags: - if isinstance(tag, basestring): - if reset_tag_by_name(obj, tag): - resetted.append(tag) - else: - if reset_tag(obj, tag): - resetted.append(tag.name) - entry = ObjectAnnotationTagHistoryEntry.objects.create( - content_type=ctype, - content_id=obj.pk, - setted=','.join(setted), - unsetted=','.join(resetted), - date=datetime.datetime.now(), - comment=comment, - person=person) - notify_tag_entry(entry, extra_notify) - - -def update_state(request, doc, comment, person, to_state, added_tags, removed_tags, estimated_date=None, extra_notify=[]): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - doc = Document.objects.get(pk=doc.pk) - save_document_in_history(doc) - - doc.time = datetime.datetime.now() - from_state = doc.get_state("draft-stream-%s" % doc.stream_id) - doc.set_state(to_state) - - e = DocEvent(type="changed_document", time=doc.time, by=person, doc=doc) - e.desc = u"%s changed to %s from %s" % (to_state.type.label, to_state, from_state) - e.save() - - # reminder - reminder_type = DocReminderTypeName.objects.get(slug="stream-s") - try: - reminder = DocReminder.objects.get(event__doc=doc, type=reminder_type, - active=True) - except DocReminder.DoesNotExist: - reminder = None - - if estimated_date: - if not reminder: - reminder = DocReminder(type=reminder_type) - - reminder.event = e - reminder.due = estimated_date - reminder.active = True - reminder.save() - elif reminder: - reminder.active = False - reminder.save() - - set_tags=", ".join(x.name for x in added_tags) - reset_tags=", ".join(x.name for x in removed_tags) - receivers = get_notification_receivers(doc, extra_notify) - send_mail(request, receivers, settings.DEFAULT_FROM_EMAIL, - u"State changed for draft %s" % doc.name, - 'ietfworkflows/state_updated_mail.txt', - dict(doc=doc, - entry=dict(from_state=from_state, - to_state=to_state, - transition_date=doc.time, - person=person, - comment=comment, - set_tags=set_tags, - reset_tags=reset_tags))) - - if (to_state.slug=='sub-pub'): - receivers = get_pubreq_receivers(doc, extra_notify) - cc_receivers = get_pubreq_cc_receivers(doc) - - send_mail(request, receivers, settings.DEFAULT_FROM_EMAIL, - u"Publication has been requested for draft %s" % doc.name, - 'ietfworkflows/state_updated_mail.txt', - dict(doc=doc, - entry=dict(from_state=from_state, - to_state=to_state, - transition_date=doc.time, - person=person, - comment=comment)), cc=cc_receivers) - - return - - ctype = ContentType.objects.get_for_model(doc) - from_state = get_state_for_draft(doc) - to_state = set_state_for_draft(doc, to_state, estimated_date) - if not to_state: - return False - entry = ObjectWorkflowHistoryEntry.objects.create( - content_type=ctype, - content_id=doc.pk, - from_state=from_state and from_state.name or '', - to_state=to_state and to_state.name or '', - date=datetime.datetime.now(), - comment=comment, - person=person) - notify_state_entry(entry, extra_notify) - - -def update_stream(request, doc, comment, person, to_stream, extra_notify=[]): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - doc = Document.objects.get(pk=doc.pk) - save_document_in_history(doc) - - doc.time = datetime.datetime.now() - from_stream = doc.stream - doc.stream = to_stream - doc.save() - - e = DocEvent(type="changed_stream", time=doc.time, by=person, doc=doc) - e.desc = u"Stream changed to %s" % to_stream.name - if from_stream: - e.desc += u"from %s" % from_stream.name - e.save() - - receivers = get_notification_receivers(doc, extra_notify) - send_mail(request, receivers, settings.DEFAULT_FROM_EMAIL, - u"Stream changed for draft %s" % doc.name, - 'ietfworkflows/stream_updated_mail.txt', - dict(doc=doc, - entry=dict(from_stream=from_stream, - to_stream=to_stream, - transition_date=doc.time, - person=person, - comment=comment))) - return - - ctype = ContentType.objects.get_for_model(doc) - from_stream = get_stream_from_draft(doc) - to_stream = set_stream_for_draft(doc, to_stream) - entry = ObjectStreamHistoryEntry.objects.create( - content_type=ctype, - content_id=doc.pk, - from_stream=from_stream and from_stream.name or '', - to_stream=to_stream and to_stream.name or '', - date=datetime.datetime.now(), - comment=comment, - person=person) - notify_stream_entry(entry, extra_notify) - - -def get_full_info_for_draft(draft): - return dict( - streamed=get_streamed_draft(draft), - stream=get_stream_from_draft(draft), - workflow=get_workflow_for_draft(draft), - tags=[i.annotation_tag for i in get_annotation_tags_for_draft(draft)], - state=get_state_for_draft(draft), - shepherd=draft.shepherd if draft.shepherd_id else None, - ) diff --git a/ietf/ietfworkflows/views.py b/ietf/ietfworkflows/views.py deleted file mode 100644 index 75ad58700..000000000 --- a/ietf/ietfworkflows/views.py +++ /dev/null @@ -1,150 +0,0 @@ -from django.http import HttpResponseRedirect, HttpResponseForbidden -from django.shortcuts import get_object_or_404, render_to_response -from django.template import RequestContext -from django.conf import settings -from django.core.urlresolvers import reverse as urlreverse - -from ietf.idtracker.models import InternetDraft -from ietf.ietfworkflows.models import Stream, StreamDelegate -from ietf.ietfworkflows.forms import (DraftTagsStateForm, - NoWorkflowStateForm, - StreamDelegatesForm) -from ietf.ietfworkflows.streams import (get_stream_from_draft, - get_streamed_draft) -from ietf.ietfworkflows.utils import (get_workflow_history_for_draft, - get_workflow_for_draft, - get_annotation_tags_for_draft, - get_state_for_draft) -from ietf.ietfworkflows.accounts import (can_edit_state, can_edit_stream, - is_chair_of_stream, can_adopt) -from ietf.doc.utils import get_tags_for_stream_id -from ietf.name.models import DocTagName -from ietf.group.utils import save_group_in_history -from ietf.group.models import Group, Role - - -REDUCED_HISTORY_LEN = 20 - - -def stream_history(request, name): - draft = get_object_or_404(InternetDraft, filename=name) - streamed = get_streamed_draft(draft) - stream = get_stream_from_draft(draft) - workflow = get_workflow_for_draft(draft) - tags = [] - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - used = list(draft.tags.all()) - tags = DocTagName.objects.filter(slug__in=get_tags_for_stream_id(draft.stream_id)) - for t in tags: - t.setted = t.slug in used - else: - if workflow: - tags_setted = [i.annotation_tag.pk for i in get_annotation_tags_for_draft(draft)] - for tag in workflow.get_tags(): - tag.setted = tag.pk in tags_setted - tags.append(tag) - state = get_state_for_draft(draft) - history = get_workflow_history_for_draft(draft) - show_more = False - if len(history) > REDUCED_HISTORY_LEN: - show_more = True - - return render_to_response('ietfworkflows/stream_history.html', - {'stream': stream, - 'streamed': streamed, - 'draft': draft, - 'tags': tags, - 'state': state, - 'workflow': workflow, - 'show_more': show_more, - 'history': history[:REDUCED_HISTORY_LEN], - }, - context_instance=RequestContext(request)) - - -def _edit_draft_stream(request, draft, form_class=DraftTagsStateForm): - user = request.user - workflow = get_workflow_for_draft(draft) - if not workflow and form_class == DraftTagsStateForm: - form_class = NoWorkflowStateForm - if request.method == 'POST': - form = form_class(user=user, draft=draft, data=request.POST) - form.request = request - if request.POST.get("cancel",""): - return HttpResponseRedirect(draft.get_absolute_url()) - if form.is_valid(): - form.save() - - # This behavior surprises folks. Let's try running awhile without it. - #if form_class == NoWorkflowStateForm and settings.USE_DB_REDESIGN_PROXY_CLASSES: - # return HttpResponseRedirect(urlreverse('ietf.ietfworkflows.views.edit_state', kwargs={ 'name': draft.filename } )) - - return HttpResponseRedirect(draft.get_absolute_url()) - else: - form = form_class(user=user, draft=draft) - form.request = request - state = get_state_for_draft(draft) - stream = get_stream_from_draft(draft) - history = get_workflow_history_for_draft(draft, 'objectworkflowhistoryentry') - tags = get_annotation_tags_for_draft(draft) - milestones = draft.groupmilestone_set.all() - return render_to_response('ietfworkflows/state_edit.html', - {'draft': draft, - 'state': state, - 'stream': stream, - 'workflow': workflow, - 'history': history, - 'tags': tags, - 'form': form, - 'milestones': milestones, - }, - context_instance=RequestContext(request)) - -# these three views are reusing the same view really, which apart from -# being somewhat obscure means that there are subtle bugs (like the -# title being wrong) - would probably be better to switch to a model -# where each part is edited on its own, we come from an overview page -# anyway, so there's not a big win in putting in a common -# overview/edit page here -def edit_adopt(request, name): - draft = get_object_or_404(InternetDraft, filename=name) - if not can_adopt(request.user, draft): - return HttpResponseForbidden("You don't have permission to access this view") - return _edit_draft_stream(request, draft, NoWorkflowStateForm) - -def edit_state(request, name): - draft = get_object_or_404(InternetDraft, filename=name, stream__isnull=False) - if not can_edit_state(request.user, draft, ): - return HttpResponseForbidden("You don't have permission to access this view") - return _edit_draft_stream(request, draft, DraftTagsStateForm) - - - -def stream_delegates(request, stream_name): - stream = get_object_or_404(Stream, name=stream_name) - if not is_chair_of_stream(request.user, stream): - return HttpResponseForbidden('You have no permission to access this view') - chairs = stream.get_chairs() - form = StreamDelegatesForm(stream=stream) - if request.method == 'POST': - if request.POST.get('delete', False): - pk_list = request.POST.getlist('remove_delegate') - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - stream_group = Group.objects.get(acronym=stream.slug) - save_group_in_history(stream_group) - Role.objects.filter(person__in=pk_list, group=stream_group, name="delegate").delete() - else: - StreamDelegate.objects.filter(stream=stream, person__pk__in=pk_list).delete() - else: - form = StreamDelegatesForm(request.POST, stream=stream) - if form.is_valid(): - form.save() - form = StreamDelegatesForm(stream=stream) - delegates = stream.get_delegates() - return render_to_response('ietfworkflows/stream_delegates.html', - {'stream': stream, - 'chairs': chairs, - 'delegates': delegates, - 'form': form, - }, - context_instance=RequestContext(request)) diff --git a/ietf/ipr/__init__.py b/ietf/ipr/__init__.py index a4b306690..8b1378917 100644 --- a/ietf/ipr/__init__.py +++ b/ietf/ipr/__init__.py @@ -1,2 +1 @@ -# Copyright The IETF Trust 2007, All Rights Reserved diff --git a/ietf/ipr/admin.py b/ietf/ipr/admin.py index ca96d2b09..41fa7ca16 100644 --- a/ietf/ipr/admin.py +++ b/ietf/ipr/admin.py @@ -8,24 +8,22 @@ class IprContactAdmin(admin.ModelAdmin): admin.site.register(IprContact, IprContactAdmin) class IprDetailAdmin(admin.ModelAdmin): - list_display = ['title', 'submitted_date', 'docs', ] - search_fields = ['title', 'legal_name', ] -admin.site.register(IprDetail, IprDetailAdmin) + list_display = ['title', 'submitted_date', 'docs', 'status'] + search_fields = ['title', 'legal_name'] -class IprLicensingAdmin(admin.ModelAdmin): - pass -admin.site.register(IprLicensing, IprLicensingAdmin) + 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(IprDetail, IprDetailAdmin) class IprNotificationAdmin(admin.ModelAdmin): pass admin.site.register(IprNotification, IprNotificationAdmin) -class IprSelecttypeAdmin(admin.ModelAdmin): - pass -admin.site.register(IprSelecttype, IprSelecttypeAdmin) - class IprUpdateAdmin(admin.ModelAdmin): pass admin.site.register(IprUpdate, IprUpdateAdmin) -admin.site.register(IprDocAlias) +class IprDocAliasAdmin(admin.ModelAdmin): + raw_id_fields = ["ipr", "doc_alias"] +admin.site.register(IprDocAlias, IprDocAliasAdmin) diff --git a/ietf/ipr/feeds.py b/ietf/ipr/feeds.py index 4a1900302..3afac4b13 100644 --- a/ietf/ipr/feeds.py +++ b/ietf/ipr/feeds.py @@ -22,14 +22,9 @@ class LatestIprDisclosures(Feed): # though the database has only date, not time return datetime.combine(item.submitted_date, time(0,0,0)) def item_author_name(self, item): - s = item.get_submitter() + s = item.get_submitter() if s: - if isinstance(s.name, unicode): - # for django.VERSION[0] > 0 - return s.name - else: - # for django.VERSION[0] == 0 - return unicode(s.name, encoding='utf-8', errors='replace') + return s.name return None def item_author_email(self, item): s = item.get_submitter() diff --git a/ietf/ipr/models.py b/ietf/ipr/models.py index 35da4779d..f453d92c3 100644 --- a/ietf/ipr/models.py +++ b/ietf/ipr/models.py @@ -1,11 +1,9 @@ # Copyright The IETF Trust 2007, All Rights Reserved from django.db import models -from django.conf import settings -from ietf.utils.lazy import reverse_lazy -# ------------------------------------------------------------------------ -# Models +from ietf.doc.models import DocAlias + LICENSE_CHOICES = ( (1, 'a) No License Required for Implementers.'), @@ -23,10 +21,7 @@ STDONLY_CHOICES = ( (1, "The licensing declaration is limited solely to standards-track IETF documents."), ) SELECT_CHOICES = ( - ("0", 'NO'), - ("1", 'YES'), - ("2", 'NO'), - (0, 'NO'), # with new schema, choices are really numeric + (0, 'NO'), (1, 'YES'), (2, 'NO'), ) @@ -36,27 +31,6 @@ STATUS_CHOICES = ( ( 2, "Rejected by Administrator" ), ( 3, "Removed by Request" ), ) -# not clear why this has both an ID and selecttype -# Also not clear why a table for "YES" and "NO". -class IprSelecttype(models.Model): - type_id = models.AutoField(primary_key=True) - is_pending = models.IntegerField(unique=True, db_column="selecttype") - type_display = models.CharField(blank=True, max_length=15) - def __str__(self): - return self.type_display - class Meta: - if not settings.USE_DB_REDESIGN_PROXY_CLASSES: - db_table = 'ipr_selecttype' - -class IprLicensing(models.Model): - licensing_option = models.AutoField(primary_key=True) - value = models.CharField(max_length=255, db_column='licensing_option_value') - def __str__(self): - return self.value; - class Meta: - if not settings.USE_DB_REDESIGN_PROXY_CLASSES: - db_table = 'ipr_licensing' - class IprDetail(models.Model): ipr_id = models.AutoField(primary_key=True) @@ -93,7 +67,6 @@ class IprDetail(models.Model): applies_to_all = models.IntegerField("Applies to all IPR owned by Submitter", blank=True, null=True, choices=SELECT_CHOICES, db_column="selectowned") # Licensing Declaration fieldset - #licensing_option = models.ForeignKey(IprLicensing, db_column='licensing_option') licensing_option = models.IntegerField(null=True, blank=True, choices=LICENSE_CHOICES) lic_opt_a_sub = models.IntegerField(null=True, editable=False, choices=STDONLY_CHOICES) lic_opt_b_sub = models.IntegerField(null=True, editable=False, choices=STDONLY_CHOICES) @@ -115,20 +88,13 @@ class IprDetail(models.Model): submitted_date = models.DateField(blank=True) update_notified_date = models.DateField(null=True, blank=True) - def __str__(self): - return self.title def __unicode__(self): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - # the latin-1 decode doesn't seem necessary anymore - return self.title - return self.title.decode("latin-1", 'replace') - def docs(self): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - return list(IprDraftProxy.objects.filter(ipr=self)) - return list(self.drafts.all()) + list(self.rfcs.all()) + return self.title + @models.permalink def get_absolute_url(self): return ('ietf.ipr.views.show', [str(self.ipr_id)]) + def get_submitter(self): try: return self.contact.get(contact_type=3) @@ -137,6 +103,9 @@ class IprDetail(models.Model): except IprContact.MultipleObjectsReturned: return self.contact.filter(contact_type=3)[0] + def docs(self): + return self.iprdocalias_set.select_related("doc_alias", "doc_alias__document").order_by("id") + class IprContact(models.Model): TYPE_CHOICES = ( (1, 'Patent Holder Contact'), @@ -173,12 +142,20 @@ class IprUpdate(models.Model): processed = models.IntegerField(null=True, blank=True) -from ietf.doc.models import DocAlias - class IprDocAlias(models.Model): - ipr = models.ForeignKey(IprDetail, related_name='documents') + ipr = models.ForeignKey(IprDetail) doc_alias = models.ForeignKey(DocAlias) rev = models.CharField(max_length=2, blank=True) + + def formatted_name(self): + name = self.doc_alias.name + if name.startswith("rfc"): + return name.upper() + elif self.rev: + return "%s-%s" % (name, self.rev) + else: + return name + def __unicode__(self): if self.rev: return u"%s which applies to %s-%s" % (self.ipr, self.doc_alias.name, self.rev) @@ -189,46 +166,3 @@ class IprDocAlias(models.Model): verbose_name = "IPR document alias" verbose_name_plural = "IPR document aliases" -# proxy stuff - -from ietf.utils.proxy import TranslatingManager - -class IprDraftProxy(IprDocAlias): - objects = TranslatingManager(dict(document="doc_alias__name")) - - # document = models.ForeignKey(InternetDraft, db_column='id_document_tag', "ipr") - # document = models.ForeignKey(Rfc, db_column='rfc_number', related_name="ipr") - @property - def document(self): - from ietf.doc.proxy import DraftLikeDocAlias - return DraftLikeDocAlias.objects.get(pk=self.doc_alias_id) - - #revision = models.CharField(max_length=2) - @property - def revision(self): - return self.rev - - class Meta: - proxy = True - -IprDraft = IprDraftProxy - -class IprRfcProxy(IprDocAlias): - objects = TranslatingManager(dict(document=lambda v: ("doc_alias__name", "rfc%s" % v))) - - # document = models.ForeignKey(InternetDraft, db_column='id_document_tag', "ipr") - # document = models.ForeignKey(Rfc, db_column='rfc_number', related_name="ipr") - @property - def document(self): - from ietf.doc.proxy import DraftLikeDocAlias - return DraftLikeDocAlias.objects.get(pk=self.doc_alias_id) - - #revision = models.CharField(max_length=2) - @property - def revision(self): - return self.rev - - class Meta: - proxy = True - -IprRfc = IprRfcProxy diff --git a/ietf/ipr/new.py b/ietf/ipr/new.py index 23ba5d691..ca075c724 100644 --- a/ietf/ipr/new.py +++ b/ietf/ipr/new.py @@ -1,19 +1,18 @@ # Copyright The IETF Trust 2007, All Rights Reserved -import re -import models -import ietf.utils -from django import forms +import re, datetime -from datetime import 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 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 -from ietf.idtracker.models import Rfc, InternetDraft # ---------------------------------------------------------------- # Create base forms from models @@ -22,21 +21,19 @@ from ietf.idtracker.models import Rfc, InternetDraft 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'.""" -from django.forms import ModelForm - -class BaseIprForm(ModelForm): - licensing_option = forms.IntegerField(widget=forms.RadioSelect(choices=models.LICENSE_CHOICES), required=False) +class BaseIprForm(forms.ModelForm): + licensing_option = forms.IntegerField(widget=forms.RadioSelect(choices=LICENSE_CHOICES), 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 = models.IprDetail + 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(ModelForm): +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 = models.IprContact + model = IprContact exclude = ('ipr', 'contact_type') # Some subclassing: @@ -65,8 +62,6 @@ def new(request, type, update=None, submitter=None): one form containing fields from 4 tables -- don't build something like this again... """ - debug = "" - section_list = section_table[type].copy() section_list.update({"title":False, "new_intro":False, "form_intro":True, "form_submit":True, "form_legend": True, }) @@ -102,19 +97,11 @@ def new(request, type, update=None, submitter=None): setattr(self, contact, ContactForm(prefix=contact[:4], initial=contact_initial.get(contact, {}), *args, **kwnoinit)) rfclist_initial = "" if update: - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - from ietf.ipr.models import IprDocAlias - rfclist_initial = " ".join(a.doc_alias.name.upper() for a in IprDocAlias.objects.filter(doc_alias__name__startswith="rfc", ipr=update)) - else: - rfclist_initial = " ".join(["RFC%d" % rfc.document_id for rfc in update.rfcs.all()]) + 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: - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - from ietf.ipr.models import IprDocAlias - 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")) - else: - draftlist_initial = " ".join([draft.document.filename + (draft.revision and "-%s" % draft.revision or "") for draft in update.drafts.all()]) + 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) @@ -142,12 +129,8 @@ def new(request, type, update=None, submitter=None): rfclist = rfclist.strip().split() for rfc in rfclist: try: - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - from ietf.doc.models import DocAlias - DocAlias.objects.get(name="rfc%s" % int(rfc)) - else: - Rfc.objects.get(rfc_number=int(rfc)) - except: + 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 @@ -161,25 +144,19 @@ def new(request, type, update=None, submitter=None): if draft.endswith(".txt"): draft = draft[:-4] if re.search("-[0-9][0-9]$", draft): - filename = draft[:-3] + name = draft[:-3] rev = draft[-2:] else: - filename = draft + name = draft rev = None try: - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - from ietf.doc.models import DocAlias - id = DocAlias.objects.get(name=filename) - # proxy attribute for code below - id.revision = id.document.rev - else: - id = InternetDraft.objects.get(filename=filename) - except Exception, e: + 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." % filename) - if rev and id.revision != rev: - raise forms.ValidationError("Unexpected revision '%s' for draft %s - the current revision is %s. Please check this." % (rev, filename, id.revision)) - drafts.append("%s-%s" % (filename, id.revision)) + 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): @@ -200,12 +177,9 @@ def new(request, type, update=None, submitter=None): # 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' or '_testpost' in request.REQUEST) and not submitter: - if request.method == 'POST': - data = request.POST.copy() - else: - data = request.GET.copy() - data["submitted_date"] = datetime.now().strftime("%Y-%m-%d") + 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" @@ -222,18 +196,18 @@ def new(request, type, update=None, submitter=None): form = IprForm(data) if form.is_valid(): # Save data : - # IprDetail, IprUpdate, IprContact+, IprDraft+, IprRfc+, IprNotification + # 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" + 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" - if type == "specific": + 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 - if type == "third-party": + 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 @@ -248,7 +222,7 @@ def new(request, type, update=None, submitter=None): instance.save() if update: - updater = models.IprUpdate(ipr=instance, updated=update, status_to_be=1, processed=0) + updater = IprUpdate(ipr=instance, updated=update, status_to_be=1, processed=0) updater.save() contact_type = {"hold":1, "ietf":2, "subm": 3} @@ -263,7 +237,7 @@ def new(request, type, update=None, submitter=None): del cdata["contact_is_submitter"] except KeyError: pass - contact = models.IprContact(**dict([(str(a),b) for a,b in cdata.items()])) + 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 @@ -279,34 +253,21 @@ def new(request, type, update=None, submitter=None): # else: # log("Invalid contact: %s" % contact) - # Save IprDraft(s) + # Save draft links for draft in form.cleaned_data["draftlist"].split(): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - name = draft[:-3] - rev = draft[-2:] - - from ietf.doc.models import DocAlias - models.IprDocAlias.objects.create( - doc_alias=DocAlias.objects.get(name=name), - ipr=instance, - rev=rev) - else: - id = InternetDraft.objects.get(filename=draft[:-3]) - iprdraft = models.IprDraft(document=id, ipr=instance, revision=draft[-2:]) - iprdraft.save() + name = draft[:-3] + rev = draft[-2:] + + IprDocAlias.objects.create( + doc_alias=DocAlias.objects.get(name=name), + ipr=instance, + rev=rev) - # Save IprRfc(s) for rfcnum in form.cleaned_data["rfclist"].split(): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - from ietf.doc.models import DocAlias - models.IprDocAlias.objects.create( - doc_alias=DocAlias.objects.get(name="rfc%s" % int(rfcnum)), - ipr=instance, - rev="") - else: - rfc = Rfc.objects.get(rfc_number=int(rfcnum)) - iprrfc = models.IprRfc(document=rfc, ipr=instance) - iprrfc.save() + 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)) @@ -328,12 +289,12 @@ def new(request, type, update=None, submitter=None): form = IprForm() form.unbound_form = True - # ietf.utils.log(dir(form.ietf_contact_is_submitter)) - return render("ipr/details_edit.html", {"ipr": form, "section_list":section_list, "debug": debug}, context_instance=RequestContext(request)) + # 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(models.IprDetail, ipr_id=ipr_id) + ipr = get_object_or_404(IprDetail, ipr_id=ipr_id) if not ipr.status in [1,3]: raise Http404 type = "specific" @@ -355,9 +316,7 @@ def update(request, ipr_id=None): if request.method == 'POST': form = UpdateForm(request.POST) - elif '_testpost' in request.REQUEST: - form = UpdateForm(request.GET) - else: + else: form = UpdateForm() if not(form.is_valid()): @@ -386,6 +345,3 @@ def get_ipr_summary(data): ipr = ", ".join(ipr[:-1]) + ", and " + ipr[-1] return ipr - -# changes done by convert-096.py:changed newforms to forms -# cleaned_data diff --git a/ietf/ipr/search.py b/ietf/ipr/search.py index 9ea73a09c..bd79e02f2 100644 --- a/ietf/ipr/search.py +++ b/ietf/ipr/search.py @@ -3,28 +3,21 @@ 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 ietf.ipr.models import IprDraft, IprDetail + +from ietf.ipr.models import IprDocAlias, IprDetail from ietf.ipr.related import related_docs from ietf.utils import log, normalize_draftname from ietf.group.models import Group from ietf.doc.models import DocAlias - -def mark_last_doc(iprs): - for item in iprs: - docs = item.docs() - count = len(docs) - if count > 1: - item.last_draft = docs[count-1] - def iprs_from_docs(docs): iprs = [] for doc in docs: - from ietf.ipr.models import IprDocAlias disclosures = [ x.ipr for x in IprDocAlias.objects.filter(doc_alias=doc, ipr__status__in=[1,3]) ] doc.iprs = None if disclosures: @@ -46,67 +39,60 @@ def patent_file_search(url, q): return q in text return False -def search(request, type="", q="", id=""): +def search(request): wgs = Group.objects.filter(type="wg").select_related().order_by("acronym") - args = request.REQUEST.items() - if args: - for key, value in args: - if key == "option": - type = value - if re.match(".*search", key): - q = value - if re.match(".*id", key): - id = value - if type and q or id: - #log("Got query: type=%s, q=%s, id=%s" % (type, q, id)) + 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 type in ["document_search", "rfc_search"]: + if search_type in ["document_search", "rfc_search"]: doc = q - if type == "document_search": - if 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") - if id: - start = DocAlias.objects.filter(name=id) - if type == "rfc_search": - if q: - try: - q = int(q, 10) - except: - q = -1 - start = DocAlias.objects.filter(name__contains=q, name__startswith="rfc") - if start.count() == 1: + 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, "first": first, "iprs": iprs, "docs": docs, "doc": doc }, + 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.count(): + 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, "first": {}, "iprs": {}, "docs": {}, "doc": doc }, + 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 type == "patent_search": + elif search_type == "patent_search": iprs = IprDetail.objects.filter(legal_name__icontains=q, status__in=[1,3]).order_by("-submitted_date", "-ipr_id") - count = iprs.count() + count = len(iprs) iprs = [ ipr for ipr in iprs if not ipr.updated_by.all() ] - # Some extra information, to help us render 'and' between the - # last two documents in a sequence - mark_last_doc(iprs) return render("ipr/search_holder_result.html", {"q": q, "iprs": iprs, "count": count }, context_instance=RequestContext(request) ) - # Search by content of email or pagent_info field + # Search by patents field or content of emails for patent numbers # IPR list with documents - elif type == "patent_info_search": + 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) ) @@ -123,16 +109,13 @@ def search(request, type="", q="", id=""): iprs.append(ipr) count = len(iprs) iprs = [ ipr for ipr in iprs if not ipr.updated_by.all() ] - # Some extra information, to help us render 'and' between the - # last two documents in a sequence - iprs.sort(key=lambda x: x.ipr_id, reverse=True) # Reverse sort - mark_last_doc(iprs) + 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 type == "wg_search": + elif search_type == "wg_search": docs = list(DocAlias.objects.filter(document__group__acronym=q)) related = [] for doc in docs: @@ -149,7 +132,7 @@ def search(request, type="", q="", id=""): # Search by rfc and id title # Document list with IPRs - elif type == "title_search": + elif search_type == "title_search": docs = list(DocAlias.objects.filter(document__title__icontains=q)) related = [] for doc in docs: @@ -166,18 +149,15 @@ def search(request, type="", q="", id=""): # Search by title of IPR disclosure # IPR list with documents - elif type == "ipr_title_search": + 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() ] - # Some extra information, to help us render 'and' between the - # last two documents in a sequence - mark_last_doc(iprs) 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" % type) + 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)) diff --git a/ietf/ipr/tests.py b/ietf/ipr/tests.py index baeb70492..a6af02600 100644 --- a/ietf/ipr/tests.py +++ b/ietf/ipr/tests.py @@ -1,101 +1,281 @@ -# Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -# All rights reserved. Contact: Pasi Eronen -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# -# * Neither the name of the Nokia Corporation and/or its -# subsidiary(-ies) nor the names of its contributors may be used -# to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import os, datetime, shutil + +import urllib + +from pyquery import PyQuery -import os -import unittest -from django.test.client import Client from django.conf import settings -from ietf.utils.test_utils import SimpleUrlTestCase, RealDatabaseTest, canonicalize_feed, canonicalize_sitemap -from ietf.utils.mail import outbox, empty_outbox +from django.core.urlresolvers import reverse as urlreverse -class IprUrlTestCase(SimpleUrlTestCase): - def testUrls(self): - self.doTestUrls(__file__) - def doCanonicalize(self, url, content): - if url.startswith("/feed/"): - return canonicalize_feed(content) - elif url == "/sitemap-ipr.xml": - return canonicalize_sitemap(content) - else: - return content +from ietf.utils.test_utils import TestCase, login_testing_unauthorized +from ietf.utils.test_data import make_test_data +from ietf.utils.mail import outbox +from ietf.ipr.models import * -# this test should be ported to run on a test database instead of the -# real database, and possibly expanded -# class NewIprTestCase(unittest.TestCase,RealDatabaseTest): -# SPECIFIC_DISCLOSURE = { -# 'legal_name':'Testing Only Please Ignore', -# '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':'1149', -# 'draftlist':'draft-burdis-http-sasl-00', -# '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' -# } -# -# def setUp(self): -# self.setUpRealDatabase() -# def tearDown(self): -# self.tearDownRealDatabase() -# -# def testNewSpecific(self): -# print " Testing IPR disclosure submission" -# empty_outbox() -# c = Client() -# response = c.post('/ipr/new-specific/', self.SPECIFIC_DISCLOSURE) -# self.assertEquals(response.status_code, 200) -# self.assert_("Your IPR disclosure has been submitted" in response.content) -# self.assertEquals(len(outbox), 1) -# print "OK (1 email found in test outbox)" + +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 + + def tearDown(self): + shutil.rmtree(self.ipr_dir) + + def test_overview(self): + make_test_data() + ipr = IprDetail.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_iprs_for_drafts(self): + draft = make_test_data() + ipr = IprDetail.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) + self.assertTrue(str(ipr.pk) in r.content) + + def test_about(self): + r = self.client.get(urlreverse("ietf.ipr.views.about")) + self.assertEqual(r.status_code, 200) + self.assertTrue("File a disclosure" in r.content) + + def test_search(self): + draft = make_test_data() + ipr = IprDetail.objects.get(title="Statement regarding rights") + + 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]")) + + # find by id + r = self.client.get(url + "?option=document_search&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) + 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") + self.assertEqual(r.status_code, 200) + self.assertTrue(draft.name in r.content) + self.assertTrue(ipr.title not in r.content) + + DocAlias.objects.create(name="rfc321", document=draft) + + # find RFC + r = self.client.get(url + "?option=rfc_search&rfc_search=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) + self.assertEqual(r.status_code, 200) + self.assertTrue(ipr.title in r.content) - -class IprFileTestCase(unittest.TestCase): - def testFileExistence(self): - print " Testing if IPR disclosure files exist locally" - fpath = os.path.join(settings.IPR_DOCUMENT_PATH, "juniper-ipr-RFC-4875.txt") - if not os.path.exists(fpath): - print "\nERROR: IPR disclosure files not found in "+settings.IPR_DOCUMENT_PATH - print "They are needed for testing IPR searching." - print "Download them to a local directory with:" - print "wget -nd -nc -np -r ftp://ftp.ietf.org/ietf/IPR/" - print "And set IPR_DOCUMENT_PATH in settings_local.py\n" - else: - print "OK (they seem to exist)" - + # find by patent info + r = self.client.get(url + "?option=patent_info_search&patent_info_search=%s" % ipr.patents) + 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") + 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) + 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)) + 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)) + 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") + + 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") + + 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): + draft = make_test_data() + + url = urlreverse("ietf.ipr.new.new", kwargs={ "type": "generic" }) + + # faulty post + r = self.client.post(url, { + "legal_name": "Test Legal", + }) + self.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + self.assertTrue(len(q("ul.errorlist")) > 0) + + # 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" + }) + 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") + self.assertEqual(len(iprs), 1) + ipr = iprs[0] + self.assertEqual(ipr.legal_name, "Test Legal") + self.assertEqual(ipr.status, 0) + + def test_new_specific(self): + draft = make_test_data() + + url = urlreverse("ietf.ipr.new.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" + }) + 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) + self.assertEqual(len(iprs), 1) + ipr = iprs[0] + self.assertEqual(ipr.legal_name, "Test Legal") + self.assertEqual(ipr.status, 0) + + def test_new_thirdparty(self): + draft = make_test_data() + + url = urlreverse("ietf.ipr.new.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" + }) + self.assertEqual(r.status_code, 200) + self.assertTrue("Your IPR disclosure has been submitted" in r.content) + + iprs = IprDetail.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) + + 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 }) + + # 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" + }) + 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) + self.assertEqual(len(iprs), 1) + ipr = iprs[0] + self.assertEqual(ipr.legal_name, "Test Legal") + self.assertEqual(ipr.status, 0) + + self.assertTrue(ipr.updates.filter(updated=original_ipr)) diff --git a/ietf/ipr/testurl.list b/ietf/ipr/testurl.list deleted file mode 100644 index ca755d894..000000000 --- a/ietf/ipr/testurl.list +++ /dev/null @@ -1,73 +0,0 @@ -200 /ipr/ -200 /ipr/657/ # Generic disclosure -200 /ipr/564/ # Generic submitted by email -200 /ipr/834/ # Specific disclosure -200 /ipr/1121/ # Specific disclosure submitted by email (PDF) -200 /ipr/1173/ # Specific disclosure submitted by email (TXT) -200 /ipr/795/ # Third-party disclosure -200 /ipr/865/ # Third party disclosure submitted by email (TXT) -200 /ipr/1140/ # Non-ASCII patent holder name -200 /ipr/1069/ # Non-ASCII title -200 /ipr/1129/ # Non-ASCII other fields -200 /ipr/751/ # Updates others, and is updated by others -200 /ipr/765/ # Removed -404 /ipr/1066/ # Test record - -200 /ipr/new-generic/ -200 /ipr/new-specific/ -200 /ipr/new-third-party/ -200 /ipr/new-generic/?_testpost=1 -200 /ipr/new-specific/?_testpost=1 -200 /ipr/new-third-party/?_testpost=1 - -301 /ipr/update/ -200 /ipr/update/657/ # Generic -200 /ipr/update/820/ # Third-party -200 /ipr/update/844/ # Specific -404 /ipr/update/1066/ # Removed test record - -200 /ipr/update/657/?_testpost=1 # Generic -200 /ipr/update/820/?_testpost=1 # Third-party -200 /ipr/update/844/?_testpost=1 # Specific -200 /ipr/update/657/?_testpost=1&email=test@example.com&name=Test&telephone=123&update_auth=on -200 /ipr/update/820/?_testpost=1&email=test@example.com&name=Test&telephone=123&update_auth=on -200 /ipr/update/844/?_testpost=1&email=test@example.com&name=Test&telephone=123&update_auth=on - -200 /ipr/search/ -302 /ipr/search/?option=document_search # incomplete argument set gives redirect - -200 /ipr/search/?document_search=mod&option=document_search # Returns document list -200 /ipr/search/?id_document_tag=2220&option=document_search # Simple case -200 /ipr/search/?id_document_tag=2221&option=document_search # Empty result -200 /ipr/search/?id_document_tag=2221x&option=document_search # Non-numeric -200 /ipr/search/?option=document_search&document_search=draft-housley-tls-authz-extns-05 # More complex result - -200 /ipr/search/?rfc_search=1034&option=rfc_search # Loong result -200 /ipr/search/?rfc_search=4555&option=rfc_search # Simple result -200 /ipr/search/?rfc_search=4444&option=rfc_search # Empty result -200 /ipr/search/?rfc_search=4xyz&option=rfc_search # non-numeric - -200 /ipr/search/?patent_search=nortel&option=patent_search -200 /ipr/search/?patent_search=nortelxz&option=patent_search # Empty result - -200 /ipr/search/?wg_search=dnsext&option=wg_search -200 /ipr/search/?wg_search=aaa&option=wg_search -200 /ipr/search/?wg_search=acct&option=wg_search # Empty result - -200 /ipr/search/?option=title_search&title_search=AAA -200 /ipr/search/?option=title_search&title_search=AAAxz # Empty result - -200 /ipr/search/?patent_info_search=123&option=patent_info_search -200 /ipr/search/?patent_info_search=31415&option=patent_info_search # Empty result -200 /ipr/search/?patent_info_search=12&option=patent_info_search # Error: at least 3 characters -200 /ipr/search/?patent_info_search=abc&option=patent_info_search # Error: at least 1 digit - -200 /ipr/search/?option=ipr_title_search&ipr_title_search=nortel -200 /ipr/search/?option=ipr_title_search&ipr_title_search=nortelxz # Empty result -404 /ipr/search/?id_document_tag=12345 # no search type: 404 - -200 /ipr/about/ -200 /ipr/by-draft/ - -200 /feed/ipr/ -200 /sitemap-ipr.xml diff --git a/ietf/ipr/urls.py b/ietf/ipr/urls.py index 43ad3749f..e27c38224 100644 --- a/ietf/ipr/urls.py +++ b/ietf/ipr/urls.py @@ -7,8 +7,8 @@ from django.views.generic.simple import redirect_to urlpatterns = patterns('', url(r'^$', views.showlist, name='ipr_showlist'), - (r'^about/$', views.default), - (r'^by-draft/$', views.list_drafts), + (r'^about/$', views.about), + (r'^by-draft/$', views.iprs_for_drafts_txt), url(r'^(?P\d+)/$', views.show, name='ipr_show'), (r'^update/$', redirect_to, { 'url': reverse_lazy('ipr_showlist') }), (r'^update/(?P\d+)/$', new.update), @@ -17,7 +17,3 @@ urlpatterns = patterns('', (r'^new-(?Pthird-party)/$', new.new), url(r'^search/$', search.search, name="ipr_search"), ) - - - - diff --git a/ietf/ipr/view_sections.py b/ietf/ipr/view_sections.py index 385b18af2..45b41f6f6 100644 --- a/ietf/ipr/view_sections.py +++ b/ietf/ipr/view_sections.py @@ -1,6 +1,5 @@ # Copyright The IETF Trust 2007, All Rights Reserved - section_table = { "specific": { "title": True, "specific": 1, "generic": 0, "third_party": 0, @@ -38,3 +37,15 @@ section_table = { "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"] + diff --git a/ietf/ipr/views.py b/ietf/ipr/views.py index 4cca6d8f1..bc6df1076 100644 --- a/ietf/ipr/views.py +++ b/ietf/ipr/views.py @@ -1,18 +1,18 @@ # Copyright The IETF Trust 2007, All Rights Reserved +import os + from django.shortcuts import render_to_response as render, get_object_or_404 from django.template import RequestContext from django.template.loader import render_to_string from django.http import HttpResponse, Http404 from django.conf import settings -from ietf.idtracker.models import IETFWG -from ietf.ipr.models import IprDetail, SELECT_CHOICES, LICENSE_CHOICES -from ietf.ipr.view_sections import section_table -from ietf.utils import log -import os -def default(request): - """Default page, with links to sub-pages""" +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 Document + +def about(request): return render("ipr/disclosure.html", {}, context_instance=RequestContext(request)) def showlist(request): @@ -20,7 +20,7 @@ def showlist(request): 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) - + return render("ipr/list.html", { 'generic_disclosures' : generic_disclosures.order_by(* ['-submitted_date', ] ), @@ -28,56 +28,6 @@ def showlist(request): 'thirdpty_disclosures': thirdpty_disclosures.order_by(* ['-submitted_date', ] ), }, context_instance=RequestContext(request) ) -def list_drafts(request): - iprs = IprDetail.objects.filter(status=1) - docipr = {} - docs = [] - for ipr in iprs: - for draft in ipr.drafts.all(): - name = draft.document.filename - if not name in docipr: - docipr[name] = [] - docipr[name] += [ ipr.ipr_id ] - for rfc in ipr.rfcs.all(): - name = "RFC%04d" % rfc.document.rfc_number - if not name in docipr: - docipr[name] = [] - docipr[name] += [ ipr.ipr_id ] - docs = [ {"name":key, "iprs":value, } for key,value in docipr.items() ] - return HttpResponse(render_to_string("ipr/drafts.html", { "docs":docs, }, - context_instance=RequestContext(request)), - mimetype="text/plain") - -def list_draftsREDESIGN(request): - from ietf.ipr.models import IprDocAlias - - docipr = {} - - for o in IprDocAlias.objects.filter(ipr__status=1).select_related("doc_alias"): - name = o.doc_alias.name - if name.startswith("rfc"): - name = name.upper() - - if not name in docipr: - docipr[name] = [] - - docipr[name].append(o.ipr_id) - - docs = [ dict(name=name, iprs=sorted(iprs)) for name, iprs in docipr.iteritems() ] - - # drafts.html is not an HTML file - return HttpResponse(render_to_string("ipr/drafts.html", - dict(docs=docs), - context_instance=RequestContext(request)), - mimetype="text/plain") - - -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - list_drafts = list_draftsREDESIGN - - -# Details views - def show(request, ipr_id=None, removed=None): """Show a specific IPR disclosure""" assert ipr_id != None @@ -87,9 +37,9 @@ def show(request, ipr_id=None, removed=None): context_instance=RequestContext(request)) if removed and ipr.status != 3: raise Http404 - if not ipr.status == 1 and not removed: + if ipr.status != 1 and not removed: raise Http404 - section_list = get_section_list(ipr) + section_list = section_list_for_ipr(ipr) contacts = ipr.contact.all() for contact in contacts: if contact.contact_type == 1: @@ -122,24 +72,30 @@ def show(request, ipr_id=None, removed=None): # if file does not exist, iframe is used instead pass - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - from ietf.ipr.models import IprDraft, IprRfc - ipr.drafts = IprDraft.objects.filter(ipr=ipr).exclude(doc_alias__name__startswith="rfc").order_by("id") - ipr.rfcs = IprRfc.objects.filter(ipr=ipr).filter(doc_alias__name__startswith="rfc").order_by("id") + 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")] return render("ipr/details.html", {"ipr": ipr, "section_list": section_list}, context_instance=RequestContext(request)) +def iprs_for_drafts_txt(request): + docipr = {} -# ---- Helper functions ------------------------------------------------------ + for o in IprDocAlias.objects.filter(ipr__status=1).select_related("doc_alias"): + name = o.doc_alias.name + if name.startswith("rfc"): + name = name.upper() + + if not name in docipr: + docipr[name] = [] + + docipr[name].append(o.ipr_id) + + 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), mimetype="text/plain") -def get_section_list(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"] diff --git a/ietf/liaisons/__init__.py b/ietf/liaisons/__init__.py index 3f64c6e2b..aeccae32c 100644 --- a/ietf/liaisons/__init__.py +++ b/ietf/liaisons/__init__.py @@ -2,7 +2,7 @@ # coding: latin-1 from types import ModuleType -import urls, models, views, forms, accounts, admin, utils, widgets, decorators, sitemaps, feeds +import urls, models, views, forms, admin, utils, widgets, sitemaps, feeds # These people will be sent a stack trace if there's an uncaught exception in # code any of the modules imported above: diff --git a/ietf/liaisons/accounts.py b/ietf/liaisons/accounts.py index 144c0bd53..a86cc33fd 100644 --- a/ietf/liaisons/accounts.py +++ b/ietf/liaisons/accounts.py @@ -1,14 +1,21 @@ -from django.conf import settings +from ietf.person.models import Person +from ietf.group.models import Role -from ietf.idtracker.models import Role, PersonOrOrgInfo +def proxy_personify_role(role): + """Return person from role with an old-school email() method using + email from role.""" + p = role.person + p.email = lambda: (p.plain_name(), role.email.address) + return p - -LIAISON_EDIT_GROUPS = ['Secretariat'] +LIAISON_EDIT_GROUPS = ['Secretariat'] # this is not working anymore, refers to old auth model def get_ietf_chair(): - person = PersonOrOrgInfo.objects.filter(role=Role.IETF_CHAIR) - return person and person[0] or None + try: + return proxy_personify_role(Role.objects.get(name="chair", group__acronym="ietf")) + except Role.DoesNotExist: + return None def get_iesg_chair(): @@ -16,48 +23,62 @@ def get_iesg_chair(): def get_iab_chair(): - person = PersonOrOrgInfo.objects.filter(role=Role.IAB_CHAIR) - return person and person[0] or None - - -def get_iab_executive_director(): - person = PersonOrOrgInfo.objects.filter(role=Role.IAB_EXCUTIVE_DIRECTOR) - return person and person[0] or None - - -def get_person_for_user(user): try: - return user.get_profile().person() - except: + return proxy_personify_role(Role.objects.get(name="chair", group__acronym="iab")) + except Role.DoesNotExist: return None +def get_irtf_chair(): + try: + return proxy_personify_role(Role.objects.get(name="chair", group__acronym="irtf")) + except Role.DoesNotExist: + return None + + +def get_iab_executive_director(): + try: + return proxy_personify_role(Role.objects.get(name="execdir", group__acronym="iab")) + except Person.DoesNotExist: + return None + + +def get_person_for_user(user): + if not user.is_authenticated(): + return None + try: + p = user.get_profile() + p.email = lambda: (p.plain_name(), p.email_address()) + return p + except Person.DoesNotExist: + return None + def is_areadirector(person): - return bool(person.areadirector_set.all()) + return bool(Role.objects.filter(person=person, name="ad", group__state="active", group__type="area")) def is_wgchair(person): - return bool(person.wgchair_set.all()) + return bool(Role.objects.filter(person=person, name="chair", group__state="active", group__type="wg")) def is_wgsecretary(person): - return bool(person.wgsecretary_set.all()) - - -def has_role(person, role): - return bool(person.role_set.filter(pk=role)) + return bool(Role.objects.filter(person=person, name="sec", group__state="active", group__type="wg")) def is_ietfchair(person): - return has_role(person, Role.IETF_CHAIR) + return bool(Role.objects.filter(person=person, name="chair", group__acronym="ietf")) def is_iabchair(person): - return has_role(person, Role.IAB_CHAIR) + return bool(Role.objects.filter(person=person, name="chair", group__acronym="iab")) def is_iab_executive_director(person): - return has_role(person, Role.IAB_EXCUTIVE_DIRECTOR) + return bool(Role.objects.filter(person=person, name="execdir", group__acronym="iab")) + + +def is_irtfchair(person): + return bool(Role.objects.filter(person=person, name="chair", group__acronym="irtf")) def can_add_outgoing_liaison(user): @@ -74,15 +95,17 @@ def can_add_outgoing_liaison(user): def is_sdo_liaison_manager(person): - return bool(person.liaisonmanagers_set.all()) + return bool(Role.objects.filter(person=person, name="liaiman", group__type="sdo")) def is_sdo_authorized_individual(person): - return bool(person.sdoauthorizedindividual_set.all()) + return bool(Role.objects.filter(person=person, name="auth", group__type="sdo")) def is_secretariat(user): - return bool(user.groups.filter(name='Secretariat')) + if isinstance(user, basestring): + return False + return user.is_authenticated() and bool(Role.objects.filter(person__user=user, name="secr", group__acronym="secretariat")) def can_add_incoming_liaison(user): @@ -102,36 +125,14 @@ def can_add_liaison(user): def is_sdo_manager_for_outgoing_liaison(person, liaison): - from ietf.liaisons.utils import IETFHM, SDOEntity - from ietf.liaisons.models import SDOs - from_entity = IETFHM.get_entity_by_key(liaison.from_raw_code) - sdo = None - if not from_entity: - try: - sdo = SDOs.objects.get(sdo_name=liaison.from_body()) - except SDOs.DoesNotExist: - pass - elif isinstance(from_entity, SDOEntity): - sdo = from_entity.obj - if sdo: - return bool(sdo.liaisonmanagers_set.filter(person=person)) + if liaison.from_group and liaison.from_group.type_id == "sdo": + return bool(liaison.from_group.role_set.filter(name="liaiman", person=person)) return False def is_sdo_manager_for_incoming_liaison(person, liaison): - from ietf.liaisons.utils import IETFHM, SDOEntity - from ietf.liaisons.models import SDOs - to_entity = IETFHM.get_entity_by_key(liaison.to_raw_code) - sdo = None - if not to_entity: - try: - sdo = SDOs.objects.get(sdo_name=liaison.to_body) - except SDOs.DoesNotExist: - pass - elif isinstance(to_entity, SDOEntity): - sdo = to_entity.obj - if sdo: - return bool(sdo.liaisonmanagers_set.filter(person=person)) + if liaison.to_group and liaison.to_group.type_id == "sdo": + return bool(liaison.to_group.role_set.filter(name="liaiman", person=person)) return False @@ -143,6 +144,3 @@ def can_edit_liaison(user, liaison): return (is_sdo_manager_for_outgoing_liaison(person, liaison) or is_sdo_manager_for_incoming_liaison(person, liaison)) return False - -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - from accountsREDESIGN import * diff --git a/ietf/liaisons/accountsREDESIGN.py b/ietf/liaisons/accountsREDESIGN.py deleted file mode 100644 index fc3fffa07..000000000 --- a/ietf/liaisons/accountsREDESIGN.py +++ /dev/null @@ -1,140 +0,0 @@ -from ietf.person.models import Person -from ietf.group.models import Role -from ietf.utils.proxy import proxy_personify_role - -LIAISON_EDIT_GROUPS = ['Secretariat'] # this is not working anymore, refers to old auth model - - -def get_ietf_chair(): - try: - return proxy_personify_role(Role.objects.get(name="chair", group__acronym="ietf")) - except Role.DoesNotExist: - return None - - -def get_iesg_chair(): - return get_ietf_chair() - - -def get_iab_chair(): - try: - return proxy_personify_role(Role.objects.get(name="chair", group__acronym="iab")) - except Role.DoesNotExist: - return None - - -def get_irtf_chair(): - try: - return proxy_personify_role(Role.objects.get(name="chair", group__acronym="irtf")) - except Role.DoesNotExist: - return None - - -def get_iab_executive_director(): - try: - return proxy_personify_role(Role.objects.get(name="execdir", group__acronym="iab")) - except Person.DoesNotExist: - return None - - -def get_person_for_user(user): - if not user.is_authenticated(): - return None - try: - p = user.get_profile() - p.email = lambda: (p.plain_name(), p.email_address()) - return p - except Person.DoesNotExist: - return None - -def is_areadirector(person): - return bool(Role.objects.filter(person=person, name="ad", group__state="active", group__type="area")) - - -def is_wgchair(person): - return bool(Role.objects.filter(person=person, name="chair", group__state="active", group__type="wg")) - - -def is_wgsecretary(person): - return bool(Role.objects.filter(person=person, name="sec", group__state="active", group__type="wg")) - - -def is_ietfchair(person): - return bool(Role.objects.filter(person=person, name="chair", group__acronym="ietf")) - - -def is_iabchair(person): - return bool(Role.objects.filter(person=person, name="chair", group__acronym="iab")) - - -def is_iab_executive_director(person): - return bool(Role.objects.filter(person=person, name="execdir", group__acronym="iab")) - - -def is_irtfchair(person): - return bool(Role.objects.filter(person=person, name="chair", group__acronym="irtf")) - - -def can_add_outgoing_liaison(user): - person = get_person_for_user(user) - if not person: - return False - - if (is_areadirector(person) or is_wgchair(person) or - is_wgsecretary(person) or is_ietfchair(person) or - is_iabchair(person) or is_iab_executive_director(person) or - is_sdo_liaison_manager(person) or is_secretariat(user)): - return True - return False - - -def is_sdo_liaison_manager(person): - return bool(Role.objects.filter(person=person, name="liaiman", group__type="sdo")) - - -def is_sdo_authorized_individual(person): - return bool(Role.objects.filter(person=person, name="auth", group__type="sdo")) - - -def is_secretariat(user): - if isinstance(user, basestring): - return False - return user.is_authenticated() and bool(Role.objects.filter(person__user=user, name="secr", group__acronym="secretariat")) - - -def can_add_incoming_liaison(user): - person = get_person_for_user(user) - if not person: - return False - - if (is_sdo_liaison_manager(person) or - is_sdo_authorized_individual(person) or - is_secretariat(user)): - return True - return False - - -def can_add_liaison(user): - return can_add_incoming_liaison(user) or can_add_outgoing_liaison(user) - - -def is_sdo_manager_for_outgoing_liaison(person, liaison): - if liaison.from_group and liaison.from_group.type_id == "sdo": - return bool(liaison.from_group.role_set.filter(name="liaiman", person=person)) - return False - - -def is_sdo_manager_for_incoming_liaison(person, liaison): - if liaison.to_group and liaison.to_group.type_id == "sdo": - return bool(liaison.to_group.role_set.filter(name="liaiman", person=person)) - return False - - -def can_edit_liaison(user, liaison): - if is_secretariat(user): - return True - person = get_person_for_user(user) - if is_sdo_liaison_manager(person): - return (is_sdo_manager_for_outgoing_liaison(person, liaison) or - is_sdo_manager_for_incoming_liaison(person, liaison)) - return False diff --git a/ietf/liaisons/admin.py b/ietf/liaisons/admin.py index f34ea433b..21385011e 100644 --- a/ietf/liaisons/admin.py +++ b/ietf/liaisons/admin.py @@ -8,10 +8,3 @@ class LiaisonStatementAdmin(admin.ModelAdmin): ordering = ('title', ) raw_id_fields = ('from_contact', 'related_to', 'from_group', 'to_group', 'attachments') admin.site.register(LiaisonStatement, LiaisonStatementAdmin) - -class LiaisonDetailAdmin(admin.ModelAdmin): - list_display = ['pk', 'title', 'from_id', 'to_body', 'submitted_date', 'purpose', 'related_to' ] - list_display_links = ['pk', 'title'] - ordering = ('title', ) -admin.site.register(LiaisonDetail, LiaisonDetailAdmin) - \ No newline at end of file diff --git a/ietf/liaisons/decorators.py b/ietf/liaisons/decorators.py deleted file mode 100644 index 744082211..000000000 --- a/ietf/liaisons/decorators.py +++ /dev/null @@ -1,5 +0,0 @@ -from ietf.ietfauth.decorators import passes_test_decorator -from ietf.liaisons.accounts import can_add_liaison - -can_submit_liaison = passes_test_decorator(lambda u, *args, **kwargs: can_add_liaison(u), - "Restricted to participants who are authorized to submit liaison statements on behalf of the various IETF entities") diff --git a/ietf/liaisons/feeds.py b/ietf/liaisons/feeds.py index 5b5e38716..4e62bb5cb 100644 --- a/ietf/liaisons/feeds.py +++ b/ietf/liaisons/feeds.py @@ -1,24 +1,22 @@ # Copyright The IETF Trust 2007, All Rights Reserved +import re, datetime + from django.conf import settings from django.contrib.syndication.feeds import Feed, FeedDoesNotExist from django.utils.feedgenerator import Atom1Feed from django.db.models import Q -from ietf.liaisons.models import LiaisonDetail, FromBodies -from ietf.idtracker.models import Acronym -from datetime import datetime, time -import re +from django.core.urlresolvers import reverse as urlreverse -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - from ietf.group.models import Group - from ietf.liaisons.proxy import LiaisonDetailProxy as LiaisonDetail - from ietf.liaisons.models import LiaisonStatement +from ietf.group.models import Group +from ietf.liaisons.models import LiaisonStatement # A slightly funny feed class, the 'object' is really # just a dict with some parameters that items() uses # to construct a queryset. class Liaisons(Feed): feed_type = Atom1Feed + def get_object(self, bits): obj = {} if bits[0] == 'recent': @@ -27,77 +25,50 @@ class Liaisons(Feed): obj['title'] = 'Recent Liaison Statements' obj['limit'] = 15 return obj - if bits[0] == 'from': + + if bits[0] == 'from': if len(bits) != 2: raise FeedDoesNotExist - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - try: - group = Group.objects.get(acronym=bits[1]) - obj['filter'] = { 'from_group': group } - obj['title'] = u'Liaison Statements from %s' % group.name + try: + group = Group.objects.get(acronym=bits[1]) + obj['filter'] = { 'from_group': group } + obj['title'] = u'Liaison Statements from %s' % group.name + return obj + except Group.DoesNotExist: + # turn all-nonword characters into one-character + # wildcards to make it easier to construct a URL that + # matches + search_string = re.sub(r"[^a-zA-Z1-9]", ".", bits[1]) + statements = LiaisonStatement.objects.filter(from_name__iregex=search_string) + if statements: + name = statements[0].from_name + obj['filter'] = { 'from_name': name } + obj['title'] = u'Liaison Statements from %s' % name return obj - except Group.DoesNotExist: - # turn all-nonword characters into one-character - # wildcards to make it easier to construct the URL - search_string = re.sub(r"[^a-zA-Z1-9]", ".", bits[1]) - statements = LiaisonStatement.objects.filter(from_name__iregex=search_string) - if statements: - name = statements[0].from_name - obj['filter'] = { 'from_name': name } - obj['title'] = u'Liaison Statements from %s' % name - return obj - else: - raise FeedDoesNotExist - try: - acronym = Acronym.objects.get(acronym=bits[1]) - obj['filter'] = {'from_id': acronym.acronym_id} - body = bits[1] - except Acronym.DoesNotExist: - # Find body matches. Turn all non-word characters - # into wildcards for the like search. - # Note that supplying sql here means that this is - # mysql-specific (e.g., postgresql wants 'ilike' for - # the same operation) - body_list = FromBodies.objects.values('from_id','body_name').extra(where=['body_name like "%s"' % re.sub('\W', '_', bits[1])]) - if not body_list: - raise FeedDoesNotExist - frmlist = [b['from_id'] for b in body_list] - # Assume that all of the matches have the same name. - # This is not guaranteed (e.g., a url like '-----------' - # will match several bodies) but is true of well-formed - # inputs. - body = body_list[0]['body_name'] - obj['filter'] = {'from_id__in': frmlist} - obj['title'] = 'Liaison Statements from %s' % body - return obj - if bits[0] == 'to': + else: + raise FeedDoesNotExist + + if bits[0] == 'to': if len(bits) != 2: raise FeedDoesNotExist - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - obj['filter'] = dict(to_name__icontains=bits[1]) - else: - # The schema uses two different fields for the same - # basic purpose, depending on whether it's a Secretariat-submitted - # or Liaison-tool-submitted document. - obj['q'] = [ (Q(by_secretariat=0) & Q(to_body__icontains=bits[1])) | (Q(by_secretariat=1) & Q(submitter_name__icontains=bits[1])) ] - obj['title'] = 'Liaison Statements where to matches %s' % bits[1] - return obj + obj['filter'] = dict(to_name__icontains=bits[1]) + obj['title'] = 'Liaison Statements where to matches %s' % bits[1] + return obj + if bits[0] == 'subject': if len(bits) != 2: raise FeedDoesNotExist - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - obj['q'] = [ Q(title__icontains=bits[1]) | Q(attachments__title__icontains=bits[1]) ] - else: - obj['q'] = [ Q(title__icontains=bits[1]) | Q(uploads__file_title__icontains=bits[1]) ] - obj['title'] = 'Liaison Statements where subject matches %s' % bits[1] + + obj['q'] = [ Q(title__icontains=bits[1]) | Q(attachments__title__icontains=bits[1]) ] + obj['title'] = 'Liaison Statements where subject matches %s' % bits[1] return obj raise FeedDoesNotExist def get_feed(self, url=None): - if not url: - raise FeedDoesNotExist - else: + if url: return Feed.get_feed(self, url=url) + else: + raise FeedDoesNotExist def title(self, obj): return obj['title'] @@ -106,12 +77,16 @@ class Liaisons(Feed): # no real equivalent for any objects return '/liaison/' + def item_link(self, obj): + # no real equivalent for any objects + return urlreverse("liaison_detail", kwargs={ "object_id": obj.pk }) + def description(self, obj): return self.title(obj) def items(self, obj): # Start with the common queryset - qs = LiaisonDetail.objects.all().order_by("-submitted_date") + qs = LiaisonStatement.objects.all().order_by("-submitted") if obj.has_key('q'): qs = qs.filter(*obj['q']) if obj.has_key('filter'): @@ -123,7 +98,7 @@ class Liaisons(Feed): def item_pubdate(self, item): # this method needs to return a datetime instance, even # though the database has only date, not time - return datetime.combine(item.submitted_date, time(0,0,0)) + return item.submitted def item_author_name(self, item): - return item.from_body() + return item.from_name diff --git a/ietf/liaisons/forms.py b/ietf/liaisons/forms.py index 0cfc391f7..8c895fc1f 100644 --- a/ietf/liaisons/forms.py +++ b/ietf/liaisons/forms.py @@ -1,4 +1,4 @@ -import datetime +import datetime, os from email.utils import parseaddr from django import forms @@ -8,26 +8,31 @@ from django.forms.util import ErrorList from django.core.validators import email_re from django.template.loader import render_to_string -from ietf.idtracker.models import PersonOrOrgInfo from ietf.liaisons.accounts import (can_add_outgoing_liaison, can_add_incoming_liaison, get_person_for_user, is_secretariat, is_sdo_liaison_manager) -from ietf.liaisons.models import LiaisonDetail, Uploads, OutgoingLiaisonApproval, SDOs from ietf.liaisons.utils import IETFHM from ietf.liaisons.widgets import (FromWidget, ReadOnlyWidget, ButtonWidget, ShowAttachmentsWidget, RelatedLiaisonWidget) +from ietf.liaisons.models import LiaisonStatement, LiaisonStatementPurposeName +from ietf.group.models import Group, Role +from ietf.person.models import Person, Email +from ietf.doc.models import Document -class LiaisonForm(forms.ModelForm): - +class LiaisonForm(forms.Form): + person = forms.ModelChoiceField(Person.objects.all()) from_field = forms.ChoiceField(widget=FromWidget, label=u'From') replyto = forms.CharField(label=u'Reply to') organization = forms.ChoiceField() to_poc = forms.CharField(widget=ReadOnlyWidget, label="POC", required=False) + response_contact = forms.CharField(required=False, max_length=255) + technical_contact = forms.CharField(required=False, max_length=255) cc1 = forms.CharField(widget=forms.Textarea, label="CC", required=False, help_text='Please insert one email address per line') - purpose_text = forms.CharField(widget=forms.Textarea, label='Other purpose') + purpose = forms.ChoiceField() deadline_date = forms.DateField(label='Deadline') submitted_date = forms.DateField(label='Submission date', initial=datetime.date.today()) title = forms.CharField(label=u'Title') + body = forms.CharField(widget=forms.Textarea, required=False) attachments = forms.CharField(label='Attachments', widget=ShowAttachmentsWidget, required=False) attach_title = forms.CharField(label='Title', required=False) attach_file = forms.FileField(label='File', required=False) @@ -36,38 +41,51 @@ class LiaisonForm(forms.ModelForm): require=['id_attach_title', 'id_attach_file'], required_label='title and file'), required=False) - related_to = forms.ModelChoiceField(LiaisonDetail.objects.all(), label=u'Related Liaison', widget=RelatedLiaisonWidget, required=False) + related_to = forms.ModelChoiceField(LiaisonStatement.objects.all(), label=u'Related Liaison', widget=RelatedLiaisonWidget, required=False) fieldsets = [('From', ('from_field', 'replyto')), ('To', ('organization', 'to_poc')), ('Other email addresses', ('response_contact', 'technical_contact', 'cc1')), - ('Purpose', ('purpose', 'purpose_text', 'deadline_date')), + ('Purpose', ('purpose', 'deadline_date')), ('References', ('related_to', )), ('Liaison Statement', ('title', 'submitted_date', 'body', 'attachments')), ('Add attachment', ('attach_title', 'attach_file', 'attach_button')), ] - class Meta: - model = LiaisonDetail - - class Media: - js = ("/js/jquery-1.5.1.min.js", - "/js/jquery-ui-1.8.11.custom.min.js", - "/js/liaisons.js", ) - - css = {'all': ("/css/liaisons.css", - "/css/jquery-ui-themes/jquery-ui-1.8.11.custom.css")} - def __init__(self, user, *args, **kwargs): self.user = user self.fake_person = None self.person = get_person_for_user(user) if kwargs.get('data', None): - kwargs['data'].update({'person': self.person.pk}) if is_secretariat(self.user) and 'from_fake_user' in kwargs['data'].keys(): - self.fake_person = PersonOrOrgInfo.objects.get(pk=kwargs['data']['from_fake_user']) + self.fake_person = Person.objects.get(pk=kwargs['data']['from_fake_user']) kwargs['data'].update({'person': self.fake_person.pk}) + else: + kwargs['data'].update({'person': self.person.pk}) + + self.instance = kwargs.pop("instance", None) + super(LiaisonForm, self).__init__(*args, **kwargs) + + # now copy in values from instance, like a ModelForm + if self.instance: + self.initial["person"] = self.instance.from_contact.person_id if self.instance.from_contact else None + self.initial["replyto"] = self.instance.reply_to + self.initial["to_poc"] = self.instance.to_contact + self.initial["response_contact"] = self.instance.response_contact + self.initial["technical_contact"] = self.instance.technical_contact + self.initial["cc1"] = self.instance.cc + self.initial["purpose"] = self.instance.purpose.order + self.initial["deadline_date"] = self.instance.deadline + self.initial["submitted_date"] = self.instance.submitted.date() if self.instance.submitted else None + self.initial["title"] = self.instance.title + self.initial["body"] = self.instance.body + self.initial["attachments"] = self.instance.attachments.all() + self.initial["related_to"] = self.instance.related_to_id + if "approved" in self.fields: + self.initial["approved"] = bool(self.instance.approved) + + self.fields["purpose"].choices = [("", "---------")] + [(str(l.order), l.name) for l in LiaisonStatementPurposeName.objects.all()] self.hm = IETFHM self.set_from_field() self.set_replyto_field() @@ -81,25 +99,19 @@ class LiaisonForm(forms.ModelForm): def set_required_fields(self): purpose = self.data.get('purpose', None) - if purpose == '5': - self.fields['purpose_text'].required=True - else: - self.fields['purpose_text'].required=False if purpose in ['1', '2']: - self.fields['deadline_date'].required=True + self.fields['deadline_date'].required = True else: - self.fields['deadline_date'].required=False + self.fields['deadline_date'].required = False def reset_required_fields(self): - self.fields['purpose_text'].required=True - self.fields['deadline_date'].required=True + self.fields['deadline_date'].required = True def set_from_field(self): assert NotImplemented def set_replyto_field(self): - email = self.person.email() - self.fields['replyto'].initial = email and email[1] + self.fields['replyto'].initial = self.person.email()[1] def set_organization_field(self): assert NotImplemented @@ -171,7 +183,7 @@ class LiaisonForm(forms.ModelForm): return self.hm.get_entity_by_key(organization_key) def get_poc(self, organization): - return ', '.join([i.email()[1] for i in organization.get_poc()]) + return ', '.join(u"%s <%s>" % i.email() for i in organization.get_poc()) def clean_cc1(self): value = self.cleaned_data.get('cc1', '') @@ -191,34 +203,53 @@ class LiaisonForm(forms.ModelForm): return ','.join(result) def get_cc(self, from_entity, to_entity): - #Old automatic Cc code, now we retrive it from cleaned_data - #persons = to_entity.get_cc(self.person) - #persons += from_entity.get_from_cc(self.person) - #return ', '.join(['%s <%s>' % i.email() for i in persons]) - cc = self.cleaned_data.get('cc1', '') - return cc + return self.cleaned_data.get('cc1', '') def save(self, *args, **kwargs): - liaison = super(LiaisonForm, self).save(*args, **kwargs) - self.save_extra_fields(liaison) - self.save_attachments(liaison) - return liaison + l = self.instance + if not l: + l = LiaisonStatement() + + l.title = self.cleaned_data["title"] + l.purpose = LiaisonStatementPurposeName.objects.get(order=self.cleaned_data["purpose"]) + l.body = self.cleaned_data["body"].strip() + l.deadline = self.cleaned_data["deadline_date"] + l.related_to = self.cleaned_data["related_to"] + l.reply_to = self.cleaned_data["replyto"] + l.response_contact = self.cleaned_data["response_contact"] + l.technical_contact = self.cleaned_data["technical_contact"] + + now = datetime.datetime.now() + + l.modified = now + l.submitted = datetime.datetime.combine(self.cleaned_data["submitted_date"], now.time()) + if not l.approved: + l.approved = now + + self.save_extra_fields(l) + + l.save() # we have to save here to make sure we get an id for the attachments + self.save_attachments(l) + + return l def save_extra_fields(self, liaison): - now = datetime.datetime.now() - liaison.last_modified_date = now from_entity = self.get_from_entity() - liaison.from_raw_body = from_entity.name - liaison.from_raw_code = self.cleaned_data.get('from_field') + liaison.from_name = from_entity.name + liaison.from_group = from_entity.obj + e = self.cleaned_data["person"].email_set.order_by('-active', '-time') + if e: + liaison.from_contact = e[0] + organization = self.get_to_entity() - liaison.to_raw_code = self.cleaned_data.get('organization') - liaison.to_body = organization.name - liaison.to_poc = self.get_poc(organization) - liaison.submitter_name, liaison.submitter_email = self.person.email() - liaison.cc1 = self.get_cc(from_entity, organization) - liaison.save() + liaison.to_name = organization.name + liaison.to_group = organization.obj + liaison.to_contact = self.get_poc(organization) + + liaison.cc = self.get_cc(from_entity, organization) def save_attachments(self, instance): + written = instance.attachments.all().count() for key in self.files.keys(): title_key = key.replace('file', 'title') if not key.startswith('attach_file_') or not title_key in self.data.keys(): @@ -229,13 +260,18 @@ class LiaisonForm(forms.ModelForm): extension = '.' + extension[1] else: extension = '' - attach = Uploads.objects.create( - file_title = self.data.get(title_key), - person = self.person, - detail = instance, - file_extension = extension, + written += 1 + name = instance.name() + ("-attachment-%s" % written) + attach, _ = Document.objects.get_or_create( + name = name, + defaults=dict( + title = self.data.get(title_key), + type_id = "liai-att", + external_url = name + extension, # strictly speaking not necessary, but just for the time being ... + ) ) - attach_file = open('%sfile%s%s' % (settings.LIAISON_ATTACH_PATH, attach.pk, attach.file_extension), 'w') + instance.attachments.add(attach) + attach_file = open(os.path.join(settings.LIAISON_ATTACH_PATH, attach.name + extension), 'w') attach_file.write(attached_file.read()) attach_file.close() @@ -245,8 +281,7 @@ class LiaisonForm(forms.ModelForm): exclude_filter = {'pk': self.instance.pk} else: exclude_filter = {} - exists = bool(LiaisonDetail.objects.exclude(**exclude_filter).filter(title__iexact=title).count()) - if exists: + if LiaisonStatement.objects.exclude(**exclude_filter).filter(title__iexact=title).exists(): raise forms.ValidationError('A liaison statement with the same title has previously been submitted.') return title @@ -255,20 +290,26 @@ class IncomingLiaisonForm(LiaisonForm): def set_from_field(self): if is_secretariat(self.user): - sdos = SDOs.objects.all() + sdos = Group.objects.filter(type="sdo", state="active") else: - sdo_managed = [i.sdo for i in self.person.liaisonmanagers_set.all()] - sdo_authorized = [i.sdo for i in self.person.sdoauthorizedindividual_set.all()] - sdos = set(sdo_managed).union(sdo_authorized) - self.fields['from_field'].choices = [('sdo_%s' % i.pk, i.sdo_name) for i in sdos] + sdos = Group.objects.filter(type="sdo", state="active", role__person=self.person, role__name__in=("liaiman", "auth")).distinct() + self.fields['from_field'].choices = [('sdo_%s' % i.pk, i.name) for i in sdos.order_by("name")] self.fields['from_field'].widget.submitter = unicode(self.person) + def set_replyto_field(self): + e = Email.objects.filter(person=self.person, role__group__state="active", role__name__in=["liaiman", "auth"]) + if e: + addr = e[0].address + else: + addr = self.person.email_address() + self.fields['replyto'].initial = addr + def set_organization_field(self): self.fields['organization'].choices = self.hm.get_all_incoming_entities() def get_post_only(self): from_entity = self.get_from_entity() - if is_secretariat(self.user) or self.person.sdoauthorizedindividual_set.filter(sdo=from_entity.obj): + if is_secretariat(self.user) or Role.objects.filter(person=self.person, group=from_entity.obj, name="auth"): return False return True @@ -278,6 +319,9 @@ class IncomingLiaisonForm(LiaisonForm): return super(IncomingLiaisonForm, self).clean() +def liaison_manager_sdos(person): + return Group.objects.filter(type="sdo", state="active", role__person=person, role__name="liaiman").distinct() + class OutgoingLiaisonForm(LiaisonForm): to_poc = forms.CharField(label="POC", required=True) @@ -301,17 +345,24 @@ class OutgoingLiaisonForm(LiaisonForm): all_entities += i[1] if all_entities: self.fields['from_field'].widget.full_power_on = [i[0] for i in all_entities] - self.fields['from_field'].widget.reduced_to_set = ['sdo_%s' % i.sdo.pk for i in self.person.liaisonmanagers_set.all().distinct()] + self.fields['from_field'].widget.reduced_to_set = ['sdo_%s' % i.pk for i in liaison_manager_sdos(self.person)] else: self.fields['from_field'].choices = self.hm.get_entities_for_person(self.person) self.fields['from_field'].widget.submitter = unicode(self.person) self.fieldsets[0] = ('From', ('from_field', 'replyto', 'approved')) + def set_replyto_field(self): + e = Email.objects.filter(person=self.person, role__group__state="active", role__name__in=["ad", "chair"]) + if e: + addr = e[0].address + else: + addr = self.person.email_address() + self.fields['replyto'].initial = addr + def set_organization_field(self): # If the user is a liaison manager and is nothing more, reduce the To field to his SDOs if not self.hm.get_entities_for_person(self.person) and is_sdo_liaison_manager(self.person): - sdos = [i.sdo for i in self.person.liaisonmanagers_set.all().distinct()] - self.fields['organization'].choices = [('sdo_%s' % i.pk, i.sdo_name) for i in sdos] + self.fields['organization'].choices = [('sdo_%s' % i.pk, i.name) for i in liaison_manager_sdos(self.person)] else: self.fields['organization'].choices = self.hm.get_all_outgoing_entities() self.fieldsets[1] = ('To', ('organization', 'other_organization', 'to_poc')) @@ -336,16 +387,9 @@ class OutgoingLiaisonForm(LiaisonForm): from_entity = self.get_from_entity() needs_approval = from_entity.needs_approval(self.person) if not needs_approval or self.cleaned_data.get('approved', False): - approved = True - approval_date = datetime.datetime.now() + liaison.approved = datetime.datetime.now() else: - approved = False - approval_date = None - approval = OutgoingLiaisonApproval.objects.create( - approved = approved, - approval_date = approval_date) - liaison.approval = approval - liaison.save() + liaison.approved = None def clean_to_poc(self): value = self.cleaned_data.get('to_poc', None) @@ -361,10 +405,10 @@ class OutgoingLiaisonForm(LiaisonForm): person = self.fake_person or self.person for i in self.hm.get_entities_for_person(person): all_entities += i[1] - # If the from entity is one in which the user has full privileges the to entity could be anyone + # If the from entity is one in wich the user has full privileges the to entity could be anyone if from_code in [i[0] for i in all_entities]: return to_code - sdo_codes = ['sdo_%s' % i.sdo.pk for i in person.liaisonmanagers_set.all().distinct()] + sdo_codes = ['sdo_%s' % i.pk for i in liaison_manager_sdos(person)] if to_code in sdo_codes: return to_code entity = self.get_to_entity() @@ -384,35 +428,28 @@ class EditLiaisonForm(LiaisonForm): cc1 = forms.CharField(widget=forms.TextInput, label="CC", required=False) class Meta: - model = LiaisonDetail fields = ('from_raw_body', 'to_body', 'to_poc', 'cc1', 'last_modified_date', 'title', - 'response_contact', 'technical_contact', 'purpose_text', 'body', + 'response_contact', 'technical_contact', 'body', 'deadline_date', 'purpose', 'replyto', 'related_to') def __init__(self, *args, **kwargs): super(EditLiaisonForm, self).__init__(*args, **kwargs) self.edit = True - self.initial.update({'attachments': self.instance.uploads_set.all()}) - self.fields['submitted_date'].initial = self.instance.submitted_date def set_from_field(self): - self.fields['from_field'].initial = self.instance.from_body + self.fields['from_field'].initial = self.instance.from_name def set_replyto_field(self): - self.fields['replyto'].initial = self.instance.replyto + self.fields['replyto'].initial = self.instance.reply_to def set_organization_field(self): - self.fields['organization'].initial = self.instance.to_body + self.fields['organization'].initial = self.instance.to_name def save_extra_fields(self, liaison): - now = datetime.datetime.now() - liaison.last_modified_date = now - liaison.from_raw_body = self.cleaned_data.get('from_field') - liaison.to_body = self.cleaned_data.get('organization') - liaison.to_poc = self.cleaned_data['to_poc'] - liaison.cc1 = self.cleaned_data['cc1'] - liaison.save() - + liaison.from_name = self.cleaned_data.get('from_field') + liaison.to_name = self.cleaned_data.get('organization') + liaison.to_contact = self.cleaned_data['to_poc'] + liaison.cc = self.cleaned_data['cc1'] def liaison_form_factory(request, **kwargs): user = request.user @@ -426,5 +463,3 @@ def liaison_form_factory(request, **kwargs): return IncomingLiaisonForm(user, **kwargs) return None -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - from ietf.liaisons.formsREDESIGN import * diff --git a/ietf/liaisons/formsREDESIGN.py b/ietf/liaisons/formsREDESIGN.py deleted file mode 100644 index efe2c6eb4..000000000 --- a/ietf/liaisons/formsREDESIGN.py +++ /dev/null @@ -1,474 +0,0 @@ -import datetime, os -from email.utils import parseaddr - -from django import forms -from django.conf import settings -from django.db.models import Q -from django.forms.util import ErrorList -from django.core.validators import email_re -from django.template.loader import render_to_string - -from ietf.liaisons.accounts import (can_add_outgoing_liaison, can_add_incoming_liaison, - get_person_for_user, is_secretariat, is_sdo_liaison_manager) -from ietf.liaisons.utils import IETFHM -from ietf.liaisons.widgets import (FromWidget, ReadOnlyWidget, ButtonWidget, - ShowAttachmentsWidget, RelatedLiaisonWidget) -from ietf.liaisons.models import LiaisonStatement, LiaisonStatementPurposeName -from ietf.liaisons.proxy import LiaisonDetailProxy -from ietf.group.models import Group, Role -from ietf.person.models import Person, Email -from ietf.doc.models import Document - - -class LiaisonForm(forms.Form): - person = forms.ModelChoiceField(Person.objects.all()) - from_field = forms.ChoiceField(widget=FromWidget, label=u'From') - replyto = forms.CharField(label=u'Reply to') - organization = forms.ChoiceField() - to_poc = forms.CharField(widget=ReadOnlyWidget, label="POC", required=False) - response_contact = forms.CharField(required=False, max_length=255) - technical_contact = forms.CharField(required=False, max_length=255) - cc1 = forms.CharField(widget=forms.Textarea, label="CC", required=False, help_text='Please insert one email address per line') - purpose = forms.ChoiceField() - purpose_text = forms.CharField(widget=forms.Textarea, label='Other purpose') - deadline_date = forms.DateField(label='Deadline') - submitted_date = forms.DateField(label='Submission date', initial=datetime.date.today()) - title = forms.CharField(label=u'Title') - body = forms.CharField(widget=forms.Textarea, required=False) - attachments = forms.CharField(label='Attachments', widget=ShowAttachmentsWidget, required=False) - attach_title = forms.CharField(label='Title', required=False) - attach_file = forms.FileField(label='File', required=False) - attach_button = forms.CharField(label='', - widget=ButtonWidget(label='Attach', show_on='id_attachments', - require=['id_attach_title', 'id_attach_file'], - required_label='title and file'), - required=False) - related_to = forms.ModelChoiceField(LiaisonStatement.objects.all(), label=u'Related Liaison', widget=RelatedLiaisonWidget, required=False) - - fieldsets = [('From', ('from_field', 'replyto')), - ('To', ('organization', 'to_poc')), - ('Other email addresses', ('response_contact', 'technical_contact', 'cc1')), - ('Purpose', ('purpose', 'purpose_text', 'deadline_date')), - ('References', ('related_to', )), - ('Liaison Statement', ('title', 'submitted_date', 'body', 'attachments')), - ('Add attachment', ('attach_title', 'attach_file', 'attach_button')), - ] - - class Media: - js = ("/js/jquery-1.5.1.min.js", - "/js/jquery-ui-1.8.11.custom.min.js", - "/js/liaisons.js", ) - - css = {'all': ("/css/liaisons.css", - "/css/jquery-ui-themes/jquery-ui-1.8.11.custom.css")} - - def __init__(self, user, *args, **kwargs): - self.user = user - self.fake_person = None - self.person = get_person_for_user(user) - if kwargs.get('data', None): - if is_secretariat(self.user) and 'from_fake_user' in kwargs['data'].keys(): - self.fake_person = Person.objects.get(pk=kwargs['data']['from_fake_user']) - kwargs['data'].update({'person': self.fake_person.pk}) - else: - kwargs['data'].update({'person': self.person.pk}) - - self.instance = kwargs.pop("instance", None) - - super(LiaisonForm, self).__init__(*args, **kwargs) - - # now copy in values from instance, like a ModelForm - if self.instance: - for name, field in self.fields.iteritems(): - try: - x = getattr(self.instance, name) - if name == "purpose": # proxy has a name-clash on purpose so help it - x = x.order - - try: - x = x.pk # foreign keys need the .pk, not the actual object - except AttributeError: - pass - self.initial[name] = x - except AttributeError: - # we have some fields on the form that aren't in the model - pass - self.fields["purpose"].choices = [("", "---------")] + [(str(l.order), l.name) for l in LiaisonStatementPurposeName.objects.all()] - self.hm = IETFHM - self.set_from_field() - self.set_replyto_field() - self.set_organization_field() - - def __unicode__(self): - return self.as_div() - - def get_post_only(self): - return False - - def set_required_fields(self): - purpose = self.data.get('purpose', None) - if purpose == '5': - self.fields['purpose_text'].required=True - else: - self.fields['purpose_text'].required=False - if purpose in ['1', '2']: - self.fields['deadline_date'].required=True - else: - self.fields['deadline_date'].required=False - - def reset_required_fields(self): - self.fields['purpose_text'].required=True - self.fields['deadline_date'].required=True - - def set_from_field(self): - assert NotImplemented - - def set_replyto_field(self): - self.fields['replyto'].initial = self.person.email()[1] - - def set_organization_field(self): - assert NotImplemented - - def as_div(self): - return render_to_string('liaisons/liaisonform.html', {'form': self}) - - def get_fieldsets(self): - if not self.fieldsets: - yield dict(name=None, fields=self) - else: - for fieldset, fields in self.fieldsets: - fieldset_dict = dict(name=fieldset, fields=[]) - for field_name in fields: - if field_name in self.fields.keyOrder: - fieldset_dict['fields'].append(self[field_name]) - if not fieldset_dict['fields']: - # if there is no fields in this fieldset, we continue to next fieldset - continue - yield fieldset_dict - - def full_clean(self): - self.set_required_fields() - super(LiaisonForm, self).full_clean() - self.reset_required_fields() - - def has_attachments(self): - for key in self.files.keys(): - if key.startswith('attach_file_') and key.replace('file', 'title') in self.data.keys(): - return True - return False - - def check_email(self, value): - if not value: - return - emails = value.split(',') - for email in emails: - name, addr = parseaddr(email) - if not email_re.search(addr): - raise forms.ValidationError('Invalid email address: %s' % addr) - - def clean_response_contact(self): - value = self.cleaned_data.get('response_contact', None) - self.check_email(value) - return value - - def clean_technical_contact(self): - value = self.cleaned_data.get('technical_contact', None) - self.check_email(value) - return value - - def clean_reply_to(self): - value = self.cleaned_data.get('reply_to', None) - self.check_email(value) - return value - - def clean(self): - if not self.cleaned_data.get('body', None) and not self.has_attachments(): - self._errors['body'] = ErrorList([u'You must provide a body or attachment files']) - self._errors['attachments'] = ErrorList([u'You must provide a body or attachment files']) - return self.cleaned_data - - def get_from_entity(self): - organization_key = self.cleaned_data.get('from_field') - return self.hm.get_entity_by_key(organization_key) - - def get_to_entity(self): - organization_key = self.cleaned_data.get('organization') - return self.hm.get_entity_by_key(organization_key) - - def get_poc(self, organization): - return ', '.join(u"%s <%s>" % i.email() for i in organization.get_poc()) - - def clean_cc1(self): - value = self.cleaned_data.get('cc1', '') - result = [] - errors = [] - for address in value.split('\n'): - address = address.strip(); - if not address: - continue - try: - self.check_email(address) - except forms.ValidationError: - errors.append(address) - result.append(address) - if errors: - raise forms.ValidationError('Invalid email addresses: %s' % ', '.join(errors)) - return ','.join(result) - - def get_cc(self, from_entity, to_entity): - #Old automatic Cc code, now we retrive it from cleaned_data - #persons = to_entity.get_cc(self.person) - #persons += from_entity.get_from_cc(self.person) - #return ', '.join(['%s <%s>' % i.email() for i in persons]) - cc = self.cleaned_data.get('cc1', '') - return cc - - def save(self, *args, **kwargs): - l = self.instance - if not l: - l = LiaisonDetailProxy() - - l.title = self.cleaned_data["title"] - l.purpose = LiaisonStatementPurposeName.objects.get(order=self.cleaned_data["purpose"]) - l.body = self.cleaned_data["body"].strip() - l.deadline = self.cleaned_data["deadline_date"] - l.related_to = self.cleaned_data["related_to"] - l.reply_to = self.cleaned_data["replyto"] - l.response_contact = self.cleaned_data["response_contact"] - l.technical_contact = self.cleaned_data["technical_contact"] - - now = datetime.datetime.now() - - l.modified = now - l.submitted = datetime.datetime.combine(self.cleaned_data["submitted_date"], now.time()) - if not l.approved: - l.approved = now - - self.save_extra_fields(l) - - l.save() # we have to save here to make sure we get an id for the attachments - self.save_attachments(l) - - return l - - def save_extra_fields(self, liaison): - from_entity = self.get_from_entity() - liaison.from_name = from_entity.name - liaison.from_group = from_entity.obj - e = self.cleaned_data["person"].email_set.order_by('-active') - if e: - liaison.from_contact = e[0] - - organization = self.get_to_entity() - liaison.to_name = organization.name - liaison.to_group = organization.obj - liaison.to_contact = self.get_poc(organization) - - liaison.cc = self.get_cc(from_entity, organization) - - def save_attachments(self, instance): - written = instance.attachments.all().count() - for key in self.files.keys(): - title_key = key.replace('file', 'title') - if not key.startswith('attach_file_') or not title_key in self.data.keys(): - continue - attached_file = self.files.get(key) - extension=attached_file.name.rsplit('.', 1) - if len(extension) > 1: - extension = '.' + extension[1] - else: - extension = '' - written += 1 - name = instance.name() + ("-attachment-%s" % written) - attach, _ = Document.objects.get_or_create( - name = name, - defaults=dict( - title = self.data.get(title_key), - type_id = "liai-att", - external_url = name + extension, # strictly speaking not necessary, but just for the time being ... - ) - ) - instance.attachments.add(attach) - attach_file = open(os.path.join(settings.LIAISON_ATTACH_PATH, attach.name + extension), 'w') - attach_file.write(attached_file.read()) - attach_file.close() - - def clean_title(self): - title = self.cleaned_data.get('title', None) - if self.instance and self.instance.pk: - exclude_filter = {'pk': self.instance.pk} - else: - exclude_filter = {} - exists = bool(LiaisonStatement.objects.exclude(**exclude_filter).filter(title__iexact=title).count()) - if exists: - raise forms.ValidationError('A liaison statement with the same title has previously been submitted.') - return title - - -class IncomingLiaisonForm(LiaisonForm): - - def set_from_field(self): - if is_secretariat(self.user): - sdos = Group.objects.filter(type="sdo", state="active") - else: - sdos = Group.objects.filter(type="sdo", state="active", role__person=self.person, role__name__in=("liaiman", "auth")).distinct() - self.fields['from_field'].choices = [('sdo_%s' % i.pk, i.name) for i in sdos.order_by("name")] - self.fields['from_field'].widget.submitter = unicode(self.person) - - def set_replyto_field(self): - e = Email.objects.filter(person=self.person, role__group__state="active", role__name__in=["liaiman", "auth"]) - if e: - addr = e[0].address - else: - addr = self.person.email_address() - self.fields['replyto'].initial = addr - - def set_organization_field(self): - self.fields['organization'].choices = self.hm.get_all_incoming_entities() - - def get_post_only(self): - from_entity = self.get_from_entity() - if is_secretariat(self.user) or Role.objects.filter(person=self.person, group=from_entity.obj, name="auth"): - return False - return True - - def clean(self): - if 'send' in self.data.keys() and self.get_post_only(): - self._errors['from_field'] = ErrorList([u'As an IETF Liaison Manager you can not send an incoming liaison statements, you only can post them']) - return super(IncomingLiaisonForm, self).clean() - - -def liaison_manager_sdos(person): - return Group.objects.filter(type="sdo", state="active", role__person=person, role__name="liaiman").distinct() - -class OutgoingLiaisonForm(LiaisonForm): - - to_poc = forms.CharField(label="POC", required=True) - approved = forms.BooleanField(label="Obtained prior approval", required=False) - other_organization = forms.CharField(label="Other SDO", required=True) - - def get_to_entity(self): - organization_key = self.cleaned_data.get('organization') - organization = self.hm.get_entity_by_key(organization_key) - if organization_key == 'othersdo' and self.cleaned_data.get('other_organization', None): - organization.name=self.cleaned_data['other_organization'] - return organization - - def set_from_field(self): - if is_secretariat(self.user): - self.fields['from_field'].choices = self.hm.get_all_incoming_entities() - elif is_sdo_liaison_manager(self.person): - self.fields['from_field'].choices = self.hm.get_all_incoming_entities() - all_entities = [] - for i in self.hm.get_entities_for_person(self.person): - all_entities += i[1] - if all_entities: - self.fields['from_field'].widget.full_power_on = [i[0] for i in all_entities] - self.fields['from_field'].widget.reduced_to_set = ['sdo_%s' % i.pk for i in liaison_manager_sdos(self.person)] - else: - self.fields['from_field'].choices = self.hm.get_entities_for_person(self.person) - self.fields['from_field'].widget.submitter = unicode(self.person) - self.fieldsets[0] = ('From', ('from_field', 'replyto', 'approved')) - - def set_replyto_field(self): - e = Email.objects.filter(person=self.person, role__group__state="active", role__name__in=["ad", "chair"]) - if e: - addr = e[0].address - else: - addr = self.person.email_address() - self.fields['replyto'].initial = addr - - def set_organization_field(self): - # If the user is a liaison manager and is nothing more, reduce the To field to his SDOs - if not self.hm.get_entities_for_person(self.person) and is_sdo_liaison_manager(self.person): - self.fields['organization'].choices = [('sdo_%s' % i.pk, i.name) for i in liaison_manager_sdos(self.person)] - else: - self.fields['organization'].choices = self.hm.get_all_outgoing_entities() - self.fieldsets[1] = ('To', ('organization', 'other_organization', 'to_poc')) - - def set_required_fields(self): - super(OutgoingLiaisonForm, self).set_required_fields() - organization = self.data.get('organization', None) - if organization == 'othersdo': - self.fields['other_organization'].required=True - else: - self.fields['other_organization'].required=False - - def reset_required_fields(self): - super(OutgoingLiaisonForm, self).reset_required_fields() - self.fields['other_organization'].required=True - - def get_poc(self, organization): - return self.cleaned_data['to_poc'] - - def save_extra_fields(self, liaison): - super(OutgoingLiaisonForm, self).save_extra_fields(liaison) - from_entity = self.get_from_entity() - needs_approval = from_entity.needs_approval(self.person) - if not needs_approval or self.cleaned_data.get('approved', False): - liaison.approved = datetime.datetime.now() - else: - liaison.approved = None - - def clean_to_poc(self): - value = self.cleaned_data.get('to_poc', None) - self.check_email(value) - return value - - def clean_organization(self): - to_code = self.cleaned_data.get('organization', None) - from_code = self.cleaned_data.get('from_field', None) - if not to_code or not from_code: - return to_code - all_entities = [] - person = self.fake_person or self.person - for i in self.hm.get_entities_for_person(person): - all_entities += i[1] - # If the from entity is one in wich the user has full privileges the to entity could be anyone - if from_code in [i[0] for i in all_entities]: - return to_code - sdo_codes = ['sdo_%s' % i.pk for i in liaison_manager_sdos(person)] - if to_code in sdo_codes: - return to_code - entity = self.get_to_entity() - entity_name = entity and entity.name or to_code - if self.fake_person: - raise forms.ValidationError('%s is not allowed to send a liaison to: %s' % (self.fake_person, entity_name)) - else: - raise forms.ValidationError('You are not allowed to send a liaison to: %s' % entity_name) - - -class EditLiaisonForm(LiaisonForm): - - from_field = forms.CharField(widget=forms.TextInput, label=u'From') - replyto = forms.CharField(label=u'Reply to', widget=forms.TextInput) - organization = forms.CharField(widget=forms.TextInput) - to_poc = forms.CharField(widget=forms.TextInput, label="POC", required=False) - cc1 = forms.CharField(widget=forms.TextInput, label="CC", required=False) - - class Meta: - fields = ('from_raw_body', 'to_body', 'to_poc', 'cc1', 'last_modified_date', 'title', - 'response_contact', 'technical_contact', 'purpose_text', 'body', - 'deadline_date', 'purpose', 'replyto', 'related_to') - - def __init__(self, *args, **kwargs): - super(EditLiaisonForm, self).__init__(*args, **kwargs) - self.edit = True - self.initial.update({'attachments': self.instance.uploads_set.all()}) - self.fields['submitted_date'].initial = self.instance.submitted_date - - def set_from_field(self): - self.fields['from_field'].initial = self.instance.from_body - - def set_replyto_field(self): - self.fields['replyto'].initial = self.instance.replyto - - def set_organization_field(self): - self.fields['organization'].initial = self.instance.to_body - - def save_extra_fields(self, liaison): - liaison.from_name = self.cleaned_data.get('from_field') - liaison.to_name = self.cleaned_data.get('organization') - liaison.to_contact = self.cleaned_data['to_poc'] - liaison.cc = self.cleaned_data['cc1'] - diff --git a/ietf/liaisons/mails.py b/ietf/liaisons/mails.py index db80b9d3c..3af748db5 100644 --- a/ietf/liaisons/mails.py +++ b/ietf/liaisons/mails.py @@ -8,14 +8,11 @@ from ietf.utils.mail import send_mail_text from ietf.liaisons.utils import role_persons_with_fixed_email from ietf.group.models import Role -def send_liaison_by_email(request, liaison, fake=False): - if liaison.is_pending(): # this conditional should definitely be at the caller, not here - return notify_pending_by_email(request, liaison, fake) - +def send_liaison_by_email(request, liaison): subject = u'New Liaison Statement, "%s"' % (liaison.title) from_email = settings.LIAISON_UNIVERSAL_FROM - to_email = liaison.to_poc.split(',') - cc = liaison.cc1.split(',') + to_email = liaison.to_contact.split(',') + cc = liaison.cc.split(',') if liaison.technical_contact: cc += liaison.technical_contact.split(',') if liaison.response_contact: @@ -29,7 +26,7 @@ def send_liaison_by_email(request, liaison, fake=False): send_mail_text(request, to_email, from_email, subject, body, cc=", ".join(cc), bcc=", ".join(bcc)) -def notify_pending_by_email(request, liaison, fake): +def notify_pending_by_email(request, liaison): # Broken: this does not find the list of approvers for the sending body # For now, we are sending to statements@ietf.org so the Secretariat can nudge diff --git a/ietf/liaisons/management/commands/check_liaison_deadlines.py b/ietf/liaisons/management/commands/check_liaison_deadlines.py index 7deeb4ecf..73dd585ef 100644 --- a/ietf/liaisons/management/commands/check_liaison_deadlines.py +++ b/ietf/liaisons/management/commands/check_liaison_deadlines.py @@ -5,78 +5,19 @@ from django.core.management.base import BaseCommand from django.template.loader import render_to_string from django.core.urlresolvers import reverse as urlreverse -from ietf.liaisons.models import LiaisonDetail -#from ietf.liaisons.mail import IETFEmailMessage -from ietf.utils.mail import send_mail_text - - -PREVIOUS_DAYS = { - 14: 'in two weeks', - 7: 'in one week', - 4: 'in four days', - 3: 'in three days', - 2: 'in two days', - 1: 'tomorrow', - 0: 'today'} +from ietf.liaisons.models import LiaisonStatement +from ietf.liaisons.mails import possibly_send_deadline_reminder class Command(BaseCommand): help = (u"Check liaison deadlines and send a reminder if we are close to a deadline") - def send_reminder(self, liaison, days_to_go): - if days_to_go < 0: - subject = '[Liaison OUT OF DATE] %s' % liaison.title - days_msg = 'is out of date for %s days' % (-days_to_go) - else: - subject = '[Liaison deadline %s] %s' % (PREVIOUS_DAYS[days_to_go], liaison.title) - days_msg = 'expires %s' % PREVIOUS_DAYS[days_to_go] - - from_email = settings.LIAISON_UNIVERSAL_FROM - to_email = liaison.to_poc.split(',') - cc = liaison.cc1.split(',') - if liaison.technical_contact: - cc += liaison.technical_contact.split(',') - if liaison.response_contact: - cc += liaison.response_contact.split(',') - bcc = ['statements@ietf.org'] - body = render_to_string('liaisons/liaison_deadline_mail.txt', - {'liaison': liaison, - 'days_msg': days_msg, - 'url': settings.IDTRACKER_BASE_URL + urlreverse("liaison_approval_detail", kwargs=dict(object_id=liaison.pk)), - 'referenced_url': settings.IDTRACKER_BASE_URL + urlreverse("liaison_detail", kwargs=dict(object_id=liaison.related_to.pk)) if liaison.related_to else None, - }) - send_mail_text(context=None,to=to_email,frm=from_email,cc=cc,subject=subject,bcc=bcc,txt=body) - print 'Liaison %05s#: Deadline reminder Sent!' % liaison.pk - - #mail = IETFEmailMessage(subject=subject, - # to=to_email, - # from_email=from_email, - # cc=cc, - # bcc=bcc, - # body=body) - #if not settings.DEBUG: - # mail.send() - # print 'Liaison %05s#: Deadline reminder Sent!' % liaison.pk - #else: - # print 'Liaison %05s#: Deadline reminder Not Sent because in DEBUG mode!' % liaison.pk - def handle(self, *args, **options): today = datetime.date.today() - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - from ietf.liaisons.mails import possibly_send_deadline_reminder - from ietf.liaisons.proxy import LiaisonDetailProxy as LiaisonDetail - - cutoff = today - datetime.timedelta(14) - - for l in LiaisonDetail.objects.filter(action_taken=False, deadline__gte=cutoff).exclude(deadline=None): - r = possibly_send_deadline_reminder(l) - if r: - print 'Liaison %05s#: Deadline reminder sent!' % liaison.pk - return - - query = LiaisonDetail.objects.filter(deadline_date__isnull=False, action_taken=False, deadline_date__gte=today - datetime.timedelta(14)) - for liaison in query: - delta = liaison.deadline_date - today - if delta.days < 0 or delta.days in PREVIOUS_DAYS.keys(): - self.send_reminder(liaison, delta.days) + cutoff = today - datetime.timedelta(14) + + for l in LiaisonStatement.objects.filter(action_taken=False, deadline__gte=cutoff).exclude(deadline=None): + r = possibly_send_deadline_reminder(l) + if r: + print 'Liaison %05s#: Deadline reminder sent!' % liaison.pk diff --git a/ietf/liaisons/management/commands/remind_update_sdo_list.py b/ietf/liaisons/management/commands/remind_update_sdo_list.py index 8c69093b8..fb37be74f 100644 --- a/ietf/liaisons/management/commands/remind_update_sdo_list.py +++ b/ietf/liaisons/management/commands/remind_update_sdo_list.py @@ -5,7 +5,8 @@ from django.core.mail import EmailMessage from django.core.management.base import BaseCommand from django.template.loader import render_to_string -from ietf.liaisons.models import SDOs +from ietf.group.models import Group +from ietf.liaisons.mails import send_sdo_reminder class Command(BaseCommand): @@ -16,56 +17,15 @@ class Command(BaseCommand): ) - def send_mail_to(self, person, sdo): - subject = 'Request for update list of authorized individuals' - email = person.email()[1] - name = ' '.join([i for i in (person.name_prefix, person.first_name, person.middle_initial, person.last_name, person.name_suffix) if i]) - authorized_list = [i.person for i in sdo.sdoauthorizedindividual_set.all()] - body = render_to_string('liaisons/sdo_reminder.txt', - {'manager_name': name, - 'sdo_name': sdo.sdo_name, - 'individuals': authorized_list, - }) - mail = EmailMessage(subject=subject, - to=[email], - from_email=settings.LIAISON_UNIVERSAL_FROM, - body = body) - if not settings.DEBUG: - mail.send() - msg = '%05s#: %s Mail Sent!' % (sdo.pk, sdo.sdo_name) - else: - msg = '%05s#: %s Mail Not Sent because in DEBUG mode!' % (sdo.pk, sdo.sdo_name) - return msg - def handle(self, *args, **options): sdo_pk = options.get('sdo_pk', None) return_output = options.get('return_output', False) - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - msg_list = send_reminders_to_sdos(sdo_pk=sdo_pk) - return msg_list if return_output else None - - query = SDOs.objects.all().order_by('pk') - if sdo_pk: - query = query.filter(pk=sdo_pk) - - msg_list = [] - for sdo in query: - manager = sdo.liaisonmanager() - if manager: - msg = self.send_mail_to(manager.person, sdo) - else: - msg = '%05s#: %s has no liaison manager' % (sdo.pk, sdo.sdo_name) - print msg - msg_list.append(msg) - if return_output: - return msg_list + msg_list = send_reminders_to_sdos(sdo_pk=sdo_pk) + return msg_list if return_output else None def send_reminders_to_sdos(sdo_pk=None): - from ietf.group.models import Group - from ietf.liaisons.mails import send_sdo_reminder - sdos = Group.objects.filter(type="sdo").order_by('pk') if sdo_pk: sdos = sdos.filter(pk=sdo_pk) diff --git a/ietf/liaisons/models.py b/ietf/liaisons/models.py index d1b2fe832..6f596256c 100644 --- a/ietf/liaisons/models.py +++ b/ietf/liaisons/models.py @@ -1,369 +1,52 @@ # Copyright The IETF Trust 2007, All Rights Reserved -from django.conf import settings -from django.core.exceptions import ObjectDoesNotExist from django.db import models -from django.template.loader import render_to_string -from django.contrib.auth.models import User -from django.core.urlresolvers import reverse as urlreverse -from ietf.idtracker.models import Acronym, PersonOrOrgInfo, Area, IESGLogin -#from ietf.liaisons.mail import IETFEmailMessage -from ietf.utils.mail import send_mail_text -from ietf.ietfauth.models import LegacyLiaisonUser -from ietf.utils.admin import admin_link -class LiaisonPurpose(models.Model): - purpose_id = models.AutoField(primary_key=True) - purpose_text = models.CharField(blank=True, max_length=50) - def __str__(self): - return self.purpose_text - class Meta: - db_table = 'liaison_purpose' - -class FromBodies(models.Model): - from_id = models.AutoField(primary_key=True) - body_name = models.CharField(blank=True, max_length=35) - poc = models.ForeignKey(PersonOrOrgInfo, db_column='poc', null=True) - is_liaison_manager = models.BooleanField() - other_sdo = models.BooleanField() - email_priority = models.IntegerField(null=True, blank=True) - def __str__(self): - return self.body_name - class Meta: - db_table = 'from_bodies' - verbose_name = "From body" - verbose_name_plural = "From bodies" - contact_link = admin_link('poc', label='Contact') +from ietf.name.models import LiaisonStatementPurposeName +from ietf.doc.models import Document +from ietf.person.models import Email +from ietf.group.models import Group +class LiaisonStatement(models.Model): + title = models.CharField(blank=True, max_length=255) + purpose = models.ForeignKey(LiaisonStatementPurposeName) + body = models.TextField(blank=True) + deadline = models.DateField(null=True, blank=True) + related_to = models.ForeignKey('LiaisonStatement', blank=True, null=True) -class OutgoingLiaisonApproval(models.Model): - approved = models.BooleanField(default=True) - approval_date = models.DateField(null=True, blank=True) + from_group = models.ForeignKey(Group, related_name="liaisonstatement_from_set", null=True, blank=True, help_text="Sender group, if it exists") + from_name = models.CharField(max_length=255, help_text="Name of the sender body") + from_contact = models.ForeignKey(Email, blank=True, null=True) + to_group = models.ForeignKey(Group, related_name="liaisonstatement_to_set", null=True, blank=True, help_text="Recipient group, if it exists") + to_name = models.CharField(max_length=255, help_text="Name of the recipient body") + to_contact = models.CharField(blank=True, max_length=255, help_text="Contacts at recipient body") + reply_to = models.CharField(blank=True, max_length=255) -class LiaisonDetail(models.Model): - detail_id = models.AutoField(primary_key=True) - person = models.ForeignKey(PersonOrOrgInfo, null=True, db_column='person_or_org_tag') - submitted_date = models.DateField(null=True, blank=True) - last_modified_date = models.DateField(null=True, blank=True) - from_id = models.IntegerField(null=True, blank=True) - to_body = models.CharField(blank=True, null=True, max_length=255) - title = models.CharField(blank=True, null=True, max_length=255) - response_contact = models.CharField(blank=True, null=True, max_length=255) - technical_contact = models.CharField(blank=True, null=True, max_length=255) - purpose_text = models.TextField(blank=True, null=True, db_column='purpose') - body = models.TextField(blank=True,null=True) - deadline_date = models.DateField(null=True, blank=True) - cc1 = models.TextField(blank=True, null=True) - # unclear why cc2 is a CharField, but it's always - # either NULL or blank. - cc2 = models.CharField(blank=True, null=True, max_length=50) - submitter_name = models.CharField(blank=True, null=True, max_length=255) - submitter_email = models.CharField(blank=True, null=True, max_length=255) - by_secretariat = models.IntegerField(null=True, blank=True) - to_poc = models.CharField(blank=True, null=True, max_length=255) - to_email = models.CharField(blank=True, null=True, max_length=255) - purpose = models.ForeignKey(LiaisonPurpose,null=True) - replyto = models.CharField(blank=True, null=True, max_length=255) - from_raw_body = models.CharField(blank=True, null=True, max_length=255) - from_raw_code = models.CharField(blank=True, null=True, max_length=255) - to_raw_code = models.CharField(blank=True, null=True, max_length=255) - approval = models.ForeignKey(OutgoingLiaisonApproval, blank=True, null=True) - action_taken = models.BooleanField(default=False, db_column='taken_care') - related_to = models.ForeignKey('LiaisonDetail', blank=True, null=True) - def __str__(self): - return self.title or "" - def __unicode__(self): - return self.title or "" - def from_body(self): - """The from_raw_body stores the name of the entity - sending the liaison. - For legacy liaisons (the ones with empty from_raw_body) - the legacy_from_body() is returned.""" - if not self.from_raw_body: - return self.legacy_from_body() - return self.from_raw_body - def from_sdo(self): - try: - name = FromBodies.objects.get(pk=self.from_id).body_name - sdo = SDOs.objects.get(sdo_name=name) - return sdo - except ObjectDoesNotExist: - return None - def legacy_from_body(self): - """The from_id field is a foreign key for either - FromBodies or Acronyms, depending on whether it's - the IETF or not. There is no flag field saying - which, so we just try it. If the index values - overlap, then this function will be ambiguous - and will return the value from FromBodies. Current - acronym IDs start at 925 so the day of reckoning - is not nigh.""" - try: - from_body = FromBodies.objects.get(pk=self.from_id) - return from_body.body_name - except ObjectDoesNotExist: - pass - try: - acronym = Acronym.objects.get(pk=self.from_id) - try: - x = acronym.area - kind = "AREA" - except Area.DoesNotExist: - kind = "WG" - return "IETF %s %s" % (acronym.acronym.upper(), kind) - except ObjectDoesNotExist: - pass - return "" % self.from_id - def from_email(self): - """If there is an entry in from_bodies, it has - the desired email priority. However, if it's from - an IETF WG, there is no entry in from_bodies, so - default to 1.""" - try: - from_body = FromBodies.objects.get(pk=self.from_id) - email_priority = from_body.email_priority - except FromBodies.DoesNotExist: - email_priority = 1 - return self.person.emailaddress_set.all().get(priority=email_priority) - def get_absolute_url(self): - return '/liaison/%d/' % self.detail_id - class Meta: - db_table = 'liaison_detail' + response_contact = models.CharField(blank=True, max_length=255) + technical_contact = models.CharField(blank=True, max_length=255) + cc = models.TextField(blank=True) - def notify_pending_by_email(self, fake): - from ietf.liaisons.utils import IETFHM + submitted = models.DateTimeField(null=True, blank=True) + modified = models.DateTimeField(null=True, blank=True) + approved = models.DateTimeField(null=True, blank=True) - from_entity = IETFHM.get_entity_by_key(self.from_raw_code) - if not from_entity: - return None - to_email = [] - for person in from_entity.can_approve(): - to_email.append('%s <%s>' % person.email()) - subject = 'New Liaison Statement, "%s" needs your approval' % (self.title) - from_email = settings.LIAISON_UNIVERSAL_FROM - body = render_to_string('liaisons/pending_liaison_mail.txt', { - 'liaison': self, - 'url': settings.IDTRACKER_BASE_URL + urlreverse("liaison_approval_detail", kwargs=dict(object_id=self.pk)), - 'referenced_url': settings.IDTRACKER_BASE_URL + urlreverse("liaison_detail", kwargs=dict(object_id=self.related_to.pk)) if self.related_to else None, - }) - send_mail_text(context=None, to=to_email, frm=from_email, subject=subject, txt = body) - #mail = IETFEmailMessage(subject=subject, - # to=to_email, - # from_email=from_email, - # body = body) - #if not fake: - # mail.send() - #return mail + action_taken = models.BooleanField(default=False) - def send_by_email(self, fake=False): - if self.is_pending(): - return self.notify_pending_by_email(fake) - subject = 'New Liaison Statement, "%s"' % (self.title) - from_email = settings.LIAISON_UNIVERSAL_FROM - to_email = self.to_poc.split(',') - cc = self.cc1.split(',') - if self.technical_contact: - cc += self.technical_contact.split(',') - if self.response_contact: - cc += self.response_contact.split(',') - bcc = ['statements@ietf.org'] - body = render_to_string('liaisons/liaison_mail.txt', { - 'liaison': self, - 'url': settings.IDTRACKER_BASE_URL + urlreverse("liaison_detail", kwargs=dict(object_id=self.pk)), - 'referenced_url': settings.IDTRACKER_BASE_URL + urlreverse("liaison_detail", kwargs=dict(object_id=self.related_to.pk)) if self.related_to else None, - }) - send_mail_text(context=None,to=to_email,frm=from_email,subject=subject,txt=body,cc=cc,bcc=bcc) - #mail = IETFEmailMessage(subject=subject, - # to=to_email, - # from_email=from_email, - # cc = cc, - # bcc = bcc, - # body = body) - #if not fake: - # mail.send() - #return mail + attachments = models.ManyToManyField(Document, blank=True) - def is_pending(self): - return bool(self.approval and not self.approval.approved) - - -class SDOs(models.Model): - sdo_id = models.AutoField(primary_key=True, verbose_name='ID') - sdo_name = models.CharField(blank=True, max_length=255, verbose_name='SDO Name') - def __str__(self): - return self.sdo_name - def liaisonmanager(self): - try: - return self.liaisonmanagers_set.all()[0] - except: - return None - def sdo_contact(self): - try: - return self.sdoauthorizedindividual_set.all()[0] - except: - return None - class Meta: - verbose_name = 'SDO' - verbose_name_plural = 'SDOs' - db_table = 'sdos' - ordering = ('sdo_name', ) - liaisonmanager_link = admin_link('liaisonmanager', label='Liaison') - sdo_contact_link = admin_link('sdo_contact') - -class LiaisonStatementManager(models.Model): - person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag') - sdo = models.ForeignKey(SDOs, verbose_name='SDO') - def __unicode__(self): - return '%s (%s)' % (self.person, self.sdo) - class Meta: - abstract = True - # Helper functions, for use in the admin interface - def login_name(self): - login_name = None - try: - login_name = IESGLogin.objects.get(person=self.person).login_name - if User.objects.filter(username=login_name).count(): - return login_name - except IESGLogin.DoesNotExist: - pass - try: - login_name = LegacyLiaisonUser.objects.get(person=self.person).login_name - except LegacyLiaisonUser.DoesNotExist: - pass - return login_name - def user(self): - login_name = self.login_name() - user = None - if login_name: - try: - return User.objects.get(username=login_name), login_name - except User.DoesNotExist: - pass - return None, login_name - def user_name(self): - user, login_name = self.user() - if user: - return u'%s' % (user.id, login_name) + def name(self): + from django.template.defaultfilters import slugify + if self.from_group: + frm = self.from_group.acronym or self.from_group.name else: - if login_name: - return u'Add login: %s' % (login_name, login_name) - else: - return u'Add liaison user: %s' % (self.person.pk, self.person.email()[1], self.person, ) - - user_name.allow_tags = True - def groups(self): - user, login_name = self.user() - return ", ".join([ group.name for group in user.groups.all()]) - person_link = admin_link('person') - sdo_link = admin_link('sdo', label='SDO') - -class LiaisonManagers(LiaisonStatementManager): - email_priority = models.IntegerField(null=True, blank=True) - def email(self): - try: - return self.person.emailaddress_set.get(priority=self.email_priority) - except ObjectDoesNotExist: - return None - class Meta: - verbose_name = 'SDO Liaison Manager' - verbose_name_plural = 'SDO Liaison Managers' - db_table = 'liaison_managers' - ordering = ('sdo__sdo_name', ) + frm = self.from_name + if self.to_group: + to = self.to_group.acronym or self.to_group.name + else: + to = self.to_name + return slugify("liaison" + " " + self.submitted.strftime("%Y-%m-%d") + " " + frm[:50] + " " + to[:50] + " " + self.title[:115]) -class SDOAuthorizedIndividual(LiaisonStatementManager): - class Meta: - verbose_name = 'SDO Authorized Individual' - verbose_name_plural = 'SDO Authorized Individuals' - -# This table is not used by any code right now. -#class LiaisonsInterim(models.Model): -# title = models.CharField(blank=True, max_length=255) -# submitter_name = models.CharField(blank=True, max_length=255) -# submitter_email = models.CharField(blank=True, max_length=255) -# submitted_date = models.DateField(null=True, blank=True) -# from_id = models.IntegerField(null=True, blank=True) -# def __str__(self): -# return self.title -# class Meta: -# db_table = 'liaisons_interim' - -class Uploads(models.Model): - file_id = models.AutoField(primary_key=True) - file_title = models.CharField(blank=True, max_length=255) - person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag') - file_extension = models.CharField(blank=True, max_length=10) - detail = models.ForeignKey(LiaisonDetail) - def __str__(self): - return self.file_title - def filename(self): - return "file%s%s" % (self.file_id, self.file_extension) - class Meta: - db_table = 'uploads' - -# empty table -#class SdoChairs(models.Model): -# sdo = models.ForeignKey(SDOs) -# person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag') -# email_priority = models.IntegerField(null=True, blank=True) -# class Meta: -# db_table = 'sdo_chairs' - -# changes done by convert-096.py:changed maxlength to max_length -# removed core -# removed edit_inline -# removed num_in_admin -# removed raw_id_admin - -if settings.USE_DB_REDESIGN_PROXY_CLASSES or hasattr(settings, "IMPORTING_FROM_OLD_SCHEMA"): - from ietf.name.models import LiaisonStatementPurposeName - from ietf.doc.models import Document - from ietf.person.models import Email - from ietf.group.models import Group - - class LiaisonStatement(models.Model): - title = models.CharField(blank=True, max_length=255) - purpose = models.ForeignKey(LiaisonStatementPurposeName) - body = models.TextField(blank=True) - deadline = models.DateField(null=True, blank=True) - - related_to = models.ForeignKey('LiaisonStatement', blank=True, null=True) - - from_group = models.ForeignKey(Group, related_name="liaisonstatement_from_set", null=True, blank=True, help_text="Sender group, if it exists") - from_name = models.CharField(max_length=255, help_text="Name of the sender body") - from_contact = models.ForeignKey(Email, blank=True, null=True) - to_group = models.ForeignKey(Group, related_name="liaisonstatement_to_set", null=True, blank=True, help_text="Recipient group, if it exists") - to_name = models.CharField(max_length=255, help_text="Name of the recipient body") - to_contact = models.CharField(blank=True, max_length=255, help_text="Contacts at recipient body") - - reply_to = models.CharField(blank=True, max_length=255) - - response_contact = models.CharField(blank=True, max_length=255) - technical_contact = models.CharField(blank=True, max_length=255) - cc = models.TextField(blank=True) - - submitted = models.DateTimeField(null=True, blank=True) - modified = models.DateTimeField(null=True, blank=True) - approved = models.DateTimeField(null=True, blank=True) - - action_taken = models.BooleanField(default=False) - - attachments = models.ManyToManyField(Document, blank=True) - - def name(self): - from django.template.defaultfilters import slugify - if self.from_group: - frm = self.from_group.acronym or self.from_group.name - else: - frm = self.from_name - if self.to_group: - to = self.to_group.acronym or self.to_group.name - else: - to = self.to_name - return slugify("liaison" + " " + self.submitted.strftime("%Y-%m-%d") + " " + frm[:50] + " " + to[:50] + " " + self.title[:115]) - - def __unicode__(self): - return self.title or "" - - LiaisonDetailOld = LiaisonDetail + def __unicode__(self): + return self.title or u"" diff --git a/ietf/liaisons/proxy.py b/ietf/liaisons/proxy.py deleted file mode 100644 index 9e1ca61bc..000000000 --- a/ietf/liaisons/proxy.py +++ /dev/null @@ -1,188 +0,0 @@ -from ietf.utils.proxy import TranslatingManager -from ietf.liaisons.models import LiaisonStatement -from ietf.doc.models import Document - -class LiaisonDetailProxy(LiaisonStatement): - objects = TranslatingManager(dict(submitted_date="submitted", - deadline_date="deadline", - to_body="to_name", - from_raw_body="from_name")) - - def from_object(self, base): - for f in base._meta.fields: - setattr(self, f.name, getattr(base, f.name)) - return self - - #detail_id = models.AutoField(primary_key=True) - @property - def detail_id(self): - return self.id - #person = models.ForeignKey(PersonOrOrgInfo, null=True, db_column='person_or_org_tag') - @property - def person(self): - return self.from_contact.person if self.from_contact else "" - #submitted_date = models.DateField(null=True, blank=True) - @property - def submitted_date(self): - return self.submitted.date() if self.submitted else None - #last_modified_date = models.DateField(null=True, blank=True) - @property - def last_modified_date(self): - return self.modified.date() if self.modified else None - #from_id = models.IntegerField(null=True, blank=True) - @property - def from_id(self): - return self.from_group_id - #to_body = models.CharField(blank=True, null=True, max_length=255) - @property - def to_body(self): - return self.to_name - #title = models.CharField(blank=True, null=True, max_length=255) # same name - #response_contact = models.CharField(blank=True, null=True, max_length=255) # same name - #technical_contact = models.CharField(blank=True, null=True, max_length=255) # same name - #purpose_text = models.TextField(blank=True, null=True, db_column='purpose') - @property - def purpose_text(self): - return "" - #body = models.TextField(blank=True,null=True) # same name - #deadline_date = models.DateField(null=True, blank=True) - @property - def deadline_date(self): - return self.deadline - #cc1 = models.TextField(blank=True, null=True) - @property - def cc1(self): - return self.cc - #cc2 = models.CharField(blank=True, null=True, max_length=50) # unused - @property - def cc2(self): - return "" - #submitter_name = models.CharField(blank=True, null=True, max_length=255) - @property - def submitter_name(self): - i = self.to_name.find('<') - if i > 0: - return self.to_name[:i - 1] - else: - return self.to_name - #submitter_email = models.CharField(blank=True, null=True, max_length=255) - @property - def submitter_email(self): - import re - re_email = re.compile("<(.*)>") - match = re_email.search(self.to_name) - if match: - return match.group(1) - else: - return "" - #by_secretariat = models.IntegerField(null=True, blank=True) - @property - def by_secretariat(self): - return not self.from_contact - #to_poc = models.CharField(blank=True, null=True, max_length=255) - @property - def to_poc(self): - return self.to_contact - #to_email = models.CharField(blank=True, null=True, max_length=255) - @property - def to_email(self): - return "" - #purpose = models.ForeignKey(LiaisonPurpose,null=True) - #replyto = models.CharField(blank=True, null=True, max_length=255) - @property - def replyto(self): - return self.reply_to - #from_raw_body = models.CharField(blank=True, null=True, max_length=255) - @property - def from_raw_body(self): - return self.from_name - - def raw_codify(self, group): - if not group: - return "" - if group.type_id in ("sdo", "wg", "area"): - return "%s_%s" % (group.type_id, group.id) - return group.acronym - - #from_raw_code = models.CharField(blank=True, null=True, max_length=255) - @property - def from_raw_code(self): - return self.raw_codify(self.from_group) - #to_raw_code = models.CharField(blank=True, null=True, max_length=255) - @property - def to_raw_code(self): - return self.raw_codify(self.to_group) - #approval = models.ForeignKey(OutgoingLiaisonApproval, blank=True, null=True) - @property - def approval(self): - return bool(self.approved) - #action_taken = models.BooleanField(default=False, db_column='taken_care') # same name - #related_to = models.ForeignKey('LiaisonDetail', blank=True, null=True) # same name - - @property - def uploads_set(self): - return UploadsProxy.objects.filter(liaisonstatement=self).order_by("name", "external_url") - - @property - def liaisondetail_set(self): - return self.liaisonstatement_set - - def __str__(self): - return unicode(self) - def __unicode__(self): - return self.title or "" - def from_body(self): - return self.from_name - def from_sdo(self): - return self.from_group if self.from_group and self.from_group.type_id == "sdo" else None - def from_email(self): - return self.from_contact.address - def get_absolute_url(self): - return '/liaison/%d/' % self.detail_id - class Meta: - proxy = True - - def send_by_email(self, fake=False): - # grab this from module instead of stuffing in on the model - from ietf.liaisons.mails import send_liaison_by_email - # we don't have a request so just pass None for the time being - return send_liaison_by_email(None, self, fake) - - def notify_pending_by_email(self, fake=False): - # grab this from module instead of stuffing in on the model - from ietf.liaisons.mails import notify_pending_by_email - # we don't have a request so just pass None for the time being - return notify_pending_by_email(None, self, fake) - - def is_pending(self): - return not self.approved - -class UploadsProxy(Document): - #file_id = models.AutoField(primary_key=True) - @property - def file_id(self): - if not self.external_url or self.external_url.startswith(self.name): - return self.name # new data - else: - return int(self.external_url.split(".")[0][len("file"):]) # old data - #file_title = models.CharField(blank=True, max_length=255) - @property - def file_title(self): - return self.title - #person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag') - #file_extension = models.CharField(blank=True, max_length=10) - @property - def file_extension(self): - t = self.external_url.split(".") - if len(t) > 1: - return "." + t[1] - else: - return "" - #detail = models.ForeignKey(LiaisonDetail) - @property - def detail(self): - return self.liaisonstatement_set.all()[0] - def filename(self): - return self.external_url - class Meta: - proxy = True diff --git a/ietf/liaisons/sitemaps.py b/ietf/liaisons/sitemaps.py index 156ffed4c..161fed1c3 100644 --- a/ietf/liaisons/sitemaps.py +++ b/ietf/liaisons/sitemaps.py @@ -2,16 +2,17 @@ # from django.contrib.sitemaps import Sitemap from django.conf import settings -from ietf.liaisons.models import LiaisonDetail -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - from ietf.liaisons.proxy import LiaisonDetailProxy as LiaisonDetail +from ietf.liaisons.models import LiaisonStatement class LiaisonMap(Sitemap): changefreq = "never" + def items(self): - return LiaisonDetail.objects.all() + return LiaisonStatement.objects.all() + def location(self, obj): - return "/liaison/%d/" % obj.detail_id + return "/liaison/%s/" % obj.pk + def lastmod(self, obj): - return obj.last_modified_date + return obj.modified diff --git a/ietf/liaisons/tests.py b/ietf/liaisons/tests.py index c5d3c9f91..e938ca373 100644 --- a/ietf/liaisons/tests.py +++ b/ietf/liaisons/tests.py @@ -6,27 +6,15 @@ from django.core.urlresolvers import reverse as urlreverse from StringIO import StringIO from pyquery import PyQuery -from ietf.utils.test_utils import SimpleUrlTestCase, canonicalize_feed, canonicalize_sitemap, login_testing_unauthorized +from ietf.utils.test_utils import TestCase, login_testing_unauthorized from ietf.utils.test_data import make_test_data from ietf.utils.mail import outbox -from ietf.utils import TestCase -class LiaisonsUrlTestCase(SimpleUrlTestCase): - def testUrls(self): - self.doTestUrls(__file__) - def doCanonicalize(self, url, content): - if url.startswith("/feed/"): - return canonicalize_feed(content) - elif url == "/sitemap-liaison.xml": - return canonicalize_sitemap(content) - else: - return content +from ietf.liaisons.models import LiaisonStatement, LiaisonStatementPurposeName +from ietf.person.models import Person, Email +from ietf.group.models import Group, Role +from ietf.liaisons.mails import send_sdo_reminder, possibly_send_deadline_reminder -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - from ietf.liaisons.models import LiaisonStatement, LiaisonStatementPurposeName - from ietf.person.models import Person, Email - from ietf.group.models import Group, Role - def make_liaison_models(): sdo = Group.objects.create( name="United League of Marsmen", @@ -89,12 +77,60 @@ def make_liaison_models(): action_taken=False, ) return l - -class LiaisonManagementTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] +class LiaisonTests(TestCase): + def test_overview(self): + make_test_data() + liaison = make_liaison_models() + r = self.client.get(urlreverse('liaison_list')) + self.assertEqual(r.status_code, 200) + self.assertTrue(liaison.title in r.content) + + def test_details(self): + make_test_data() + liaison = make_liaison_models() + + r = self.client.get(urlreverse("liaison_detail", kwargs={ 'object_id': liaison.pk })) + self.assertEqual(r.status_code, 200) + self.assertTrue(liaison.title in r.content) + + def test_feeds(self): + make_test_data() + liaison = make_liaison_models() + + r = self.client.get('/feed/liaison/recent/') + self.assertEqual(r.status_code, 200) + self.assertTrue(liaison.title in r.content) + + r = self.client.get('/feed/liaison/from/%s/' % liaison.from_group.acronym) + self.assertEqual(r.status_code, 200) + self.assertTrue(liaison.title in r.content) + + r = self.client.get('/feed/liaison/to/%s/' % liaison.to_name) + self.assertEqual(r.status_code, 200) + self.assertTrue(liaison.title in r.content) + + r = self.client.get('/feed/liaison/subject/marsmen/') + self.assertEqual(r.status_code, 200) + self.assertTrue(liaison.title in r.content) + + def test_sitemap(self): + make_test_data() + liaison = make_liaison_models() + + r = self.client.get('/sitemap-liaison.xml') + self.assertEqual(r.status_code, 200) + self.assertTrue(urlreverse("liaison_detail", kwargs={ 'object_id': liaison.pk }) in r.content) + + def test_help_pages(self): + self.assertEqual(self.client.get('/liaison/help/').status_code, 200) + self.assertEqual(self.client.get('/liaison/help/fields/').status_code, 200) + self.assertEqual(self.client.get('/liaison/help/from_ietf/').status_code, 200) + self.assertEqual(self.client.get('/liaison/help/to_ietf/').status_code, 200) + + +class LiaisonManagementTests(TestCase): def setUp(self): self.liaison_dir = os.path.abspath("tmp-liaison-dir") try: @@ -117,52 +153,63 @@ class LiaisonManagementTestCase(TestCase): url = urlreverse('liaison_detail', kwargs=dict(object_id=liaison.pk)) # normal get r = self.client.get(url) - self.assertEquals(r.status_code, 200) + self.assertEqual(r.status_code, 200) q = PyQuery(r.content) - self.assertEquals(len(q('form input[name=do_action_taken]')), 0) + self.assertEqual(len(q('form input[name=do_action_taken]')), 0) # log in and get self.client.login(remote_user="secretary") r = self.client.get(url) - self.assertEquals(r.status_code, 200) + self.assertEqual(r.status_code, 200) q = PyQuery(r.content) - self.assertEquals(len(q('form input[name=do_action_taken]')), 1) + self.assertEqual(len(q('form input[name=do_action_taken]')), 1) # mark action taken r = self.client.post(url, dict(do_action_taken="1")) - self.assertEquals(r.status_code, 200) + self.assertEqual(r.status_code, 200) q = PyQuery(r.content) - self.assertEquals(len(q('form input[name=do_action_taken]')), 0) + self.assertEqual(len(q('form input[name=do_action_taken]')), 0) liaison = LiaisonStatement.objects.get(id=liaison.id) self.assertTrue(liaison.action_taken) - def test_approval(self): + def test_approval_process(self): make_test_data() liaison = make_liaison_models() # has to come from WG to need approval liaison.from_group = Group.objects.get(acronym="mars") liaison.approved = None liaison.save() - - url = urlreverse('liaison_approval_detail', kwargs=dict(object_id=liaison.pk)) + + # check the overview page + url = urlreverse('liaison_approval_list') # this liaison is for a WG so we need the AD for the area login_testing_unauthorized(self, "ad", url) + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + self.assertTrue(liaison.title in r.content) + + # check detail page + url = urlreverse('liaison_approval_detail', kwargs=dict(object_id=liaison.pk)) + self.client.logout() + login_testing_unauthorized(self, "ad", url) + # normal get r = self.client.get(url) - self.assertEquals(r.status_code, 200) + self.assertEqual(r.status_code, 200) + self.assertTrue(liaison.title in r.content) q = PyQuery(r.content) - self.assertEquals(len(q('form input[name=do_approval]')), 1) + self.assertEqual(len(q('form input[name=do_approval]')), 1) # approve mailbox_before = len(outbox) r = self.client.post(url, dict(do_approval="1")) - self.assertEquals(r.status_code, 302) + self.assertEqual(r.status_code, 302) liaison = LiaisonStatement.objects.get(id=liaison.id) self.assertTrue(liaison.approved) - self.assertEquals(len(outbox), mailbox_before + 1) + self.assertEqual(len(outbox), mailbox_before + 1) self.assertTrue("Liaison Statement" in outbox[-1]["Subject"]) def test_edit_liaison(self): @@ -174,9 +221,9 @@ class LiaisonManagementTestCase(TestCase): # get r = self.client.get(url) - self.assertEquals(r.status_code, 200) + self.assertEqual(r.status_code, 200) q = PyQuery(r.content) - self.assertEquals(len(q('form input[name=from_field]')), 1) + self.assertEqual(len(q('form input[name=from_field]')), 1) # edit attachments_before = liaison.attachments.count() @@ -198,30 +245,30 @@ class LiaisonManagementTestCase(TestCase): attach_file_1=test_file, attach_title_1="attachment", )) - self.assertEquals(r.status_code, 302) + self.assertEqual(r.status_code, 302) new_liaison = LiaisonStatement.objects.get(id=liaison.id) - self.assertEquals(new_liaison.from_name, "from") - self.assertEquals(new_liaison.reply_to, "replyto@example.com") - self.assertEquals(new_liaison.to_name, "org") - self.assertEquals(new_liaison.to_contact, "to_poc@example.com") - self.assertEquals(new_liaison.response_contact, "responce_contact@example.com") - self.assertEquals(new_liaison.technical_contact, "technical_contact@example.com") - self.assertEquals(new_liaison.cc, "cc@example.com") - self.assertEquals(new_liaison.purpose, LiaisonStatementPurposeName.objects.get(order=4)) - self.assertEquals(new_liaison.deadline, liaison.deadline + datetime.timedelta(days=1)), - self.assertEquals(new_liaison.title, "title") - self.assertEquals(new_liaison.submitted.date(), (liaison.submitted + datetime.timedelta(days=1)).date()) - self.assertEquals(new_liaison.body, "body") + self.assertEqual(new_liaison.from_name, "from") + self.assertEqual(new_liaison.reply_to, "replyto@example.com") + self.assertEqual(new_liaison.to_name, "org") + self.assertEqual(new_liaison.to_contact, "to_poc@example.com") + self.assertEqual(new_liaison.response_contact, "responce_contact@example.com") + self.assertEqual(new_liaison.technical_contact, "technical_contact@example.com") + self.assertEqual(new_liaison.cc, "cc@example.com") + self.assertEqual(new_liaison.purpose, LiaisonStatementPurposeName.objects.get(order=4)) + self.assertEqual(new_liaison.deadline, liaison.deadline + datetime.timedelta(days=1)), + self.assertEqual(new_liaison.title, "title") + self.assertEqual(new_liaison.submitted.date(), (liaison.submitted + datetime.timedelta(days=1)).date()) + self.assertEqual(new_liaison.body, "body") - self.assertEquals(new_liaison.attachments.count(), attachments_before + 1) + self.assertEqual(new_liaison.attachments.count(), attachments_before + 1) attachment = new_liaison.attachments.order_by("-name")[0] - self.assertEquals(attachment.title, "attachment") + self.assertEqual(attachment.title, "attachment") with open(os.path.join(self.liaison_dir, attachment.external_url)) as f: written_content = f.read() test_file.seek(0) - self.assertEquals(written_content, test_file.read()) + self.assertEqual(written_content, test_file.read()) def test_add_incoming_liaison(self): make_test_data() @@ -232,9 +279,9 @@ class LiaisonManagementTestCase(TestCase): # get r = self.client.get(url) - self.assertEquals(r.status_code, 200) + self.assertEqual(r.status_code, 200) q = PyQuery(r.content) - self.assertEquals(len(q('form textarea[name=body]')), 1) + self.assertEqual(len(q('form textarea[name=body]')), 1) # add new mailbox_before = len(outbox) @@ -263,34 +310,34 @@ class LiaisonManagementTestCase(TestCase): attach_title_1="attachment", send="1", )) - self.assertEquals(r.status_code, 302) + self.assertEqual(r.status_code, 302) l = LiaisonStatement.objects.all().order_by("-id")[0] - self.assertEquals(l.from_group, from_group) - self.assertEquals(l.from_contact.address, submitter.email_address()) - self.assertEquals(l.reply_to, "replyto@example.com") - self.assertEquals(l.to_group, to_group) - self.assertEquals(l.response_contact, "responce_contact@example.com") - self.assertEquals(l.technical_contact, "technical_contact@example.com") - self.assertEquals(l.cc, "cc@example.com") - self.assertEquals(l.purpose, LiaisonStatementPurposeName.objects.get(order=4)) - self.assertEquals(l.deadline, today + datetime.timedelta(days=1)), - self.assertEquals(l.related_to, liaison), - self.assertEquals(l.title, "title") - self.assertEquals(l.submitted.date(), today) - self.assertEquals(l.body, "body") + self.assertEqual(l.from_group, from_group) + self.assertEqual(l.from_contact.address, submitter.email_address()) + self.assertEqual(l.reply_to, "replyto@example.com") + self.assertEqual(l.to_group, to_group) + self.assertEqual(l.response_contact, "responce_contact@example.com") + self.assertEqual(l.technical_contact, "technical_contact@example.com") + self.assertEqual(l.cc, "cc@example.com") + self.assertEqual(l.purpose, LiaisonStatementPurposeName.objects.get(order=4)) + self.assertEqual(l.deadline, today + datetime.timedelta(days=1)), + self.assertEqual(l.related_to, liaison), + self.assertEqual(l.title, "title") + self.assertEqual(l.submitted.date(), today) + self.assertEqual(l.body, "body") self.assertTrue(l.approved) - self.assertEquals(l.attachments.count(), 1) + self.assertEqual(l.attachments.count(), 1) attachment = l.attachments.all()[0] - self.assertEquals(attachment.title, "attachment") + self.assertEqual(attachment.title, "attachment") with open(os.path.join(self.liaison_dir, attachment.external_url)) as f: written_content = f.read() test_file.seek(0) - self.assertEquals(written_content, test_file.read()) + self.assertEqual(written_content, test_file.read()) - self.assertEquals(len(outbox), mailbox_before + 1) + self.assertEqual(len(outbox), mailbox_before + 1) self.assertTrue("Liaison Statement" in outbox[-1]["Subject"]) def test_add_outgoing_liaison(self): @@ -302,9 +349,9 @@ class LiaisonManagementTestCase(TestCase): # get r = self.client.get(url) - self.assertEquals(r.status_code, 200) + self.assertEqual(r.status_code, 200) q = PyQuery(r.content) - self.assertEquals(len(q('form textarea[name=body]')), 1) + self.assertEqual(len(q('form textarea[name=body]')), 1) # add new mailbox_before = len(outbox) @@ -336,35 +383,35 @@ class LiaisonManagementTestCase(TestCase): attach_title_1="attachment", send="1", )) - self.assertEquals(r.status_code, 302) + self.assertEqual(r.status_code, 302) l = LiaisonStatement.objects.all().order_by("-id")[0] - self.assertEquals(l.from_group, from_group) - self.assertEquals(l.from_contact.address, submitter.email_address()) - self.assertEquals(l.reply_to, "replyto@example.com") - self.assertEquals(l.to_group, to_group) - self.assertEquals(l.to_contact, "to_poc@example.com") - self.assertEquals(l.response_contact, "responce_contact@example.com") - self.assertEquals(l.technical_contact, "technical_contact@example.com") - self.assertEquals(l.cc, "cc@example.com") - self.assertEquals(l.purpose, LiaisonStatementPurposeName.objects.get(order=4)) - self.assertEquals(l.deadline, today + datetime.timedelta(days=1)), - self.assertEquals(l.related_to, liaison), - self.assertEquals(l.title, "title") - self.assertEquals(l.submitted.date(), today) - self.assertEquals(l.body, "body") + self.assertEqual(l.from_group, from_group) + self.assertEqual(l.from_contact.address, submitter.email_address()) + self.assertEqual(l.reply_to, "replyto@example.com") + self.assertEqual(l.to_group, to_group) + self.assertEqual(l.to_contact, "to_poc@example.com") + self.assertEqual(l.response_contact, "responce_contact@example.com") + self.assertEqual(l.technical_contact, "technical_contact@example.com") + self.assertEqual(l.cc, "cc@example.com") + self.assertEqual(l.purpose, LiaisonStatementPurposeName.objects.get(order=4)) + self.assertEqual(l.deadline, today + datetime.timedelta(days=1)), + self.assertEqual(l.related_to, liaison), + self.assertEqual(l.title, "title") + self.assertEqual(l.submitted.date(), today) + self.assertEqual(l.body, "body") self.assertTrue(not l.approved) - self.assertEquals(l.attachments.count(), 1) + self.assertEqual(l.attachments.count(), 1) attachment = l.attachments.all()[0] - self.assertEquals(attachment.title, "attachment") + self.assertEqual(attachment.title, "attachment") with open(os.path.join(self.liaison_dir, attachment.external_url)) as f: written_content = f.read() test_file.seek(0) - self.assertEquals(written_content, test_file.read()) + self.assertEqual(written_content, test_file.read()) - self.assertEquals(len(outbox), mailbox_before + 1) + self.assertEqual(len(outbox), mailbox_before + 1) self.assertTrue("Liaison Statement" in outbox[-1]["Subject"]) # try adding statement to non-predefined organization @@ -386,46 +433,34 @@ class LiaisonManagementTestCase(TestCase): submitted_date=today.strftime("%Y-%m-%d"), body="body", )) - self.assertEquals(r.status_code, 302) + self.assertEqual(r.status_code, 302) l = LiaisonStatement.objects.all().order_by("-id")[0] - self.assertEquals(l.to_group, None) - self.assertEquals(l.to_name, "Mars Institute") + self.assertEqual(l.to_group, None) + self.assertEqual(l.to_name, "Mars Institute") def test_send_sdo_reminder(self): make_test_data() liaison = make_liaison_models() - from ietf.liaisons.mails import send_sdo_reminder - mailbox_before = len(outbox) send_sdo_reminder(Group.objects.filter(type="sdo")[0]) - self.assertEquals(len(outbox), mailbox_before + 1) + self.assertEqual(len(outbox), mailbox_before + 1) self.assertTrue("authorized individuals" in outbox[-1]["Subject"]) def test_send_liaison_deadline_reminder(self): make_test_data() liaison = make_liaison_models() - from ietf.liaisons.mails import possibly_send_deadline_reminder - from ietf.liaisons.proxy import LiaisonDetailProxy as LiaisonDetail - - l = LiaisonDetail.objects.all()[0] - mailbox_before = len(outbox) - possibly_send_deadline_reminder(l) - self.assertEquals(len(outbox), mailbox_before + 1) + possibly_send_deadline_reminder(liaison) + self.assertEqual(len(outbox), mailbox_before + 1) self.assertTrue("deadline" in outbox[-1]["Subject"]) # try pushing the deadline - l.deadline = l.deadline + datetime.timedelta(days=30) - l.save() + liaison.deadline = liaison.deadline + datetime.timedelta(days=30) + liaison.save() mailbox_before = len(outbox) - possibly_send_deadline_reminder(l) - self.assertEquals(len(outbox), mailbox_before) - - -if not settings.USE_DB_REDESIGN_PROXY_CLASSES: - # the above tests only work with the new schema - del LiaisonManagementTestCase + possibly_send_deadline_reminder(liaison) + self.assertEqual(len(outbox), mailbox_before) diff --git a/ietf/liaisons/testurl.list b/ietf/liaisons/testurl.list deleted file mode 100644 index 59ca172cd..000000000 --- a/ietf/liaisons/testurl.list +++ /dev/null @@ -1,33 +0,0 @@ -200 /liaison/ -200 /liaison/321/ -200 /liaison/553/ # submitted by email -200 /liaison/337/ # test case for ticket #182 -200 /liaison/458/ # non-ASCII title -200 /liaison/471/ # non-ASCII body and submitter name - -301 /liaison/managers/ - -200 /liaison/help/to_ietf/ -200 /liaison/help/from_ietf/ -200 /liaison/help/fields/ -200 /liaison/help/ - -404 /feed/liaison/ -200 /feed/liaison/recent/ -200 /feed/liaison/from/ccamp/ -#200 /feed/liaison/from/MFA%20Forum/ -200 /feed/liaison/from/MFA_Forum/ -200 /feed/liaison/to/ccamp/ -200 /feed/liaison/subject/H.248/ -200 /feed/liaison/subject/2173/ # non-ASCII title - -404 /feed/liaison/recent/foobar/ -404 /feed/liaison/from/ -404 /feed/liaison/from/nosuchorganization/ -404 /feed/liaison/from/foo/bar/ -404 /feed/liaison/to/ -404 /feed/liaison/to/foo/bar/ -404 /feed/liaison/subject/ -404 /feed/liaison/subject/foo/bar/ - -200 /sitemap-liaison.xml diff --git a/ietf/liaisons/urls.py b/ietf/liaisons/urls.py index a9ddb236b..f09523884 100644 --- a/ietf/liaisons/urls.py +++ b/ietf/liaisons/urls.py @@ -2,17 +2,8 @@ from django.conf.urls.defaults import patterns, url from django.db.models import Q -from ietf.liaisons.models import LiaisonDetail -info_dict = { - 'queryset': LiaisonDetail.objects.filter(Q(approval__isnull=True)|Q(approval__approved=True)).order_by("-submitted_date"), -} - -# there's an opportunity for date-based filtering. -urlpatterns = patterns('django.views.generic.list_detail', -) - -urlpatterns += patterns('django.views.generic.simple', +urlpatterns = patterns('django.views.generic.simple', (r'^help/$', 'direct_to_template', {'template': 'liaisons/help.html'}), (r'^help/fields/$', 'direct_to_template', {'template': 'liaisons/field_help.html'}), (r'^help/from_ietf/$', 'direct_to_template', {'template': 'liaisons/guide_from_ietf.html'}), diff --git a/ietf/liaisons/utils.py b/ietf/liaisons/utils.py index 0d8b48c59..75e5f3766 100644 --- a/ietf/liaisons/utils.py +++ b/ietf/liaisons/utils.py @@ -1,10 +1,42 @@ -from django.conf import settings +from django.db.models import Q -from ietf.idtracker.models import Area, IETFWG -from ietf.liaisons.models import SDOs, LiaisonManagers -from ietf.liaisons.accounts import (is_ietfchair, is_iabchair, is_iab_executive_director, is_irtfchair, +from ietf.group.models import Group, Role +from ietf.person.models import Person +from ietf.liaisons.models import LiaisonStatement +from ietf.ietfauth.utils import has_role, passes_test_decorator + +from ietf.liaisons.accounts import (is_ietfchair, is_iabchair, is_iab_executive_director, get_ietf_chair, get_iab_chair, get_iab_executive_director, - is_secretariat) + is_secretariat, can_add_liaison, get_person_for_user, proxy_personify_role) + +can_submit_liaison_required = passes_test_decorator( + lambda u, *args, **kwargs: can_add_liaison(u), + "Restricted to participants who are authorized to submit liaison statements on behalf of the various IETF entities") + +def approvable_liaison_statements(user): + liaisons = LiaisonStatement.objects.filter(approved=None) + if has_role(user, "Secretariat"): + return liaisons + + # this is a bit complicated because IETFHM encodes the + # groups, it should just give us a list of ids or acronyms + group_codes = IETFHM.get_all_can_approve_codes(get_person_for_user(user)) + group_acronyms = [] + group_ids = [] + for x in group_codes: + if "_" in x: + group_ids.append(x.split("_")[1]) + else: + group_acronyms.append(x) + + return liaisons.filter(Q(from_group__acronym__in=group_acronyms) | Q(from_group__pk__in=group_ids)) + + +# the following is a biggish object hierarchy abstracting the entity +# names and auth rules for posting liaison statements in a sort of +# semi-declarational (and perhaps overengineered given the revamped +# schema) way - unfortunately, it's never been strong enough to do so +# fine-grained enough so the form code also has some rules IETFCHAIR = {'name': u'The IETF Chair', 'address': u'chair@ietf.org'} IESG = {'name': u'The IESG', 'address': u'iesg@ietf.org'} @@ -12,10 +44,7 @@ IAB = {'name': u'The IAB', 'address': u'iab@iab.org'} IABCHAIR = {'name': u'The IAB Chair', 'address': u'iab-chair@iab.org'} IABEXECUTIVEDIRECTOR = {'name': u'The IAB Executive Director', 'address': u'execd@iab.org'} IRTFCHAIR = {'name': u'The IRTF Chair', 'address': u'irtf-chair@irtf.org'} - - -def get_all_sdo_managers(): - return [i.person for i in LiaisonManagers.objects.all().distinct()] +IESGANDIAB = {'name': u'The IESG and IAB', 'address': u'iesg-iab@ietf.org'} class FakePerson(object): @@ -27,7 +56,12 @@ class FakePerson(object): def email(self): return (self.name, self.address) +def all_sdo_managers(): + return [proxy_personify_role(r) for r in Role.objects.filter(group__type="sdo", name="liaiman").select_related("person").distinct()] +def role_persons_with_fixed_email(group, role_name): + return [proxy_personify_role(r) for r in Role.objects.filter(group=group, name=role_name).select_related("person").distinct()] + class Entity(object): poc = [] @@ -84,34 +118,11 @@ class IETFEntity(Entity): return [self.poc] def full_user_list(self): - result = get_all_sdo_managers() + result = all_sdo_managers() result.append(get_ietf_chair()) return result -class IRTFEntity(Entity): - - poc = FakePerson(**IRTFCHAIR) - - def get_from_cc(self, person): - result = [] - if not is_irtfchair(person): - result.append(self.poc) - return result - - def needs_approval(self, person=None): - if is_irtfchair(person): - return False - return True - - def can_approve(self): - return [self.poc] - - def full_user_list(self): - result.append(get_irtf_chair()) - return result - - class IABEntity(Entity): chair = FakePerson(**IABCHAIR) director = FakePerson(**IABEXECUTIVEDIRECTOR) @@ -136,27 +147,75 @@ class IABEntity(Entity): return [self.chair] def full_user_list(self): - result = get_all_sdo_managers() + result = all_sdo_managers() result += [get_iab_chair(), get_iab_executive_director()] return result +class IRTFEntity(Entity): + chair = FakePerson(**IRTFCHAIR) + poc = [chair,] + + def get_from_cc(self, person): + result = [] + return result + + def needs_approval(self, person=None): + if is_irtfchair(person): + return False + return True + + def can_approve(self): + return [self.chair] + + def full_user_list(self): + result = [get_irtf_chair()] + return result + + +class IAB_IESG_Entity(Entity): + + poc = [IABEntity.chair, IABEntity.director, FakePerson(**IETFCHAIR), FakePerson(**IESGANDIAB), ] + cc = [FakePerson(**IAB), FakePerson(**IESG), FakePerson(**IESGANDIAB)] + + def __init__(self, name, obj=None): + self.name = name + self.obj = obj + self.iab = IABEntity(name, obj) + self.iesg = IETFEntity(name, obj) + + def get_from_cc(self, person): + return list(set(self.iab.get_from_cc(person) + self.iesg.get_from_cc(person))) + + def needs_approval(self, person=None): + if not self.iab.needs_approval(person): + return False + if not self.iesg.needs_approval(person): + return False + return True + + def can_approve(self): + return list(set(self.iab.can_approve() + self.iesg.can_approve())) + + def full_user_list(self): + return [get_ietf_chair(), get_iab_chair(), get_iab_executive_director()] + class AreaEntity(Entity): def get_poc(self): - return [i.person for i in self.obj.areadirector_set.all()] + return role_persons_with_fixed_email(self.obj, "ad") def get_cc(self, person=None): return [FakePerson(**IETFCHAIR)] def get_from_cc(self, person): - result = [i.person for i in self.obj.areadirector_set.all() if i.person!=person] + result = [p for p in role_persons_with_fixed_email(self.obj, "ad") if p != person] result.append(FakePerson(**IETFCHAIR)) return result def needs_approval(self, person=None): # Check if person is an area director - if self.obj.areadirector_set.filter(person=person): + if self.obj.role_set.filter(person=person, name="ad"): return False return True @@ -164,7 +223,7 @@ class AreaEntity(Entity): return self.get_poc() def full_user_list(self): - result = get_all_sdo_managers() + result = all_sdo_managers() result += self.get_poc() return result @@ -172,34 +231,38 @@ class AreaEntity(Entity): class WGEntity(Entity): def get_poc(self): - return [i.person for i in self.obj.wgchair_set.all()] + return role_persons_with_fixed_email(self.obj, "chair") def get_cc(self, person=None): - result = [i.person for i in self.obj.area_directors()] - if self.obj.email_address: - result.append(FakePerson(name ='%s Discussion List' % self.obj.group_acronym.name, - address = self.obj.email_address)) + if self.obj.parent: + result = [p for p in role_persons_with_fixed_email(self.obj.parent, "ad") if p != person] + else: + result = [] + if self.obj.list_subscribe: + result.append(FakePerson(name ='%s Discussion List' % self.obj.name, + address = self.obj.list_subscribe)) return result def get_from_cc(self, person): - result = [i.person for i in self.obj.wgchair_set.all() if i.person!=person] - result += [i.person for i in self.obj.area_directors()] - if self.obj.email_address: - result.append(FakePerson(name ='%s Discussion List' % self.obj.group_acronym.name, - address = self.obj.email_address)) + result = [p for p in role_persons_with_fixed_email(self.obj, "chair") if p != person] + if self.obj.parent: + result += role_persons_with_fixed_email(self.obj.parent, "ad") + if self.obj.list_subscribe: + result.append(FakePerson(name ='%s Discussion List' % self.obj.name, + address = self.obj.list_subscribe)) return result def needs_approval(self, person=None): - # Check if person is director of this wg area - if self.obj.area.area.areadirector_set.filter(person=person): + # Check if person is AD of area + if self.obj.parent and self.obj.parent.role_set.filter(person=person, name="ad"): return False return True def can_approve(self): - return [i.person for i in self.obj.area.area.areadirector_set.all()] + return role_persons_with_fixed_email(self.obj.parent, "ad") if self.obj.parent else [] def full_user_list(self): - result = get_all_sdo_managers() + result = all_sdo_managers() result += self.get_poc() return result @@ -210,25 +273,19 @@ class SDOEntity(Entity): return [] def get_cc(self, person=None): - manager = self.obj.liaisonmanager() - if manager: - return [manager.person] - return [] + return role_persons_with_fixed_email(self.obj, "liaiman") def get_from_cc(self, person=None): - manager = self.obj.liaisonmanager() - if manager and manager.person!=person: - return [manager.person] - return [] + return [p for p in role_persons_with_fixed_email(self.obj, "liaiman") if p != person] def post_only(self, person, user): - if is_secretariat(user) or person.sdoauthorizedindividual_set.filter(sdo=self.obj): + if is_secretariat(user) or self.obj.role_set.filter(person=person, name="auth"): return False return True def full_user_list(self): - result = [i.person for i in self.obj.liaisonmanagers_set.all().distinct()] - result += [i.person for i in self.obj.sdoauthorizedindividual_set.all().distinct()] + result = role_persons_with_fixed_email(self.obj, "liaiman") + result += role_persons_with_fixed_email(self.obj, "auth") return result @@ -314,17 +371,41 @@ class IRTFEntityManager(EntityManager): return [] +class IAB_IESG_EntityManager(EntityManager): + + def __init__(self, *args, **kwargs): + super(IAB_IESG_EntityManager, self).__init__(*args, **kwargs) + self.entity = IAB_IESG_Entity(name=self.name) + + def get_entity(self, pk=None): + return self.entity + + def can_send_on_behalf(self, person): + if (is_iabchair(person) or + is_iab_executive_director(person) or + is_ietfchair(person)): + return self.get_managed_list() + return [] + + def can_approve_list(self, person): + if (is_iabchair(person) or + is_iab_executive_director(person) or + is_ietfchair(person)): + return self.get_managed_list() + return [] + + class AreaEntityManager(EntityManager): def __init__(self, pk=None, name=None, queryset=None): super(AreaEntityManager, self).__init__(pk, name, queryset) if self.queryset == None: - self.queryset = Area.active_areas() + self.queryset = Group.objects.filter(type="area", state="active") def get_managed_list(self, query_filter=None): if not query_filter: query_filter = {} - return [(u'%s_%s' % (self.pk, i.pk), i.area_acronym.name) for i in self.queryset.filter(**query_filter).order_by('area_acronym__name')] + return [(u'%s_%s' % (self.pk, i.pk), i.name) for i in self.queryset.filter(**query_filter).order_by('name')] def get_entity(self, pk=None): if not pk: @@ -333,14 +414,14 @@ class AreaEntityManager(EntityManager): obj = self.queryset.get(pk=pk) except self.queryset.model.DoesNotExist: return None - return AreaEntity(name=obj.area_acronym.name, obj=obj) + return AreaEntity(name=obj.name, obj=obj) def can_send_on_behalf(self, person): - query_filter = {'areadirector__in': person.areadirector_set.all()} + query_filter = dict(role__person=person, role__name="ad") return self.get_managed_list(query_filter) def can_approve_list(self, person): - query_filter = {'areadirector__in': person.areadirector_set.all()} + query_filter = dict(role__person=person, role__name="ad") return self.get_managed_list(query_filter) @@ -349,12 +430,12 @@ class WGEntityManager(EntityManager): def __init__(self, pk=None, name=None, queryset=None): super(WGEntityManager, self).__init__(pk, name, queryset) if self.queryset == None: - self.queryset = IETFWG.objects.filter(group_type=1, status=IETFWG.ACTIVE, areagroup__area__status=Area.ACTIVE) + self.queryset = Group.objects.filter(type="wg", state="active", parent__state="active").select_related("parent") def get_managed_list(self, query_filter=None): if not query_filter: query_filter = {} - return [(u'%s_%s' % (self.pk, i.pk), '%s - %s' % (i.group_acronym.acronym, i.group_acronym.name)) for i in self.queryset.filter(**query_filter).order_by('group_acronym__acronym')] + return [(u'%s_%s' % (self.pk, i.pk), '%s - %s' % (i.acronym, i.name)) for i in self.queryset.filter(**query_filter).order_by('acronym')] def get_entity(self, pk=None): if not pk: @@ -363,16 +444,15 @@ class WGEntityManager(EntityManager): obj = self.queryset.get(pk=pk) except self.queryset.model.DoesNotExist: return None - return WGEntity(name=obj.group_acronym.name, obj=obj) + return WGEntity(name=obj.name, obj=obj) def can_send_on_behalf(self, person): - wgs = set([i.group_acronym.pk for i in person.wgchair_set.all()]) - wgs = wgs.union([i.group_acronym.pk for i in person.wgsecretary_set.all()]) + wgs = Group.objects.filter(role__person=person, role__name__in=("chair", "secretary")).values_list('pk', flat=True) query_filter = {'pk__in': wgs} return self.get_managed_list(query_filter) def can_approve_list(self, person): - query_filter = {'areagroup__area__areadirector__in': person.areadirector_set.all()} + query_filter = dict(parent__role__person=person, parent__role__name="ad") return self.get_managed_list(query_filter) @@ -381,10 +461,10 @@ class SDOEntityManager(EntityManager): def __init__(self, pk=None, name=None, queryset=None): super(SDOEntityManager, self).__init__(pk, name, queryset) if self.queryset == None: - self.queryset = SDOs.objects.all() + self.queryset = Group.objects.filter(type="sdo") def get_managed_list(self): - return [(u'%s_%s' % (self.pk, i.pk), i.sdo_name) for i in self.queryset.order_by('sdo_name')] + return [(u'%s_%s' % (self.pk, i.pk), i.name) for i in self.queryset.order_by('name')] def get_entity(self, pk=None): if not pk: @@ -393,7 +473,7 @@ class SDOEntityManager(EntityManager): obj = self.queryset.get(pk=pk) except self.queryset.model.DoesNotExist: return None - return SDOEntity(name=obj.sdo_name, obj=obj) + return SDOEntity(name=obj.name, obj=obj) class IETFHierarchyManager(object): @@ -402,7 +482,7 @@ class IETFHierarchyManager(object): self.managers = {'ietf': IETFEntityManager(pk='ietf', name=u'The IETF'), 'iesg': IETFEntityManager(pk='iesg', name=u'The IESG'), 'iab': IABEntityManager(pk='iab', name=u'The IAB'), - 'irtf': IRTFEntityManager(pk='irtf', name=u'The IAB'), + 'iabiesg': IAB_IESG_EntityManager(pk='iabiesg', name=u'The IESG and the IAB'), 'area': AreaEntityManager(pk='area', name=u'IETF Areas'), 'wg': WGEntityManager(pk='wg', name=u'IETF Working Groups'), 'sdo': SDOEntityManager(pk='sdo', name=u'Standards Development Organizations'), @@ -430,7 +510,7 @@ class IETFHierarchyManager(object): def get_all_incoming_entities(self): entities = [] results = [] - for key in ['ietf', 'iesg', 'iab']: + for key in ['ietf', 'iesg', 'iab', 'iabiesg']: results += self.managers[key].get_managed_list() entities.append(('Main IETF Entities', results)) entities.append(('IETF Areas', self.managers['area'].get_managed_list())) @@ -445,7 +525,7 @@ class IETFHierarchyManager(object): def get_entities_for_person(self, person): entities = [] results = [] - for key in ['ietf', 'iesg', 'iab']: + for key in ['ietf', 'iesg', 'iab', 'iabiesg']: results += self.managers[key].can_send_on_behalf(person) if results: entities.append(('Main IETF Entities', results)) @@ -459,7 +539,7 @@ class IETFHierarchyManager(object): def get_all_can_approve_codes(self, person): entities = [] - for key in ['ietf', 'iesg', 'iab']: + for key in ['ietf', 'iesg', 'iab', 'iabiesg']: entities += self.managers[key].can_approve_list(person) entities += self.managers['area'].can_approve_list(person) entities += self.managers['wg'].can_approve_list(person) @@ -467,6 +547,3 @@ class IETFHierarchyManager(object): IETFHM = IETFHierarchyManager() - -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - from utilsREDESIGN import * diff --git a/ietf/liaisons/utilsREDESIGN.py b/ietf/liaisons/utilsREDESIGN.py deleted file mode 100644 index 53668003c..000000000 --- a/ietf/liaisons/utilsREDESIGN.py +++ /dev/null @@ -1,524 +0,0 @@ -from ietf.group.models import Group, Role -from ietf.person.models import Person -from ietf.utils.proxy import proxy_personify_role - -from ietf.liaisons.accounts import (is_ietfchair, is_iabchair, is_iab_executive_director, - get_ietf_chair, get_iab_chair, get_iab_executive_director, - is_secretariat) - -IETFCHAIR = {'name': u'The IETF Chair', 'address': u'chair@ietf.org'} -IESG = {'name': u'The IESG', 'address': u'iesg@ietf.org'} -IAB = {'name': u'The IAB', 'address': u'iab@iab.org'} -IABCHAIR = {'name': u'The IAB Chair', 'address': u'iab-chair@iab.org'} -IABEXECUTIVEDIRECTOR = {'name': u'The IAB Executive Director', 'address': u'execd@iab.org'} -IRTFCHAIR = {'name': u'The IRTF Chair', 'address': u'irtf-chair@irtf.org'} -IESGANDIAB = {'name': u'The IESG and IAB', 'address': u'iesg-iab@ietf.org'} - - -class FakePerson(object): - - def __init__(self, name, address): - self.name = name - self.address = address - - def email(self): - return (self.name, self.address) - -# the following is a biggish object hierarchy abstracting the entity -# names and auth rules for posting liaison statements in a sort of -# semi-declarational (and perhaps overengineered given the revamped -# schema) way - unfortunately, it's never been strong enough to do so -# fine-grained enough so the form code also has some rules - -def all_sdo_managers(): - return [proxy_personify_role(r) for r in Role.objects.filter(group__type="sdo", name="liaiman").select_related("person").distinct()] - -def role_persons_with_fixed_email(group, role_name): - return [proxy_personify_role(r) for r in Role.objects.filter(group=group, name=role_name).select_related("person").distinct()] - -class Entity(object): - - poc = [] - cc = [] - - def __init__(self, name, obj=None): - self.name = name - self.obj = obj - - def get_poc(self): - if not isinstance(self.poc, list): - return [self.poc] - return self.poc - - def get_cc(self, person=None): - if not isinstance(self.cc, list): - return [self.cc] - return self.cc - - def get_from_cc(self, person=None): - return [] - - def needs_approval(self, person=None): - return False - - def can_approve(self): - return [] - - def post_only(self, person, user): - return False - - def full_user_list(self): - return False - - -class IETFEntity(Entity): - - poc = FakePerson(**IETFCHAIR) - cc = FakePerson(**IESG) - - def get_from_cc(self, person): - result = [] - if not is_ietfchair(person): - result.append(self.poc) - result.append(self.cc) - return result - - def needs_approval(self, person=None): - if is_ietfchair(person): - return False - return True - - def can_approve(self): - return [self.poc] - - def full_user_list(self): - result = all_sdo_managers() - result.append(get_ietf_chair()) - return result - - -class IABEntity(Entity): - chair = FakePerson(**IABCHAIR) - director = FakePerson(**IABEXECUTIVEDIRECTOR) - poc = [chair, director] - cc = FakePerson(**IAB) - - def get_from_cc(self, person): - result = [] - if not is_iabchair(person): - result.append(self.chair) - result.append(self.cc) - if not is_iab_executive_director(person): - result.append(self.director) - return result - - def needs_approval(self, person=None): - if is_iabchair(person) or is_iab_executive_director(person): - return False - return True - - def can_approve(self): - return [self.chair] - - def full_user_list(self): - result = all_sdo_managers() - result += [get_iab_chair(), get_iab_executive_director()] - return result - - -class IRTFEntity(Entity): - chair = FakePerson(**IRTFCHAIR) - poc = [chair,] - - def get_from_cc(self, person): - result = [] - return result - - def needs_approval(self, person=None): - if is_irtfchair(person): - return False - return True - - def can_approve(self): - return [self.chair] - - def full_user_list(self): - result = [get_irtf_chair()] - return result - - -class IAB_IESG_Entity(Entity): - - poc = [IABEntity.chair, IABEntity.director, FakePerson(**IETFCHAIR), FakePerson(**IESGANDIAB), ] - cc = [FakePerson(**IAB), FakePerson(**IESG), FakePerson(**IESGANDIAB)] - - def __init__(self, name, obj=None): - self.name = name - self.obj = obj - self.iab = IABEntity(name, obj) - self.iesg = IETFEntity(name, obj) - - def get_from_cc(self, person): - return list(set(self.iab.get_from_cc(person) + self.iesg.get_from_cc(person))) - - def needs_approval(self, person=None): - if not self.iab.needs_approval(person): - return False - if not self.iesg.needs_approval(person): - return False - return True - - def can_approve(self): - return list(set(self.iab.can_approve() + self.iesg.can_approve())) - - def full_user_list(self): - return [get_ietf_chair(), get_iab_chair(), get_iab_executive_director()] - -class AreaEntity(Entity): - - def get_poc(self): - return role_persons_with_fixed_email(self.obj, "ad") - - def get_cc(self, person=None): - return [FakePerson(**IETFCHAIR)] - - def get_from_cc(self, person): - result = [p for p in role_persons_with_fixed_email(self.obj, "ad") if p != person] - result.append(FakePerson(**IETFCHAIR)) - return result - - def needs_approval(self, person=None): - # Check if person is an area director - if self.obj.role_set.filter(person=person, name="ad"): - return False - return True - - def can_approve(self): - return self.get_poc() - - def full_user_list(self): - result = all_sdo_managers() - result += self.get_poc() - return result - - -class WGEntity(Entity): - - def get_poc(self): - return role_persons_with_fixed_email(self.obj, "chair") - - def get_cc(self, person=None): - if self.obj.parent: - result = [p for p in role_persons_with_fixed_email(self.obj.parent, "ad") if p != person] - else: - result = [] - if self.obj.list_subscribe: - result.append(FakePerson(name ='%s Discussion List' % self.obj.name, - address = self.obj.list_subscribe)) - return result - - def get_from_cc(self, person): - result = [p for p in role_persons_with_fixed_email(self.obj, "chair") if p != person] - result += role_persons_with_fixed_email(self.obj.parent, "ad") if self.obj.parent else [] - if self.obj.list_subscribe: - result.append(FakePerson(name ='%s Discussion List' % self.obj.name, - address = self.obj.list_subscribe)) - return result - - def needs_approval(self, person=None): - # Check if person is director of this wg area - if self.obj.parent and self.obj.parent.role_set.filter(person=person, name="ad"): - return False - return True - - def can_approve(self): - return role_persons_with_fixed_email(self.obj.parent, "ad") if self.obj.parent else [] - - def full_user_list(self): - result = all_sdo_managers() - result += self.get_poc() - return result - - -class SDOEntity(Entity): - - def get_poc(self): - return [] - - def get_cc(self, person=None): - return role_persons_with_fixed_email(self.obj, "liaiman") - - def get_from_cc(self, person=None): - return [p for p in role_persons_with_fixed_email(self.obj, "liaiman") if p != person] - - def post_only(self, person, user): - if is_secretariat(user) or self.obj.role_set.filter(person=person, name="auth"): - return False - return True - - def full_user_list(self): - result = role_persons_with_fixed_email(self.obj, "liaiman") - result += role_persons_with_fixed_email(self.obj, "auth") - return result - - -class EntityManager(object): - - def __init__(self, pk=None, name=None, queryset=None): - self.pk = pk - self.name = name - self.queryset = queryset - - def get_entity(self, pk=None): - return Entity(name=self.name) - - def get_managed_list(self): - return [(self.pk, self.name)] - - def can_send_on_behalf(self, person): - return [] - - def can_approve_list(self, person): - return [] - - -class IETFEntityManager(EntityManager): - - def __init__(self, *args, **kwargs): - super(IETFEntityManager, self).__init__(*args, **kwargs) - self.entity = IETFEntity(name=self.name) - - def get_entity(self, pk=None): - return self.entity - - def can_send_on_behalf(self, person): - if is_ietfchair(person): - return self.get_managed_list() - return [] - - def can_approve_list(self, person): - if is_ietfchair(person): - return self.get_managed_list() - return [] - - -class IABEntityManager(EntityManager): - - def __init__(self, *args, **kwargs): - super(IABEntityManager, self).__init__(*args, **kwargs) - self.entity = IABEntity(name=self.name) - - def get_entity(self, pk=None): - return self.entity - - def can_send_on_behalf(self, person): - if (is_iabchair(person) or - is_iab_executive_director(person)): - return self.get_managed_list() - return [] - - def can_approve_list(self, person): - if (is_iabchair(person) or - is_iab_executive_director(person)): - return self.get_managed_list() - return [] - - -class IRTFEntityManager(EntityManager): - - def __init__(self, *args, **kwargs): - super(IRTFEntityManager, self).__init__(*args, **kwargs) - self.entity = IRTFEntity(name=self.name) - - def get_entity(self, pk=None): - return self.entity - - def can_send_on_behalf(self, person): - if is_irtfchair(person): - return self.get_managed_list() - return [] - - def can_approve_list(self, person): - if is_irtfchair(person): - return self.get_managed_list() - return [] - - -class IAB_IESG_EntityManager(EntityManager): - - def __init__(self, *args, **kwargs): - super(IAB_IESG_EntityManager, self).__init__(*args, **kwargs) - self.entity = IAB_IESG_Entity(name=self.name) - - def get_entity(self, pk=None): - return self.entity - - def can_send_on_behalf(self, person): - if (is_iabchair(person) or - is_iab_executive_director(person) or - is_ietfchair(person)): - return self.get_managed_list() - return [] - - def can_approve_list(self, person): - if (is_iabchair(person) or - is_iab_executive_director(person) or - is_ietfchair(person)): - return self.get_managed_list() - return [] - - -class AreaEntityManager(EntityManager): - - def __init__(self, pk=None, name=None, queryset=None): - super(AreaEntityManager, self).__init__(pk, name, queryset) - from ietf.group.proxy import Area - if self.queryset == None: - self.queryset = Area.active_areas() - - def get_managed_list(self, query_filter=None): - if not query_filter: - query_filter = {} - return [(u'%s_%s' % (self.pk, i.pk), i.area_acronym.name) for i in self.queryset.filter(**query_filter).order_by('area_acronym__name')] - - def get_entity(self, pk=None): - if not pk: - return None - try: - obj = self.queryset.get(pk=pk) - except self.queryset.model.DoesNotExist: - return None - return AreaEntity(name=obj.area_acronym.name, obj=obj) - - def can_send_on_behalf(self, person): - query_filter = dict(role__person=person, role__name="ad") - return self.get_managed_list(query_filter) - - def can_approve_list(self, person): - query_filter = dict(role__person=person, role__name="ad") - return self.get_managed_list(query_filter) - - -class WGEntityManager(EntityManager): - - def __init__(self, pk=None, name=None, queryset=None): - super(WGEntityManager, self).__init__(pk, name, queryset) - if self.queryset == None: - from ietf.group.proxy import IETFWG, Area - self.queryset = IETFWG.objects.filter(group_type=1, status=IETFWG.ACTIVE, areagroup__area__status=Area.ACTIVE) - - def get_managed_list(self, query_filter=None): - if not query_filter: - query_filter = {} - return [(u'%s_%s' % (self.pk, i.pk), '%s - %s' % (i.group_acronym.acronym, i.group_acronym.name)) for i in self.queryset.filter(**query_filter).order_by('group_acronym__acronym')] - - def get_entity(self, pk=None): - if not pk: - return None - try: - obj = self.queryset.get(pk=pk) - except self.queryset.model.DoesNotExist: - return None - return WGEntity(name=obj.group_acronym.name, obj=obj) - - def can_send_on_behalf(self, person): - wgs = Group.objects.filter(role__person=person, role__name__in=("chair", "secretary")).values_list('pk', flat=True) - query_filter = {'pk__in': wgs} - return self.get_managed_list(query_filter) - - def can_approve_list(self, person): - query_filter = dict(parent__role__person=person, parent__role__name="ad") - return self.get_managed_list(query_filter) - - -class SDOEntityManager(EntityManager): - - def __init__(self, pk=None, name=None, queryset=None): - super(SDOEntityManager, self).__init__(pk, name, queryset) - if self.queryset == None: - self.queryset = Group.objects.filter(type="sdo") - - def get_managed_list(self): - return [(u'%s_%s' % (self.pk, i.pk), i.name) for i in self.queryset.order_by('name')] - - def get_entity(self, pk=None): - if not pk: - return None - try: - obj = self.queryset.get(pk=pk) - except self.queryset.model.DoesNotExist: - return None - return SDOEntity(name=obj.name, obj=obj) - - -class IETFHierarchyManager(object): - - def __init__(self): - self.managers = {'ietf': IETFEntityManager(pk='ietf', name=u'The IETF'), - 'iesg': IETFEntityManager(pk='iesg', name=u'The IESG'), - 'iab': IABEntityManager(pk='iab', name=u'The IAB'), - 'iabiesg': IAB_IESG_EntityManager(pk='iabiesg', name=u'The IESG and the IAB'), - 'area': AreaEntityManager(pk='area', name=u'IETF Areas'), - 'wg': WGEntityManager(pk='wg', name=u'IETF Working Groups'), - 'sdo': SDOEntityManager(pk='sdo', name=u'Standards Development Organizations'), - 'othersdo': EntityManager(pk='othersdo', name=u'Other SDOs'), - } - - def get_entity_by_key(self, entity_id): - if not entity_id: - return None - id_list = entity_id.split('_', 1) - key = id_list[0] - pk = None - if len(id_list)==2: - pk = id_list[1] - if key not in self.managers.keys(): - return None - return self.managers[key].get_entity(pk) - - def get_all_entities(self): - entities = [] - for manager in self.managers.values(): - entities += manager.get_managed_list() - return entities - - def get_all_incoming_entities(self): - entities = [] - results = [] - for key in ['ietf', 'iesg', 'iab', 'iabiesg']: - results += self.managers[key].get_managed_list() - entities.append(('Main IETF Entities', results)) - entities.append(('IETF Areas', self.managers['area'].get_managed_list())) - entities.append(('IETF Working Groups', self.managers['wg'].get_managed_list())) - return entities - - def get_all_outgoing_entities(self): - entities = [(self.managers['sdo'].name, self.managers['sdo'].get_managed_list())] - entities += [(self.managers['othersdo'].name, self.managers['othersdo'].get_managed_list())] - return entities - - def get_entities_for_person(self, person): - entities = [] - results = [] - for key in ['ietf', 'iesg', 'iab', 'iabiesg']: - results += self.managers[key].can_send_on_behalf(person) - if results: - entities.append(('Main IETF Entities', results)) - areas = self.managers['area'].can_send_on_behalf(person) - if areas: - entities.append(('IETF Areas', areas)) - wgs = self.managers['wg'].can_send_on_behalf(person) - if wgs: - entities.append(('IETF Working Groups', wgs)) - return entities - - def get_all_can_approve_codes(self, person): - entities = [] - for key in ['ietf', 'iesg', 'iab', 'iabiesg']: - entities += self.managers[key].can_approve_list(person) - entities += self.managers['area'].can_approve_list(person) - entities += self.managers['wg'].can_approve_list(person) - return [i[0] for i in entities] - - -IETFHM = IETFHierarchyManager() diff --git a/ietf/liaisons/views.py b/ietf/liaisons/views.py index b935d86a9..3751e46f0 100644 --- a/ietf/liaisons/views.py +++ b/ietf/liaisons/views.py @@ -4,52 +4,49 @@ from email.utils import parseaddr from django.conf import settings from django.core.urlresolvers import reverse -from django.db.models import Q -from django.core.validators import email_re +from django.core.validators import validate_email, ValidationError from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden -from django.shortcuts import render_to_response, get_object_or_404 +from django.shortcuts import render_to_response, get_object_or_404, redirect from django.template import RequestContext from django.utils import simplejson from django.views.generic.list_detail import object_list, object_detail +from ietf.liaisons.models import LiaisonStatement from ietf.liaisons.accounts import (get_person_for_user, can_add_outgoing_liaison, can_add_incoming_liaison, LIAISON_EDIT_GROUPS, is_ietfchair, is_iabchair, is_iab_executive_director, can_edit_liaison, is_secretariat) -from ietf.liaisons.decorators import can_submit_liaison from ietf.liaisons.forms import liaison_form_factory -from ietf.liaisons.models import LiaisonDetail, OutgoingLiaisonApproval -from ietf.liaisons.utils import IETFHM - -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - from ietf.liaisons.proxy import LiaisonDetailProxy as LiaisonDetail +from ietf.liaisons.utils import IETFHM, can_submit_liaison_required, approvable_liaison_statements +from ietf.liaisons.mails import notify_pending_by_email, send_liaison_by_email -@can_submit_liaison + +@can_submit_liaison_required def add_liaison(request, liaison=None): if request.method == 'POST': form = liaison_form_factory(request, data=request.POST.copy(), files = request.FILES, liaison=liaison) if form.is_valid(): liaison = form.save() - if request.POST.get('send', None): - if liaison.is_pending(): - liaison.notify_pending_by_email() + if request.POST.get('send', False): + if not liaison.approved: + notify_pending_by_email(request, liaison) else: - liaison.send_by_email() + send_liaison_by_email(request, liaison) return HttpResponseRedirect(reverse('liaison_list')) else: form = liaison_form_factory(request, liaison=liaison) return render_to_response( - 'liaisons/liaisondetail_edit.html', + 'liaisons/edit.html', {'form': form, 'liaison': liaison}, context_instance=RequestContext(request), ) -@can_submit_liaison +@can_submit_liaison_required def get_info(request): person = get_person_for_user(request.user) @@ -74,143 +71,85 @@ def get_info(request): result.update({'error': '\n'.join([to_error, from_error])}) else: result.update({'error': False, - 'cc': [i.email() for i in to_entity.get_cc(person=person)] +\ - [i.email() for i in from_entity.get_from_cc(person=person)], + 'cc': ([i.email() for i in to_entity.get_cc(person=person)] + + [i.email() for i in from_entity.get_from_cc(person=person)]), 'poc': [i.email() for i in to_entity.get_poc()], 'needs_approval': from_entity.needs_approval(person=person), 'post_only': from_entity.post_only(person=person, user=request.user)}) if is_secretariat(request.user): full_list = [(i.pk, i.email()) for i in set(from_entity.full_user_list())] - full_list.sort(lambda x,y: cmp(x[1], y[1])) + full_list.sort(key=lambda x: x[1]) full_list = [(person.pk, person.email())] + full_list result.update({'full_list': full_list}) json_result = simplejson.dumps(result) return HttpResponse(json_result, mimetype='text/javascript') +def normalize_sort(request): + sort = request.GET.get('sort', "") + if sort not in ('submitted', 'deadline', 'title', 'to_name', 'from_name'): + sort = "submitted" -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - def approvable_liaison_statements(group_codes): - # this is a bit complicated because IETFHM encodes the - # groups, it should just give us a list of ids or acronyms - group_acronyms = [] - group_ids = [] - for x in group_codes: - if "_" in x: - group_ids.append(x.split("_")[1]) - else: - group_acronyms.append(x) + # reverse dates + order_by = "-" + sort if sort in ("submitted", "deadline") else sort - return LiaisonDetail.objects.filter(approved=None).filter(Q(from_group__acronym__in=group_acronyms) | Q (from_group__pk__in=group_ids)) + return sort, order_by def liaison_list(request): - user = request.user - can_send_outgoing = can_add_outgoing_liaison(user) - can_send_incoming = can_add_incoming_liaison(user) - can_approve = False - can_edit = False + sort, order_by = normalize_sort(request) + liaisons = LiaisonStatement.objects.exclude(approved=None).order_by(order_by) - person = get_person_for_user(request.user) - if person: - approval_codes = IETFHM.get_all_can_approve_codes(person) - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - if is_secretariat(request.user): - can_approve = LiaisonDetail.objects.filter(approved=None).order_by("-submitted").count() - else: - can_approve = approvable_liaison_statements(approval_codes).count() - else: - can_approve = LiaisonDetail.objects.filter(approval__isnull=False, approval__approved=False, from_raw_code__in=approval_codes).count() + can_send_outgoing = can_add_outgoing_liaison(request.user) + can_send_incoming = can_add_incoming_liaison(request.user) - order = request.GET.get('order_by', 'submitted_date') - plain_order = order - reverse_order = order.startswith('-') - if reverse_order: - plain_order = order[1:] - if plain_order not in ('submitted_date', 'deadline_date', 'title', 'to_body', 'from_raw_body'): - order = 'submitted_date' - reverse_order = True - plain_order = 'submitted_date' - elif plain_order in ('submitted_date', 'deadline_date'): - # Reverse order for date fields, humans find it more natural - if reverse_order: - order = plain_order - else: - order = '-%s' % plain_order - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - public_liaisons = LiaisonDetail.objects.exclude(approved=None).order_by(order) - else: - public_liaisons = LiaisonDetail.objects.filter(Q(approval__isnull=True)|Q(approval__approved=True)).order_by(order) + approvable = approvable_liaison_statements(request.user).count() - return object_list(request, public_liaisons, - allow_empty=True, - template_name='liaisons/liaisondetail_list.html', - extra_context={'can_manage': can_approve or can_send_incoming or can_send_outgoing, - 'can_approve': can_approve, - 'can_edit': can_edit, - 'can_send_incoming': can_send_incoming, - 'can_send_outgoing': can_send_outgoing, - plain_order: not reverse_order and '-' or None}, - ) + return render_to_response('liaisons/overview.html', { + "liaisons": liaisons, + "can_manage": approvable or can_send_incoming or can_send_outgoing, + "approvable": approvable, + "can_send_incoming": can_send_incoming, + "can_send_outgoing": can_send_outgoing, + "sort": sort, + }, context_instance=RequestContext(request)) +def ajax_liaison_list(request): + sort, order_by = normalize_sort(request) + liaisons = LiaisonStatement.objects.exclude(approved=None).order_by(order_by) -@can_submit_liaison + return render_to_response('liaisons/liaison_table.html', { + "liaisons": liaisons, + "sort": sort, + }, context_instance=RequestContext(request)) + +@can_submit_liaison_required def liaison_approval_list(request): - if is_secretariat(request.user): - to_approve = LiaisonDetail.objects.filter(approved=None).order_by("-submitted") - else: - person = get_person_for_user(request.user) - approval_codes = IETFHM.get_all_can_approve_codes(person) - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - to_approve = approvable_liaison_statements(approval_codes).order_by("-submitted") - else: - to_approve = LiaisonDetail.objects.filter(approval__isnull=False, approval__approved=False, from_raw_code__in=approval_codes).order_by("-submitted_date") + liaisons = approvable_liaison_statements(request.user).order_by("-submitted") - return object_list(request, to_approve, - allow_empty=True, - template_name='liaisons/liaisondetail_approval_list.html', - ) + return render_to_response('liaisons/approval_list.html', { + "liaisons": liaisons, + }, context_instance=RequestContext(request)) -@can_submit_liaison +@can_submit_liaison_required def liaison_approval_detail(request, object_id): - if is_secretariat(request.user): - to_approve = LiaisonDetail.objects.filter(approved=None).order_by("-submitted") - else: - person = get_person_for_user(request.user) - approval_codes = IETFHM.get_all_can_approve_codes(person) - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - to_approve = approvable_liaison_statements(approval_codes).order_by("-submitted") - else: - to_approve = LiaisonDetail.objects.filter(approval__isnull=False, approval__approved=False, from_raw_code__in=approval_codes).order_by("-submitted_date") + liaison = get_object_or_404(approvable_liaison_statements(request.user), pk=object_id) - if request.method=='POST' and request.POST.get('do_approval', False): - try: - liaison = to_approve.get(pk=object_id) - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - liaison.approved = datetime.datetime.now() - liaison.save() - else: - approval = liaison.approval - if not approval: - approval = OutgoingLiaisonApproval.objects.create(approved=True, approval_date=datetime.datetime.now()) - liaison.approval = approval - liaison.save() - else: - approval.approved=True - approval.save() - liaison.send_by_email() - except LiaisonDetail.DoesNotExist: - pass - return HttpResponseRedirect(reverse('liaison_list')) - return object_detail(request, - to_approve, - object_id=object_id, - template_name='liaisons/liaisondetail_approval_detail.html', - ) + if request.method == 'POST' and request.POST.get('do_approval', False): + liaison.approved = datetime.datetime.now() + liaison.save() + + send_liaison_by_email(request, liaison) + return redirect('liaison_list') + + return render_to_response('liaisons/approval_detail.html', { + "liaison": liaison, + "is_approving": True, + }, context_instance=RequestContext(request)) def _can_take_care(liaison, user): - if not liaison.deadline_date or liaison.action_taken: + if not liaison.deadline or liaison.action_taken: return False if user.is_authenticated(): @@ -224,15 +163,18 @@ def _can_take_care(liaison, user): def _find_person_in_emails(liaison, person): if not person: return False - emails = ','.join([ e for e in [liaison.cc1, liaison.cc2, liaison.to_email, - liaison.to_poc, liaison.submitter_email, - liaison.replyto, liaison.response_contact, - liaison.technical_contact] if e ]) + + emails = ','.join(e for e in [liaison.cc, liaison.to_contact, liaison.to_name, + liaison.reply_to, liaison.response_contact, + liaison.technical_contact] if e) for email in emails.split(','): name, addr = parseaddr(email) - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - person.emailaddress_set = person.email_set - if email_re.search(addr) and person.emailaddress_set.filter(address=addr): + try: + validate_email(addr) + except ValidationError: + continue + + if person.email_set.filter(address=addr): return True elif addr in ('chair@ietf.org', 'iesg@ietf.org') and is_ietfchair(person): return True @@ -240,67 +182,31 @@ def _find_person_in_emails(liaison, person): return True elif addr in ('execd@iab.org', ) and is_iab_executive_director(person): return True + return False def liaison_detail(request, object_id): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - qfilter = Q() - public_liaisons = LiaisonDetail.objects.exclude(approved=None).order_by("-submitted_date") - else: - qfilter = Q(approval__isnull=True)|Q(approval__approved=True) - public_liaisons = LiaisonDetail.objects.filter(qfilter).order_by("-submitted_date") - liaison = get_object_or_404(public_liaisons, pk=object_id) - can_edit = False - user = request.user - can_take_care = _can_take_care(liaison, user) - if user.is_authenticated() and can_edit_liaison(user, liaison): - can_edit = True + liaison = get_object_or_404(LiaisonStatement.objects.exclude(approved=None), pk=object_id) + can_edit = request.user.is_authenticated() and can_edit_liaison(request.user, liaison) + can_take_care = _can_take_care(liaison, request.user) + if request.method == 'POST' and request.POST.get('do_action_taken', None) and can_take_care: liaison.action_taken = True liaison.save() can_take_care = False - relations = liaison.liaisondetail_set.filter(qfilter) - return object_detail(request, - public_liaisons, - template_name="liaisons/liaisondetail_detail.html", - object_id=object_id, - extra_context = {'can_edit': can_edit, - 'relations': relations, - 'can_take_care': can_take_care} - ) + + relations = liaison.liaisonstatement_set.exclude(approved=None) + + return render_to_response("liaisons/detail.html", { + "liaison": liaison, + "can_edit": can_edit, + "can_take_care": can_take_care, + "relations": relations, + }, context_instance=RequestContext(request)) def liaison_edit(request, object_id): - liaison = get_object_or_404(LiaisonDetail, pk=object_id) - user = request.user - if not (user.is_authenticated() and can_edit_liaison(user, liaison)): - return HttpResponseForbidden('You have no permission to edit this liaison') + liaison = get_object_or_404(LiaisonStatement, pk=object_id) + if not (request.user.is_authenticated() and can_edit_liaison(request.user, liaison)): + return HttpResponseForbidden('You do not have permission to edit this liaison statement') return add_liaison(request, liaison=liaison) - -def ajax_liaison_list(request): - order = request.GET.get('order_by', 'submitted_date') - plain_order = order - reverse_order = order.startswith('-') - if reverse_order: - plain_order = order[1:] - if plain_order not in ('submitted_date', 'deadline_date', 'title', 'to_body', 'from_raw_body'): - order = 'submitted_date' - reverse_order = True - plain_order = 'submitted_date' - elif plain_order in ('submitted_date', 'deadline_date'): - # Reverse order for date fields, humans find it more natural - if reverse_order: - order = plain_order - else: - order = '-%s' % plain_order - - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - public_liaisons = LiaisonDetail.objects.exclude(approved=None).order_by(order) - else: - public_liaisons = LiaisonDetail.objects.filter(Q(approval__isnull=True)|Q(approval__approved=True)).order_by(order) - - return object_list(request, public_liaisons, - allow_empty=True, - template_name='liaisons/liaisondetail_simple_list.html', - extra_context={plain_order: not reverse_order and '-' or None} - ) diff --git a/ietf/liaisons/widgets.py b/ietf/liaisons/widgets.py index db5366eef..cd872a5e9 100644 --- a/ietf/liaisons/widgets.py +++ b/ietf/liaisons/widgets.py @@ -1,8 +1,11 @@ from django.conf import settings -from django.core.urlresolvers import reverse +from django.core.urlresolvers import reverse as urlreverse from django.db.models.query import QuerySet from django.forms.widgets import Select, Widget, TextInput from django.utils.safestring import mark_safe +from django.utils.html import conditional_escape + +from ietf.liaisons.models import LiaisonStatement class FromWidget(Select): @@ -14,9 +17,9 @@ class FromWidget(Select): def render(self, name, value, attrs=None, choices=()): all_choices = list(self.choices) + list(choices) - if len(all_choices)!=1 or \ - (isinstance(all_choices[0][1], (list, tuple)) and \ - len(all_choices[0][1])!=1): + if (len(all_choices) != 1 or + (isinstance(all_choices[0][1], (list, tuple)) and + len(all_choices[0][1]) != 1)): base = super(FromWidget, self).render(name, value, attrs, choices) else: option = all_choices[0] @@ -24,14 +27,14 @@ class FromWidget(Select): option = option[1][0] value = option[0] text = option[1] - base = u'%s' % (value, name, name, text) - base += u' (' + self.submitter + u')' + base = u'%s' % (conditional_escape(value), conditional_escape(name), conditional_escape(name), conditional_escape(text)) + base += u' (' + conditional_escape(self.submitter) + u')' if self.full_power_on: base += '' return mark_safe(base) @@ -39,7 +42,7 @@ class FromWidget(Select): class ReadOnlyWidget(Widget): def render(self, name, value, attrs=None): - html = u'
%s
' % (name, value or '') + html = u'
%s
' % (conditional_escape(name), conditional_escape(value or '')) return mark_safe(html) @@ -53,14 +56,14 @@ class ButtonWidget(Widget): super(ButtonWidget, self).__init__(*args, **kwargs) def render(self, name, value, attrs=None): - html = u'' % self.show_on - html += u'' % self.label + html = u'' % conditional_escape(self.show_on) + html += u'' % conditional_escape(self.label) if self.require: for i in self.require: - html += u'' % i - required_str = u'Please fill %s to attach a new file' % self.required_label - html += u'' % required_str - html += u'' % self.label + html += u'' % conditional_escape(i) + required_str = u'Please fill in %s to attach a new file' % conditional_escape(self.required_label) + html += u'' % conditional_escape(required_str) + html += u'' % conditional_escape(self.label) return mark_safe(html) @@ -71,8 +74,8 @@ class ShowAttachmentsWidget(Widget): html += u'' html += u'
' if value and isinstance(value, QuerySet): - for attach in value: - html += u'%s
' % (settings.LIAISON_ATTACH_URL, attach.file_id, attach.file_extension, attach.file_title, ) + for attachment in value: + html += u'%s
' % (settings.LIAISON_ATTACH_URL, conditional_escape(attachment.external_url), conditional_escape(attachment.title)) else: html += u'No files attached' html += u'
' @@ -88,23 +91,21 @@ class RelatedLiaisonWidget(TextInput): noliaison = 'inline' deselect = 'none' else: - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - from ietf.liaisons.proxy import LiaisonDetailProxy as LiaisonDetail - liaison = LiaisonDetail.objects.get(pk=value) + liaison = LiaisonStatement.objects.get(pk=value) title = liaison.title if not title: - files = liaison.uploads_set.all() - if files: - title = files[0].file_title + attachments = liaison.attachments.all() + if attachments: + title = attachments[0].title else: title = 'Liaison #%s' % liaison.pk noliaison = 'none' deselect = 'inline' - html = u'No liaison selected' % noliaison - html += u'%s' % title - html += u' ' % (name, value) - html += u' ' % reverse('ajax_liaison_list') + html = u'No liaison selected' % conditional_escape(noliaison) + html += u'%s' % conditional_escape(title) + html += u' ' % (conditional_escape(name), conditional_escape(value)) + html += u' ' % urlreverse('ajax_liaison_list') html += u' ' - html += ' ' % name - html += '' % (deselect, name) + html += ' ' % conditional_escape(name) + html += '' % (conditional_escape(deselect), conditional_escape(name)) return mark_safe(html) diff --git a/ietf/mailinglists/tests.py b/ietf/mailinglists/tests.py index 043584ea0..83659a9f6 100644 --- a/ietf/mailinglists/tests.py +++ b/ietf/mailinglists/tests.py @@ -1,38 +1,31 @@ -# Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -# All rights reserved. Contact: Pasi Eronen -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# -# * Neither the name of the Nokia Corporation and/or its -# subsidiary(-ies) nor the names of its contributors may be used -# to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +from django.core.urlresolvers import reverse as urlreverse -from ietf.utils.test_utils import SimpleUrlTestCase +from pyquery import PyQuery + +from ietf.utils.test_utils import TestCase +from ietf.utils.test_data import make_test_data +from ietf.utils.mail import outbox + + +class MailingListTests(TestCase): + def test_groups(self): + draft = make_test_data() + group = draft.group + url = urlreverse("ietf.mailinglists.views.groups") + + # only those with an archive + group.list_archive = "" + group.save() + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + self.assertEqual(len(q(".group-archives a:contains(\"%s\")" % group.acronym)), 0) + + # successful get + group.list_archive = "https://example.com/foo" + group.save() + r = self.client.get(url) + q = PyQuery(r.content) + self.assertEqual(len(q(".group-archives a:contains(\"%s\")" % group.acronym)), 1) -class MailingListsUrlTestCase(SimpleUrlTestCase): - def testUrls(self): - self.doTestUrls(__file__) diff --git a/ietf/mailinglists/testurl.list b/ietf/mailinglists/testurl.list deleted file mode 100644 index 2e9153518..000000000 --- a/ietf/mailinglists/testurl.list +++ /dev/null @@ -1,4 +0,0 @@ -200 /list/wg/ -301 /list/nonwg/ -301 /list/nonwg/update/ -301 /list/request/ diff --git a/ietf/mailinglists/urls.py b/ietf/mailinglists/urls.py index 2787cf30e..9795b63de 100644 --- a/ietf/mailinglists/urls.py +++ b/ietf/mailinglists/urls.py @@ -1,14 +1,9 @@ # Copyright The IETF Trust 2007, All Rights Reserved from django.conf.urls.defaults import patterns -from ietf.idtracker.models import IETFWG -http_archive_wg_queryset = IETFWG.objects.filter(email_archive__startswith='http') - -urlpatterns = patterns('django.views.generic.list_detail', - (r'^wg/$', 'object_list', { 'queryset': http_archive_wg_queryset, 'template_name': 'mailinglists/wgwebmail_list.html' }), -) -urlpatterns += patterns('', +urlpatterns = patterns('', + (r'^wg/$', 'ietf.mailinglists.views.groups'), (r'^nonwg/$', 'django.views.generic.simple.redirect_to', { 'url': 'http://www.ietf.org/list/nonwg.html'}), (r'^nonwg/update/$', 'django.views.generic.simple.redirect_to', { 'url': 'http://www.ietf.org/list/nonwg.html'}), (r'^request/$', 'django.views.generic.simple.redirect_to', { 'url': 'http://www.ietf.org/list/request.html' }), diff --git a/ietf/mailinglists/views.py b/ietf/mailinglists/views.py index a4b306690..75cb7335e 100644 --- a/ietf/mailinglists/views.py +++ b/ietf/mailinglists/views.py @@ -1,2 +1,12 @@ # Copyright The IETF Trust 2007, All Rights Reserved +from ietf.group.models import Group +from django.shortcuts import render_to_response +from django.template import RequestContext + +def groups(request): + groups = Group.objects.filter(type__in=("wg", "rg"), list_archive__startswith='http').order_by("acronym") + + return render_to_response("mailinglists/group_archives.html", { "groups": groups }, + context_instance=RequestContext(request)) + diff --git a/ietf/meeting/ajax.py b/ietf/meeting/ajax.py index 418065160..f9800451f 100644 --- a/ietf/meeting/ajax.py +++ b/ietf/meeting/ajax.py @@ -1,18 +1,14 @@ - from django.utils import simplejson as json -from dajaxice.decorators import dajaxice_register from django.core.urlresolvers import reverse from django.shortcuts import get_object_or_404 - -from ietf.ietfauth.decorators import group_required, has_role -from ietf.name.models import TimeSlotTypeName from django.http import HttpResponseRedirect, HttpResponse, QueryDict +from dajaxice.decorators import dajaxice_register +from ietf.ietfauth.utils import role_required, has_role +from ietf.name.models import TimeSlotTypeName + from ietf.meeting.helpers import get_meeting, get_schedule, get_schedule_by_id, agenda_permissions from ietf.meeting.views import edit_timeslots, edit_agenda - - -# New models from ietf.meeting.models import TimeSlot, Session, Schedule, Room, Constraint import debug @@ -50,7 +46,7 @@ def readonly(request, meeting_num, schedule_id): 'owner_href': request.build_absolute_uri(schedule.owner.json_url()), 'read_only': read_only}) -@group_required('Area Director','Secretariat') +@role_required('Area Director','Secretariat') @dajaxice_register def update_timeslot_pinned(request, schedule_id, scheduledsession_id, pinned=False): schedule = get_object_or_404(Schedule, pk = int(schedule_id)) @@ -73,7 +69,7 @@ def update_timeslot_pinned(request, schedule_id, scheduledsession_id, pinned=Fal -@group_required('Area Director','Secretariat') +@role_required('Area Director','Secretariat') @dajaxice_register def update_timeslot(request, schedule_id, session_id, scheduledsession_id=None, extended_from_id=None, duplicate=False): schedule = get_object_or_404(Schedule, pk = int(schedule_id)) @@ -132,7 +128,7 @@ def update_timeslot(request, schedule_id, session_id, scheduledsession_id=None, return json.dumps({'message':'valid'}) -@group_required('Secretariat') +@role_required('Secretariat') @dajaxice_register def update_timeslot_purpose(request, timeslot_id=None, purpose=None): ts_id = int(timeslot_id) @@ -167,10 +163,8 @@ def timeslot_roomlist(request, mtg): return HttpResponse(json.dumps(json_array), mimetype="application/json") -@group_required('Secretariat') +@role_required('Secretariat') def timeslot_addroom(request, meeting): - # authorization was enforced by the @group_require decorator above. - newroomform = AddRoomForm(request.POST) if not newroomform.is_valid(): return HttpResponse(status=404) @@ -188,9 +182,8 @@ def timeslot_addroom(request, meeting): return HttpResponseRedirect( reverse(edit_timeslots, args=[meeting.number])) -@group_required('Secretariat') +@role_required('Secretariat') def timeslot_delroom(request, meeting, roomid): - # authorization was enforced by the @group_require decorator above. room = get_object_or_404(meeting.room_set, pk=roomid) room.delete_timeslots() @@ -235,10 +228,8 @@ def timeslot_slotlist(request, mtg): return HttpResponse(json.dumps(json_array), mimetype="application/json") -@group_required('Secretariat') +@role_required('Secretariat') def timeslot_addslot(request, meeting): - - # authorization was enforced by the @group_require decorator above. addslotform = AddSlotForm(request.POST) #debug.log("newslot: %u" % ( addslotform.is_valid() )) if not addslotform.is_valid(): @@ -261,9 +252,8 @@ def timeslot_addslot(request, meeting): return HttpResponseRedirect( reverse(edit_timeslots, args=[meeting.number])) -@group_required('Secretariat') +@role_required('Secretariat') def timeslot_delslot(request, meeting, slotid): - # authorization was enforced by the @group_require decorator above. slot = get_object_or_404(meeting.timeslot_set, pk=slotid) # this will delete self as well. @@ -301,7 +291,7 @@ def timeslot_sloturl(request, num=None, slotid=None): AgendaEntryForm = modelform_factory(Schedule, exclude=('meeting','owner')) EditAgendaEntryForm = modelform_factory(Schedule, exclude=('meeting','owner', 'name')) -@group_required('Area Director','Secretariat') +@role_required('Area Director','Secretariat') def agenda_list(request, mtg): agendas = mtg.schedule_set.all() json_array=[] @@ -311,10 +301,8 @@ def agenda_list(request, mtg): mimetype="application/json") # duplicates save-as functionality below. -@group_required('Area Director','Secretariat') +@role_required('Area Director','Secretariat') def agenda_add(request, meeting): - # authorization was enforced by the @group_require decorator above. - newagendaform = AgendaEntryForm(request.POST) if not newagendaform.is_valid(): return HttpResponse(status=404) @@ -332,10 +320,8 @@ def agenda_add(request, meeting): return HttpResponseRedirect( reverse(edit_agenda, args=[meeting.number, newagenda.name])) -@group_required('Area Director','Secretariat') +@role_required('Area Director','Secretariat') def agenda_update(request, meeting, schedule): - # authorization was enforced by the @group_require decorator above. - # forms are completely useless for update actions that want to # accept a subset of values. update_dict = QueryDict(request.raw_post_data, encoding=request._encoding) @@ -380,7 +366,7 @@ def agenda_update(request, meeting, schedule): return HttpResponseRedirect( reverse(edit_agenda, args=[meeting.number, schedule.name])) -@group_required('Secretariat') +@role_required('Secretariat') def agenda_del(request, meeting, schedule): schedule.delete_scheduledsessions() #debug.log("deleting meeting: %s agenda: %s" % (meeting, meeting.agenda)) @@ -427,10 +413,8 @@ def meeting_get(request, meeting): sort_keys=True, indent=2), mimetype="application/json") -@group_required('Secretariat') +@role_required('Secretariat') def meeting_update(request, meeting): - # authorization was enforced by the @group_require decorator above. - # at present, only the official agenda can be updated from this interface. update_dict = QueryDict(request.raw_post_data, encoding=request._encoding) diff --git a/ietf/meeting/feeds.py b/ietf/meeting/feeds.py new file mode 100644 index 000000000..9c093f033 --- /dev/null +++ b/ietf/meeting/feeds.py @@ -0,0 +1,43 @@ +import re, os, datetime + +from django.contrib.syndication.feeds import Feed +from django.utils.feedgenerator import Atom1Feed +from django.conf import settings + +from ietf.doc.models import Document + +class LatestMeetingMaterial(Feed): + feed_type = Atom1Feed + link = "/meeting/" + language = "en" + feed_url = "/feed/wg-proceedings/" + base_url = "http://www3.ietf.org/proceedings/" + + def items(self): + objs = [] + for doc in Document.objects.filter(type__in=("agenda", "minutes", "slides")).order_by('-time')[:60]: + obj = dict( + title=doc.type_id, + group_acronym=doc.name.split("-")[2], + date=doc.time, + link=self.base_url + os.path.join(doc.get_file_path(), doc.external_url)[len(settings.AGENDA_PATH):], + author="" + ) + objs.append(obj) + + return objs + + def title(self, obj): + return "Meeting Materials Activity" + + def item_link(self, item): + return item['link'] + + def item_pubdate(self, item): + return item['date'] + + def item_author_name(self, item): + return item['author'] + + def item_author_email(self, item): + return None diff --git a/ietf/meeting/helpers.py b/ietf/meeting/helpers.py index 4b0948228..c1ef76e03 100644 --- a/ietf/meeting/helpers.py +++ b/ietf/meeting/helpers.py @@ -1,26 +1,23 @@ # Copyright The IETF Trust 2007, All Rights Reserved -#import models import datetime import os +import pytz + from django.http import Http404 from django.http import HttpRequest from django.db.models import Max, Q from django.conf import settings from django.core.cache import cache from django.utils.cache import get_cache_key +from django.shortcuts import get_object_or_404 import debug -from django.shortcuts import get_object_or_404 -from ietf.ietfauth.decorators import has_role +from ietf.ietfauth.utils import has_role from ietf.utils.history import find_history_active_at from ietf.doc.models import Document, State - -from ietf.proceedings.models import Meeting as OldMeeting, MeetingTime, IESGHistory, Switches - -# New models from ietf.meeting.models import Meeting from ietf.group.models import Group @@ -37,70 +34,17 @@ def find_ads_for_meeting(meeting): if history and history != g: #print " history[%u]: %s" % (num, history) if history.state_id == "active": - for x in history.rolehistory_set.filter(name="ad").select_related(): + for x in history.rolehistory_set.filter(name="ad").select_related('group', 'person', 'email'): #print "xh[%u]: %s" % (num, x) - ads.append(IESGHistory().from_role(x, meeting_time)) + ads.append(x) else: #print " group[%u]: %s" % (num, g) if g.state_id == "active": - for x in g.role_set.filter(name="ad").select_related('group', 'person'): + for x in g.role_set.filter(name="ad").select_related('group', 'person', 'email'): #print "xg[%u]: %s (#%u)" % (num, x, x.pk) - ads.append(IESGHistory().from_role(x, meeting_time)) + ads.append(x) return ads -def agenda_info(num=None): - try: - if num != None: - meeting = OldMeeting.objects.get(number=num) - else: - meeting = OldMeeting.objects.all().order_by('-date')[:1].get() - except OldMeeting.DoesNotExist: - raise Http404("No meeting information for meeting %s available" % num) - - # now go through the timeslots, only keeping those that are - # sessions/plenary/training and don't occur at the same time - timeslots = [] - time_seen = set() - for t in MeetingTime.objects.filter(meeting=meeting, type__in=("session", "plenary", "other")).order_by("time").select_related(): - if not t.time in time_seen: - time_seen.add(t.time) - timeslots.append(t) - - update = Switches().from_object(meeting) - venue = meeting.meeting_venue - - ads = [] - meeting_time = datetime.datetime.combine(meeting.date, datetime.time(0, 0, 0)) - for g in Group.objects.filter(type="area").order_by("acronym"): - history = find_history_active_at(g, meeting_time) - if history and history != g: - if history.state_id == "active": - ads.extend(IESGHistory().from_role(x, meeting_time) for x in history.rolehistory_set.filter(name="ad").select_related()) - else: - if g.state_id == "active": - ads.extend(IESGHistory().from_role(x, meeting_time) for x in g.role_set.filter(name="ad").select_related('group', 'person')) - - active_agenda = State.objects.get(used=True, type='agenda', slug='active') - plenary_agendas = Document.objects.filter(session__meeting=meeting, session__slots__type="plenary", type="agenda", ).distinct() - plenaryw_agenda = plenaryt_agenda = "The agenda has not been uploaded yet." - for agenda in plenary_agendas: - if active_agenda in agenda.states.all(): - # we use external_url at the moment, should probably regularize - # the filenames to match the document name instead - path = os.path.join(settings.AGENDA_PATH, meeting.number, "agenda", agenda.external_url) - try: - f = open(path) - s = f.read() - f.close() - except IOError: - s = "No agenda file found." - - if "tech" in agenda.name.lower(): - plenaryt_agenda = s - else: - plenaryw_agenda = s - - return timeslots, update, meeting, venue, ads, plenaryw_agenda, plenaryt_agenda # get list of all areas, + IRTF + IETF (plenaries). def get_pseudo_areas(): @@ -169,7 +113,7 @@ def get_wg_list(scheduledsessions): def get_meeting(num=None): - if (num == None): + if num == None: meeting = Meeting.objects.filter(type="ietf", agenda__isnull=False).order_by("-date")[:1].get() else: meeting = get_object_or_404(Meeting, number=num) @@ -189,6 +133,13 @@ def get_schedule_by_id(meeting, schedid): schedule = get_object_or_404(meeting.schedule_set, id=int(schedid)) return schedule +def meeting_updated(meeting): + ts = max(meeting.timeslot_set.aggregate(Max('modified'))["modified__max"] or datetime.datetime.min, + meeting.session_set.aggregate(Max('modified'))["modified__max"] or datetime.datetime.min) + tz = pytz.timezone(settings.PRODUCTION_TIMEZONE) + ts = tz.localize(ts) + return ts + def agenda_permissions(meeting, schedule, user): # do this in positive logic. cansee = False diff --git a/ietf/meeting/models.py b/ietf/meeting/models.py index 59ae9ab2a..c8e96d9eb 100644 --- a/ietf/meeting/models.py +++ b/ietf/meeting/models.py @@ -1056,7 +1056,7 @@ class Session(models.Model): with open(path) as f: return f.read() else: - "No agenda file found" + return "No agenda file found" else: return "The agenda has not been uploaded yet." diff --git a/ietf/meeting/proxy.py b/ietf/meeting/proxy.py deleted file mode 100644 index 576dfc638..000000000 --- a/ietf/meeting/proxy.py +++ /dev/null @@ -1,547 +0,0 @@ -import datetime - -from django.conf import settings - -from ietf.utils.proxy import TranslatingManager -from models import * - -import debug - -class MeetingProxy(Meeting): - objects = TranslatingManager(dict(meeting_num="number"), always_filter=dict(type="ietf")) - - def from_object(self, base): - for f in base._meta.fields: - setattr(self, f.name, getattr(base, f.name)) - return self - - #meeting_num = models.IntegerField(primary_key=True) - @property - def meeting_num(self): - return self.number - #start_date = models.DateField() - @property - def start_date(self): - return self.date - #end_date = models.DateField() - @property - def end_date(self): - return self.date + datetime.timedelta(days=5) - - #city = models.CharField(blank=True, max_length=255) - #state = models.CharField(blank=True, max_length=255) - #country = models.CharField(blank=True, max_length=255) - #time_zone = models.IntegerField(null=True, blank=True, choices=TIME_ZONE_CHOICES) - #ack = models.TextField(blank=True) - #agenda_html = models.TextField(blank=True) - #agenda_text = models.TextField(blank=True) - #future_meeting = models.TextField(blank=True) - #overview1 = models.TextField(blank=True) - #overview2 = models.TextField(blank=True) - def __str__(self): - return "IETF-%s" % (self.meeting_num) - def get_meeting_date (self,offset): - return self.start_date + datetime.timedelta(days=offset) - def num(self): - return self.number - - @property - def meeting_venue(self): - return MeetingVenueProxy().from_object(self) - - @classmethod - def get_first_cut_off(cls): - start_date = cls.objects.all().order_by('-date')[0].start_date - offset = datetime.timedelta(days=settings.FIRST_CUTOFF_DAYS) - return start_date - offset - - @classmethod - def get_second_cut_off(cls): - start_date = cls.objects.all().order_by('-date')[0].start_date - offset = datetime.timedelta(days=settings.SECOND_CUTOFF_DAYS) - return start_date - offset - - @classmethod - def get_ietf_monday(cls): - start_date = cls.objects.all().order_by('-date')[0].start_date - return start_date + datetime.timedelta(days=-start_date.weekday(), weeks=1) - - class Meta: - proxy = True - -class ProceedingProxy(Meeting): - objects = TranslatingManager(dict(meeting_num="number")) - - #meeting_num = models.ForeignKey(Meeting, db_column='meeting_num', unique=True, primary_key=True) - @property - def meeting_num(self): - return MeetingProxy().from_object(self) - @property - def meeting_num_id(self): - return self.number - #dir_name = models.CharField(blank=True, max_length=25) - @property - def dir_name(self): - return self.number - #sub_begin_date = models.DateField(null=True, blank=True) - @property - def sub_begin_date(self): - return self.get_submission_start_date() - #sub_cut_off_date = models.DateField(null=True, blank=True) - @property - def sub_cut_off_date(self): - return self.get_submission_cut_off_date() - #frozen = models.IntegerField(null=True, blank=True) - #c_sub_cut_off_date = models.DateField(null=True, blank=True) - @property - def c_sub_cut_off_date(self): - return self.get_submission_correction_date() - #pr_from_date = models.DateField(null=True, blank=True) - #pr_to_date = models.DateField(null=True, blank=True) - def __str__(self): - return "IETF %s" % (self.meeting_num_id) - class Meta: - proxy = True - -class SwitchesProxy(Meeting): - def from_object(self, base): - for f in base._meta.fields: - setattr(self, f.name, getattr(base, f.name)) - return self - - #name = models.CharField(max_length=100) - #val = models.IntegerField(null=True, blank=True) - #updated_date = models.DateField(null=True, blank=True) - #updated_time = models.TimeField(null=True, blank=True) - def updated(self): - from django.db.models import Max - import pytz - now = datetime.datetime.now() - ts = max(self.timeslot_set.aggregate(Max('modified'))["modified__max"] or now, - self.session_set.aggregate(Max('modified'))["modified__max"] or now) - tz = pytz.timezone(settings.PRODUCTION_TIMEZONE) - ts = tz.localize(ts) - return ts - class Meta: - proxy = True - -class MeetingVenueProxy(Meeting): - objects = TranslatingManager(dict(meeting_num="number")) - - def from_object(self, base): - for f in base._meta.fields: - setattr(self, f.name, getattr(base, f.name)) - return self - - #meeting_num = models.ForeignKey(Meeting, db_column='meeting_num', unique=True) - @property - def meeting_num(self): - return self.number - #break_area_name = models.CharField(max_length=255) - @property - def break_area_name(self): - return self.break_area - #reg_area_name = models.CharField(max_length=255) - @property - def reg_area_name(self): - return self.reg_area - - def __str__(self): - return "IETF %s" % (self.meeting_num) - - class Meta: - proxy = True - -class MeetingTimeProxy(TimeSlot): - # the old MeetingTimes did not include a room, so there we can't - # do a proper mapping - instead this proxy is one TimeSlot and - # uses the information in that to emulate a MeetingTime and enable - # retrieval of the other related TimeSlots - objects = TranslatingManager(dict(day_id="time", time_desc="time")) - - def from_object(self, base): - for f in base._meta.fields: - setattr(self, f.name, getattr(base, f.name)) - return self - - #time_id = models.AutoField(primary_key=True) - @property - def time_id(self): - return self.pk - #time_desc = models.CharField(max_length=100) - @property - def time_desc(self): - return u"%s-%s" % (self.time.strftime("%H%M"), (self.time + self.duration).strftime("%H%M")) - #meeting = models.ForeignKey(Meeting, db_column='meeting_num') # same name - #day_id = models.IntegerField() - @property - def day_id(self): - return (self.time.date() - self.meeting.date).days - #session_name = models.ForeignKey(SessionName,null=True) - @property - def session_name(self): - if self.type_id not in ("session", "plenary"): - return None - - class Dummy(object): - def __unicode__(self): - return self.session_name - d = Dummy() - d.session_name = self.name - return d - def __str__(self): - return "[%s] |%s| %s" % (self.meeting.number, self.time.strftime('%A'), self.time_desc) - def sessions(self): - if not hasattr(self, "_sessions_cache"): - self._sessions_cache = WgMeetingSessionProxy.objects.filter(meeting=self.meeting, time=self.time, type__in=("session", "plenary", "other"), scheduledsession__schedule=self.meeting.agenda, sessions__isnull=False).distinct() - return self._sessions_cache - def sessions_by_area(self): - return [ {"area":session.area()+session.acronym(), "info":session} for session in self.sessions() ] - def meeting_date(self): - return self.time.date() - def registration(self): - if not hasattr(self, '_reg_info'): - try: - self._reg_info = MeetingTimeProxy.objects.get(meeting=self.meeting, time__month=self.time.month, time__day=self.time.day, type="reg") - except MeetingTimeProxy.DoesNotExist: - self._reg_info = None - return self._reg_info - def reg_info(self): - reg_info = self.registration() - if reg_info and reg_info.time_desc: - return "%s %s" % (reg_info.time_desc, reg_info.name) - else: - return "" - def break_info(self): - breaks = MeetingTimeProxy.objects.filter(meeting=self.meeting, time__month=self.time.month, time__day=self.time.day, type="break").order_by("time") - for brk in breaks: - if brk.time_desc[-4:] == self.time_desc[:4]: - return brk - return None - def is_plenary(self): - return self.type_id == "plenary" - - # from NonSession - #non_session_id = models.AutoField(primary_key=True) - @property - def non_session_id(self): - return self.id - #day_id = models.IntegerField(blank=True, null=True) # already wrapped - #non_session_ref = models.ForeignKey(NonSessionRef) - @property - def non_session_ref(self): - return 1 if self.type_id == "reg" else 3 - #meeting = models.ForeignKey(Meeting, db_column='meeting_num') 3 same name - #time_desc = models.CharField(blank=True, max_length=75) # already wrapped - #show_break_location = models.BooleanField() - @property - def show_break_location(self): - return self.show_location - def day(self): - return self.time.strftime("%A") - - class Meta: - proxy = True - -NonSessionProxy = MeetingTimeProxy - -class WgMeetingSessionProxy(TimeSlot): - # we model WgMeetingSession as a TimeSlot, to make the illusion - # complete we thus have to forward all the session stuff to the - # real session - objects = TranslatingManager(dict(group_acronym_id="session__group", - status__id=lambda v: ("state", {4: "sched"}[v]))) - - def from_object(self, base): - for f in base._meta.fields: - setattr(self, f.name, getattr(base, f.name)) - return self - - #session_id = models.AutoField(primary_key=True) # same name - #meeting = models.ForeignKey(Meeting, db_column='meeting_num') # same name - #group_acronym_id = models.IntegerField() - @property - def group_acronym_id(self): - return self.session.group_id if self.session else -1 - #irtf = models.NullBooleanField() - @property - def irtf(self): - return 1 if self.session and self.session.group and self.session.group.type == "rg" else 0 - #num_session = models.IntegerField() - @property - def num_session(self): - return 1 if self.session else 0 - #length_session1 = models.CharField(blank=True, max_length=100) - @property - def length_session1(self): - if not self.session: - return "0" - - secs = self.session.requested_duration.seconds - if secs == 0: - return "0" - return str((secs / 60 - 30) / 30) - #length_session2 = models.CharField(blank=True, max_length=100) - @property - def length_session2(self): - return "0" - #length_session3 = models.CharField(blank=True, max_length=100) - @property - def length_session3(self): - return "0" - - def conflicting_group_acronyms(self, level): - if not self.session: - return "" - - conflicts = Constraint.objects.filter(meeting=self.meeting_id, - target=self.session.group, - name=level) - return " ".join(c.source.acronym for c in conflicts) - - #conflict1 = models.CharField(blank=True, max_length=255) - @property - def conflict1(self): - return self.conflicting_group_acronyms("conflict") - #conflict2 = models.CharField(blank=True, max_length=255) - @property - def conflict2(self): - return self.conflicting_group_acronyms("conflic2") - #conflict3 = models.CharField(blank=True, max_length=255) - @property - def conflict3(self): - return self.conflicting_group_acronyms("conflic3") - #conflict_other = models.TextField(blank=True) - @property - def conflict_other(self): - return "" - #special_req = models.TextField(blank=True) - @property - def special_req(self): - return self.session.comments if self.session else "" - #number_attendee = models.IntegerField(null=True, blank=True) - @property - def number_attendee(self): - return self.session.attendees if self.session else 0 - #approval_ad = models.IntegerField(null=True, blank=True) - #status = models.ForeignKey(SessionStatus, null=True, blank=True) # same name - #ts_status_id = models.IntegerField(null=True, blank=True) - #requested_date = models.DateField(null=True, blank=True) - @property - def requested_date(self): - return self.session.requested.date() if self.session else None - #approved_date = models.DateField(null=True, blank=True) - #requested_by = BrokenForeignKey(PersonOrOrgInfo, db_column='requested_by', null=True, null_values=(0, 888888)) - @property - def requested_by(self): - return self.session.requested_by if self.session else None - #scheduled_date = models.DateField(null=True, blank=True) - @property - def scheduled_date(self): - return self.session.scheduled.date() if self.session else "" - #last_modified_date = models.DateField(null=True, blank=True) - @property - def last_modified_date(self): - return self.session.modified.date() if self.session else "" - #ad_comments = models.TextField(blank=True,null=True) - #sched_room_id1 = models.ForeignKey(MeetingRoom, db_column='sched_room_id1', null=True, blank=True, related_name='here1') - #sched_time_id1 = BrokenForeignKey(MeetingTime, db_column='sched_time_id1', null=True, blank=True, related_name='now1') - #sched_date1 = models.DateField(null=True, blank=True) - #sched_room_id2 = models.ForeignKey(MeetingRoom, db_column='sched_room_id2', null=True, blank=True, related_name='here2') - #sched_time_id2 = BrokenForeignKey(MeetingTime, db_column='sched_time_id2', null=True, blank=True, related_name='now2') - #sched_date2 = models.DateField(null=True, blank=True) - #sched_room_id3 = models.ForeignKey(MeetingRoom, db_column='sched_room_id3', null=True, blank=True, related_name='here3') - #sched_time_id3 = BrokenForeignKey(MeetingTime, db_column='sched_time_id3', null=True, blank=True, related_name='now3') - #sched_date3 = models.DateField(null=True, blank=True) - #special_agenda_note = models.CharField(blank=True, max_length=255) - @property - def special_agenda_note(self): - return self.session.agenda_note if self.session else "" - #combined_room_id1 = models.ForeignKey(MeetingRoom, db_column='combined_room_id1', null=True, blank=True, related_name='here4') - #combined_time_id1 = models.ForeignKey(MeetingTime, db_column='combined_time_id1', null=True, blank=True, related_name='now4') - #combined_room_id2 = models.ForeignKey(MeetingRoom, db_column='combined_room_id2', null=True, blank=True, related_name='here5') - #combined_time_id2 = models.ForeignKey(MeetingTime, db_column='combined_time_id2', null=True, blank=True, related_name='now5') - def __str__(self): - return "%s at %s" % (self.acronym(), self.meeting) - def agenda_file(self,interimvar=0): - if not hasattr(self, '_agenda_file'): - self._agenda_file = "" - - if not self.session: - return "" - - docs = self.session.materials.filter(type="agenda", states__type="agenda", states__slug="active") - if not docs: - return "" - - # we use external_url at the moment, should probably regularize - # the filenames to match the document name instead - filename = docs[0].external_url - self._agenda_file = "%s/agenda/%s" % (self.meeting.number, filename) - - return self._agenda_file - def minute_file(self,interimvar=0): - if not self.session: - return "" - - docs = self.session.materials.filter(type="minutes", states__type="minutes", states__slug="active") - if not docs: - return "" - - # we use external_url at the moment, should probably regularize - # the filenames to match the document name instead - filename = docs[0].external_url - return "%s/minutes/%s" % (self.meeting.number, filename) - def slides(self,interimvar=0): - return SlideProxy.objects.filter(session__slots=self).order_by("order") - def interim_meeting(self): - return False - def length_session1_desc(self): - l = self.length_session1 - return { "0": "", "1": "1 hour", "2": "1.5 hours", "3": "2 hours", "4": "2.5 hours"}[l] - def length_session2_desc(self): - return "" - def length_session3_desc(self): - return "" - - @property - def ordinality(self): - return 1 - - @property - def room_id(self): - class Dummy: pass - d = Dummy() - d.room_name = self.location.name - return d - - # from ResolveAcronym: - def acronym(self): - if self.type_id == "plenary": - if "Operations and Administration" in self.name: - return "plenaryw" - if "Technical" in self.name: - return "plenaryt" - for m in self.materials.filter(type="agenda", states__type="agenda", states__slug="active"): - if "plenaryw" in m.name: - return "plenaryw" - if "plenaryt" in m.name: - return "plenaryt" - if not self.session: - return "%s" % self.pk - if hasattr(self, "interim"): - return "i" + self.session.group.acronym - else: - return self.session.group.acronym - def acronym_lower(self): - return self.acronym().lower() - def acronym_name(self): - if not self.session: - return self.name - if hasattr(self, "interim"): - return self.session.group.name + " (interim)" - elif self.session.name: - return self.session.name - else: - return self.session.group.name - def area(self): - if not self.session or not self.session.group: - return "" - if self.session.group.type_id == "irtf": - return "irtf" - if self.type_id == "plenary": - return "1plenary" - if not self.session.group.parent or not self.session.group.parent.type_id in ["area","irtf","ietf"]: - return "" - return self.session.group.parent.acronym - def area_name(self): - if self.type_id == "plenary": - return "Plenary Sessions" - elif self.session and self.session.group and self.session.group.acronym == "edu": - return "Training" - elif not self.session or not self.session.group or not self.session.group.parent or not self.session.group.parent.type_id == "area": - return "" - return self.session.group.parent.name - def isWG(self): - if not self.session or not self.session.group: - return False - if self.session.group.type_id == "wg" and self.session.group.state_id != "bof": - return True - def group_type_str(self): - if not self.session or not self.session.group: - return "" - if self.session.group and self.session.group.type_id == "wg": - if self.session.group.state_id in ["bof", "bof-conc" ]: - return "BOF" - else: - return "WG" - - return "" - - class Meta: - proxy = True - -class SlideProxy(Document): - objects = TranslatingManager(dict(), always_filter=dict(type="slides")) - - SLIDE_TYPE_CHOICES=( - ('1', '(converted) HTML'), - ('2', 'PDF'), - ('3', 'Text'), - ('4', 'PowerPoint -2003 (PPT)'), - ('5', 'Microsoft Word'), - ('6', 'PowerPoint 2007- (PPTX)'), - ) - #meeting = models.ForeignKey(Meeting, db_column='meeting_num') - @property - def meeting_id(self): - return self.name.split("-")[1] - #group_acronym_id = models.IntegerField(null=True, blank=True) - #slide_num = models.IntegerField(null=True, blank=True) - @property - def slide_num(self): - return int(self.name.split("-")[3]) - #slide_type_id = models.IntegerField(choices=SLIDE_TYPE_CHOICES) - #slide_name = models.CharField(blank=True, max_length=255) - @property - def slide_name(self): - return self.title - #irtf = models.IntegerField() - #interim = models.BooleanField() - #order_num = models.IntegerField(null=True, blank=True) - @property - def order_num(self): - return self.order - #in_q = models.IntegerField(null=True, blank=True) - def acronym(): - return self.name.split("-")[2] - def __str__(self): - return "IETF%d: %s slides (%s)" % (self.meeting_id, self.acronym(), self.slide_name) - def file_loc(self): - return "%s/slides/%s" % (self.meeting_id, self.external_url) - class Meta: - proxy = True - -class IESGHistoryProxy(Person): - def from_object(self, base): - for f in self._meta.fields: # self here to enable us to copy a history object - setattr(self, f.name, getattr(base, f.name)) - return self - - #meeting = models.ForeignKey(Meeting, db_column='meeting_num') - def from_role(self, role, time): - from ietf.utils.history import find_history_active_at - personhistory = find_history_active_at(role.person, time) - self.from_object(personhistory or role.person) - from ietf.group.proxy import Area - self.area = Area().from_object(role.group) - return self - #area = models.ForeignKey(Area, db_column='area_acronym_id') - #person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag') - @property - def person(self): - return self - #def __str__(self): - # return "IESG%s: %s (%s)" % (self.meeting_id, self.person,self.area) - class Meta: - proxy = True diff --git a/ietf/meeting/tests/__init__.py b/ietf/meeting/tests/__init__.py index f51192e9f..af03b672c 100644 --- a/ietf/meeting/tests/__init__.py +++ b/ietf/meeting/tests/__init__.py @@ -4,10 +4,6 @@ The test cases are split into multiple files. """ -import sys -from ietf.utils import TestCase -from datetime import datetime - # actual tests are distributed among a set of files in subdir tests/ from ietf.meeting.tests.meetingurls import MeetingUrlTestCase from ietf.meeting.tests.agenda import AgendaInfoTestCase diff --git a/ietf/meeting/tests/agenda-83-utc.html.good b/ietf/meeting/tests/agenda-83-utc.html.good index 294bf85a8..046edad6e 100644 --- a/ietf/meeting/tests/agenda-83-utc.html.good +++ b/ietf/meeting/tests/agenda-83-utc.html.good @@ -3,7 +3,7 @@ - + IETF 83 Meeting Agenda - DEVELOPMENT MODE @@ -101,7 +101,7 @@ img.hidden { display: none; }
- +
    @@ -115,8 +115,7 @@ img.hidden { display: none; } - -
  • Working Groups
  • +
  • Working Groups
    • @@ -326,7 +325,7 @@ img.hidden { display: none; }
    -Version 4.84-dev, 2013-11-06 +Version 4.85-dev, 2013-12-16
    Report a bug diff --git a/ietf/meeting/tests/agenda-83.html.good b/ietf/meeting/tests/agenda-83.html.good index b019c22b6..89a8aec8f 100644 --- a/ietf/meeting/tests/agenda-83.html.good +++ b/ietf/meeting/tests/agenda-83.html.good @@ -3,7 +3,7 @@ - + IETF 83 Meeting Agenda - DEVELOPMENT MODE @@ -105,7 +105,7 @@ img.hidden { display: none; }
    - +
      @@ -119,8 +119,7 @@ img.hidden { display: none; } - -
    • Working Groups
    • +
    • Working Groups
      • @@ -330,7 +329,7 @@ img.hidden { display: none; }
      -Version 4.84-dev, 2013-11-06 +Version 4.85-dev, 2013-12-16
      Report a bug diff --git a/ietf/meeting/tests/agenda.py b/ietf/meeting/tests/agenda.py index a8d513b5f..9d67bf2ab 100644 --- a/ietf/meeting/tests/agenda.py +++ b/ietf/meeting/tests/agenda.py @@ -1,5 +1,5 @@ import sys -from django.test import Client + from ietf.meeting.tests.ttest import AgendaTransactionalTestCase from ietf.utils import TestCase from ietf.name.models import SessionStatusName @@ -12,8 +12,7 @@ import debug class AgendaInfoTestCase(TestCase): # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = [ 'names.xml', # ietf/names/fixtures/names.xml for MeetingTypeName, and TimeSlotTypeName - 'meeting83.json', + perma_fixtures = [ 'meeting83.json', 'constraint83.json', 'workinggroups.json', 'groupgroup.json', @@ -27,30 +26,6 @@ class AgendaInfoTestCase(TestCase): s1 = m1.session_set.create(name = "newone", group = g1, requested_by = p1, status = st1) self.assertEqual(s1.__unicode__(), "IETF-83: pkix (unscheduled)[22090]") - def test_AgendaInfo(self): - from ietf.meeting.views import agenda_info - num = '83' - timeslots, update, meeting, venue, ads, plenaryw_agenda, plenaryt_agenda = agenda_info(num) - # I think that "timeslots" here, is unique times, not actually - # the timeslots array itself. - self.assertEqual(len(timeslots),26) - self.assertEqual(meeting.number,'83') - self.assertEqual(venue.meeting_num, "83") - # will change as more ADs are added to fixtures - self.assertEqual(len(ads), 8) - - def test_AgendaInfoReturnsSortedTimeSlots(self): - from ietf.meeting.views import agenda_info - num = '83' - timeslots, update, meeting, venue, ads, plenaryw_agenda, plenaryt_agenda = agenda_info(num) - for slotnum in range(0,len(timeslots)-1): - # debug - #sys.stdout.write("%d: %s vs %d: %s\n" % (timeslots[slotnum].pk, - # timeslots[slotnum].time, - # timeslots[slotnum+1].pk, - # timeslots[slotnum+1].time)) - self.assertTrue(timeslots[slotnum].time < timeslots[slotnum+1].time) - # this tests that a slot at 11:20 AM on Friday, has slot 10 minutes later # after it def test_TimeSlot2408_has_SlotToTheRight(self): @@ -69,17 +44,6 @@ class AgendaInfoTestCase(TestCase): ss2418 = ScheduledSession.objects.get(pk = 2418) self.assertFalse(ss2418.slot_to_the_right) - def test_AgendaInfoNotFound(self): - from django.http import Http404 - from ietf.meeting.views import agenda_info - num = '83b' - try: - timeslots, update, meeting, venue, ads, plenaryw_agenda, plenaryt_agenda = agenda_info(num) - # fail!!! - self.assertFalse(True) - except Http404: - pass - def test_DoNotGetSchedule(self): from django.http import Http404 num = '83' diff --git a/ietf/meeting/tests/api.py b/ietf/meeting/tests/api.py index bbcaa152a..547970d02 100644 --- a/ietf/meeting/tests/api.py +++ b/ietf/meeting/tests/api.py @@ -1,21 +1,20 @@ import base64 import sys, datetime -from django.test import Client -from ietf.utils import TestCase +import json +from ietf.utils import TestCase from ietf.person.models import Person from django.contrib.auth.models import User from ietf.meeting.models import TimeSlot, Session, ScheduledSession, Meeting -from ietf.ietfauth.decorators import has_role +from ietf.ietfauth.utils import has_role from auths import auth_joeblow, auth_wlo, auth_ietfchair, auth_ferrel -from django.utils import simplejson as json from ietf.meeting.helpers import get_meeting import debug class ApiTestCase(TestCase): # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = [ 'names.xml', # ietf/names/fixtures/names.xml for MeetingTypeName, and TimeSlotTypeName + perma_fixtures = [ 'meeting83.json', 'constraint83.json', 'workinggroups.json', @@ -175,7 +174,7 @@ class ApiTestCase(TestCase): resp = self.client.get("/meeting/83/session/%u/constraints.json" % (clue83.pk)) conflicts = json.loads(resp.content) self.assertNotEqual(conflicts, None) - self.assertEqual(len(conflicts), 39) + self.assertEqual(len(conflicts), 36) def test_getMeetingInfoJson(self): resp = self.client.get('/meeting/83.json') diff --git a/ietf/meeting/tests/auths.py b/ietf/meeting/tests/auths.py index 6dda45e80..c3921a20b 100644 --- a/ietf/meeting/tests/auths.py +++ b/ietf/meeting/tests/auths.py @@ -1,9 +1,7 @@ -import sys -from django.test import Client from ietf.utils import TestCase #from ietf.person.models import Person from django.contrib.auth.models import User -from ietf.ietfauth.decorators import has_role +from ietf.ietfauth.utils import has_role # from http://djangosnippets.org/snippets/850/ @@ -20,7 +18,7 @@ auth_ferrel = {'REMOTE_USER':'stephen.farrell@cs.tcd.ie'} class AuthDataTestCase(TestCase): # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = [ 'names.xml', # ietf/names/fixtures/names.xml for MeetingTypeName, and TimeSlotTypeName + perma_fixtures = [ 'meeting83.json', 'constraint83.json', 'workinggroups.json', diff --git a/ietf/meeting/tests/edit.py b/ietf/meeting/tests/edit.py index 0fdf10cca..e5771aa06 100644 --- a/ietf/meeting/tests/edit.py +++ b/ietf/meeting/tests/edit.py @@ -1,19 +1,15 @@ import re -import sys -from settings import BASE_DIR -from django.test import Client + +from django.conf import settings from ietf.utils import TestCase -#from ietf.person.models import Person -from django.contrib.auth.models import User -from django.test.client import Client -from ietf.meeting.models import TimeSlot, Session, ScheduledSession +from ietf.meeting.models import TimeSlot, Session, ScheduledSession from auths import auth_joeblow, auth_wlo, auth_ietfchair, auth_ferrel capture_output = False class EditTestCase(TestCase): # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = [ 'names.xml', # ietf/names/fixtures/names.xml for MeetingTypeName, and TimeSlotTypeName + perma_fixtures = [ 'meeting83.json', 'constraint83.json', 'workinggroups.json', @@ -27,7 +23,7 @@ class EditTestCase(TestCase): m = re.search(".*session_obj.*", resp.content) # to capture new output (and check it for correctness) if capture_output: - out = open("%s/meeting/tests/edit_out.html" % BASE_DIR, "w") + out = open("%s/meeting/tests/edit_out.html" % settings.BASE_DIR, "w") out.write(resp.content) out.close() self.assertIsNotNone(m) diff --git a/ietf/meeting/tests/urlgen.py b/ietf/meeting/tests/urlgen.py index 7c1624d3a..c179df0a3 100644 --- a/ietf/meeting/tests/urlgen.py +++ b/ietf/meeting/tests/urlgen.py @@ -1,11 +1,5 @@ -import base64 -import sys -from urlparse import urljoin - -from django.test import Client from ietf.utils import TestCase -from django.contrib.auth.models import User from ietf.person.models import Person from ietf.meeting.models import Meeting, TimeSlot, Session, ScheduledSession from ietf.meeting.models import Constraint @@ -14,7 +8,7 @@ from ietf.group.models import Group class UrlGenTestCase(TestCase): # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = [ 'names.xml', # ietf/names/fixtures/names.xml for MeetingTypeName, and TimeSlotTypeName + perma_fixtures = [ 'meeting83.json', 'constraint83.json', 'workinggroups.json', @@ -23,21 +17,17 @@ class UrlGenTestCase(TestCase): def test_meetingGeneratesUrl(self): mtg83 = Meeting.objects.get(pk=83) - hostport = "http://datatracker.ietf.org" - self.assertEqual(urljoin(hostport, mtg83.json_url()), "http://datatracker.ietf.org/meeting/83.json") + self.assertEqual(mtg83.json_url(), "/meeting/83.json") def test_constraintGeneratesUrl(self): const1 = Constraint.objects.get(pk=21037) - hostport = "http://datatracker.ietf.org" - self.assertEqual(urljoin(hostport, const1.json_url()), "http://datatracker.ietf.org/meeting/83/constraint/21037.json") + self.assertEqual(const1.json_url(), "/meeting/83/constraint/21037.json") def test_groupGeneratesUrl(self): group1 = Group.objects.get(pk=1730) - hostport = "http://datatracker.ietf.org" - self.assertEqual(urljoin(hostport, group1.json_url()), "http://datatracker.ietf.org/group/roll.json") + self.assertEqual(group1.json_url(), "/group/roll.json") def test_sessionGeneratesUrl(self): sess1 = Session.objects.get(pk=22087) - hostport = "http://datatracker.ietf.org" - self.assertEqual(urljoin(hostport, sess1.json_url()), "http://datatracker.ietf.org/meeting/83/session/22087.json") + self.assertEqual(sess1.json_url(), "/meeting/83/session/22087.json") diff --git a/ietf/meeting/tests/view.py b/ietf/meeting/tests/view.py index 000c5efe8..9009f1ac0 100644 --- a/ietf/meeting/tests/view.py +++ b/ietf/meeting/tests/view.py @@ -1,24 +1,21 @@ import re -import sys -from django.test.client import Client + +from django.core.urlresolvers import reverse + from ietf.utils import TestCase -#from ietf.person.models import Person -from django.contrib.auth.models import User -from settings import BASE_DIR from ietf.meeting.models import TimeSlot, Session, ScheduledSession from auths import auth_joeblow, auth_wlo, auth_ietfchair, auth_ferrel from ietf.meeting.helpers import get_meeting -from django.core.urlresolvers import reverse from ietf.meeting.views import edit_agenda class ViewTestCase(TestCase): # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = [ 'names.xml', # ietf/names/fixtures/names.xml for MeetingTypeName, and TimeSlotTypeName - 'meeting83.json', - 'constraint83.json', - 'workinggroups.json', - 'groupgroup.json', - 'person.json', 'users.json' ] + perma_fixtures = [ + 'meeting83', + 'constraint83', + 'workinggroups', + 'groupgroup', + 'person', 'users' ] def test_nameOfClueWg(self): clue_session = Session.objects.get(pk=2194) diff --git a/ietf/meeting/views.py b/ietf/meeting/views.py index ec4763008..234dcccb5 100644 --- a/ietf/meeting/views.py +++ b/ietf/meeting/views.py @@ -1,17 +1,17 @@ # Copyright The IETF Trust 2007, All Rights Reserved -#import models import datetime import os import re import tarfile +import debug +import urllib +import json from tempfile import mkstemp from django import forms -from django.shortcuts import render_to_response, get_object_or_404 -from django.utils import simplejson as json -from ietf.idtracker.models import IETFWG, IRTF, Area +from django.shortcuts import render_to_response, get_object_or_404, redirect from django.http import HttpResponseRedirect, HttpResponse, Http404 from django.core.urlresolvers import reverse from django.db.models import Q @@ -19,53 +19,45 @@ from django.template import RequestContext from django.template.loader import render_to_string from django.conf import settings from django.utils.decorators import decorator_from_middleware -from ietf.ietfauth.decorators import group_required, has_role from django.middleware.gzip import GZipMiddleware from django.db.models import Max from django.forms.models import modelform_factory -import debug -import urllib - from ietf.utils.pipe import pipe +from ietf.ietfauth.utils import role_required, has_role from ietf.doc.models import Document, State - -# Old model -- needs to be removed -from ietf.proceedings.models import Meeting as OldMeeting, WgMeetingSession, Proceeding, Switches - -# New models from ietf.person.models import Person -from ietf.meeting.models import TimeSlot, Session, Schedule +from ietf.meeting.models import Meeting, TimeSlot, Session, Schedule from ietf.group.models import Group -from ietf.meeting.helpers import agenda_info from ietf.meeting.helpers import get_areas from ietf.meeting.helpers import build_all_agenda_slices, get_wg_name_list from ietf.meeting.helpers import get_scheduledsessions_from_schedule, get_all_scheduledsessions_from_schedule from ietf.meeting.helpers import get_modified_from_scheduledsessions from ietf.meeting.helpers import get_wg_list, find_ads_for_meeting -from ietf.meeting.helpers import get_meeting, get_schedule, agenda_permissions - -import debug +from ietf.meeting.helpers import get_meeting, get_schedule, agenda_permissions, meeting_updated @decorator_from_middleware(GZipMiddleware) def materials(request, meeting_num=None): - proceeding = get_object_or_404(Proceeding, meeting_num=meeting_num) - begin_date = proceeding.sub_begin_date - cut_off_date = proceeding.sub_cut_off_date - cor_cut_off_date = proceeding.c_sub_cut_off_date + meeting = get_meeting(meeting_num) + + begin_date = meeting.get_submission_start_date() + cut_off_date = meeting.get_submission_cut_off_date() + cor_cut_off_date = meeting.get_submission_correction_date() now = datetime.date.today() if settings.SERVER_MODE != 'production' and '_testoverride' in request.REQUEST: pass elif now > cor_cut_off_date: - return render_to_response("meeting/materials_upload_closed.html",{'meeting_num':meeting_num,'begin_date':begin_date, 'cut_off_date':cut_off_date, 'cor_cut_off_date':cor_cut_off_date}, context_instance=RequestContext(request)) - sub_began = 0 - if now > begin_date: - sub_began = 1 + return render_to_response("meeting/materials_upload_closed.html", { + 'meeting_num': meeting_num, + 'begin_date': begin_date, + 'cut_off_date': cut_off_date, + 'cor_cut_off_date': cor_cut_off_date + }, context_instance=RequestContext(request)) + #sessions = Session.objects.filter(meeting__number=meeting_num, timeslot__isnull=False) - meeting = get_meeting(meeting_num) - schedule = get_schedule(meeting,None ) - sessions = Session.objects.filter(meeting__number=meeting_num,scheduledsession__schedule=schedule ).select_related() + schedule = get_schedule(meeting, None) + sessions = Session.objects.filter(meeting__number=meeting_num, scheduledsession__schedule=schedule).select_related() plenaries = sessions.filter(name__icontains='plenary') ietf = sessions.filter(group__parent__type__slug = 'area').exclude(group__acronym='edu') irtf = sessions.filter(group__parent__acronym = 'irtf') @@ -73,18 +65,21 @@ def materials(request, meeting_num=None): iab = sessions.filter(group__parent__acronym = 'iab') cache_version = Document.objects.filter(session__meeting__number=meeting_num).aggregate(Max('time'))["time__max"] - # - return render_to_response("meeting/materials.html", - {'meeting_num':meeting_num, - 'plenaries': plenaries, 'ietf':ietf, 'training':training, 'irtf': irtf, 'iab':iab, - 'begin_date':begin_date, 'cut_off_date':cut_off_date, - 'cor_cut_off_date':cor_cut_off_date,'sub_began':sub_began, - 'cache_version':cache_version}, - context_instance=RequestContext(request)) + return render_to_response("meeting/materials.html", { + 'meeting_num': meeting_num, + 'plenaries': plenaries, 'ietf': ietf, 'training': training, 'irtf': irtf, 'iab': iab, + 'cut_off_date': cut_off_date, + 'cor_cut_off_date': cor_cut_off_date, + 'submission_started': now > begin_date, + 'cache_version': cache_version, + }, context_instance=RequestContext(request)) def current_materials(request): - meeting = OldMeeting.objects.exclude(number__startswith='interim-').order_by('-meeting_num')[0] - return HttpResponseRedirect( reverse(materials, args=[meeting.meeting_num]) ) + meetings = Meeting.objects.exclude(number__startswith='interim-').order_by('-number') + if meetings: + return redirect(materials, meetings[0].number) + else: + raise Http404 def get_user_agent(request): if settings.SERVER_MODE != 'production' and '_testiphone' in request.REQUEST: @@ -100,7 +95,7 @@ def get_user_agent(request): class SaveAsForm(forms.Form): savename = forms.CharField(max_length=100) -@group_required('Area Director','Secretariat') +@role_required('Area Director','Secretariat') def agenda_create(request, num=None, schedule_name=None): meeting = get_meeting(num) schedule = get_schedule(meeting, schedule_name) @@ -203,7 +198,7 @@ def edit_timeslots(request, num=None): RequestContext(request)), mimetype="text/html") ############################################################################## -#@group_required('Area Director','Secretariat') +#@role_required('Area Director','Secretariat') # disable the above security for now, check it below. @decorator_from_middleware(GZipMiddleware) def edit_agenda(request, num=None, schedule_name=None): @@ -235,9 +230,9 @@ def edit_agenda(request, num=None, schedule_name=None): saveasurl=reverse(edit_agenda, args=[meeting.number, schedule.name]) - cansee,canedit = agenda_permissions(meeting, schedule, user) + can_see, can_edit = agenda_permissions(meeting, schedule, user) - if not cansee: + if not can_see: #sys.stdout.write("visible: %s public: %s owner: %s request from: %s\n" % ( # schedule.visible, schedule.public, schedule.owner, requestor)) return HttpResponse(render_to_string("meeting/private_agenda.html", @@ -293,7 +288,7 @@ def edit_agenda(request, num=None, schedule_name=None): # AgendaPropertiesForm = modelform_factory(Schedule, fields=('name','visible', 'public')) -@group_required('Area Director','Secretariat') +@role_required('Area Director','Secretariat') @decorator_from_middleware(GZipMiddleware) def edit_agenda_properties(request, num=None, schedule_name=None): @@ -311,7 +306,7 @@ def edit_agenda_properties(request, num=None, schedule_name=None): # show list of agendas. # -@group_required('Area Director','Secretariat') +@role_required('Area Director','Secretariat') @decorator_from_middleware(GZipMiddleware) def edit_agendas(request, num=None, order=None): @@ -342,7 +337,7 @@ def agenda(request, num=None, name=None, base=None, ext=None): mimetype = {".html":"text/html", ".txt": "text/plain", ".ics":"text/calendar", ".csv":"text/csv"} meeting = get_meeting(num) schedule = get_schedule(meeting, name) - updated = Switches().from_object(meeting).updated() + updated = meeting_updated(meeting) return HttpResponse(render_to_string("meeting/"+base+ext, {"schedule":schedule, "updated": updated}, RequestContext(request)), mimetype=mimetype[ext]) @@ -540,7 +535,7 @@ def week_view(request, num=None): def ical_agenda(request, num=None, name=None, ext=None): meeting = get_meeting(num) schedule = get_schedule(meeting, name) - updated = Switches().from_object(meeting).updated() + updated = meeting_updated(meeting) q = request.META.get('QUERY_STRING','') or "" filter = set(urllib.unquote(q).lower().split(',')) diff --git a/ietf/message/admin.py b/ietf/message/admin.py index d7e242067..5ba741f37 100644 --- a/ietf/message/admin.py +++ b/ietf/message/admin.py @@ -17,7 +17,7 @@ class SendQueueAdmin(admin.ModelAdmin): list_display = ["time", "by", "message", "send_at", "sent_at"] list_filter = ["time", "send_at", "sent_at"] search_fields = ["message__body"] - raw_id_fields = ["by"] + raw_id_fields = ["by", "message"] ordering = ["-time"] admin.site.register(SendQueue, SendQueueAdmin) diff --git a/ietf/message/models.py b/ietf/message/models.py index 91b2f44f2..fcecac73e 100644 --- a/ietf/message/models.py +++ b/ietf/message/models.py @@ -41,3 +41,6 @@ class SendQueue(models.Model): class Meta: ordering = ['time'] + + def __unicode__(self): + return u"'%s' %s -> %s (sent at %s)" % (self.message.subject, self.message.frm, self.message.to, self.sent_at or "") diff --git a/ietf/message/tests.py b/ietf/message/tests.py new file mode 100644 index 000000000..dbb964da7 --- /dev/null +++ b/ietf/message/tests.py @@ -0,0 +1,94 @@ +import datetime + +from django.conf import settings +from django.core.urlresolvers import reverse as urlreverse + +from ietf.utils.test_utils import TestCase +from ietf.utils.test_data import make_test_data +from ietf.utils.mail import outbox + +from ietf.message.models import Message, SendQueue +from ietf.person.models import Person +from ietf.group.models import Group +from ietf.message.utils import send_scheduled_message_from_send_queue + +class MessageTests(TestCase): + def test_message_view(self): + make_test_data() + + nomcom = Group.objects.create(name="nomcom%s" % datetime.date.today().year, type_id="nomcom") + msg = Message.objects.create( + by=Person.objects.get(name="(System)"), + subject="This is a test", + to="test@example.com", + frm="nomcomchair@example.com", + body="Hello World!", + content_type="", + ) + msg.related_groups.add(nomcom) + + r = self.client.get(urlreverse("nomcom_announcement", kwargs=dict(message_id=msg.id))) + self.assertEquals(r.status_code, 200) + self.assertTrue(msg.subject in r.content) + self.assertTrue(msg.to in r.content) + self.assertTrue(msg.frm in r.content) + self.assertTrue("Hello World!" in r.content) + + +class SendScheduledAnnouncementsTests(TestCase): + def test_send_plain_announcement(self): + make_test_data() + + msg = Message.objects.create( + by=Person.objects.get(name="(System)"), + subject="This is a test", + to="test@example.com", + frm="testmonkey@example.com", + cc="cc.a@example.com, cc.b@example.com", + bcc="bcc@example.com", + body="Hello World!", + content_type="", + ) + + q = SendQueue.objects.create( + by=Person.objects.get(name="(System)"), + message=msg, + send_at=datetime.datetime.now() + datetime.timedelta(hours=12) + ) + + mailbox_before = len(outbox) + + send_scheduled_message_from_send_queue(q) + + self.assertEquals(len(outbox), mailbox_before + 1) + self.assertTrue("This is a test" in outbox[-1]["Subject"]) + self.assertTrue(SendQueue.objects.get(id=q.id).sent_at) + + def test_send_mime_announcement(self): + make_test_data() + + msg = Message.objects.create( + by=Person.objects.get(name="(System)"), + subject="This is a test", + to="test@example.com", + frm="testmonkey@example.com", + cc="cc.a@example.com, cc.b@example.com", + bcc="bcc@example.com", + body='--NextPart\r\n\r\nA New Internet-Draft is available from the on-line Internet-Drafts directories.\r\n--NextPart\r\nContent-Type: Message/External-body;\r\n\tname="draft-huang-behave-bih-01.txt";\r\n\tsite="ftp.ietf.org";\r\n\taccess-type="anon-ftp";\r\n\tdirectory="internet-drafts"\r\n\r\nContent-Type: text/plain\r\nContent-ID: <2010-07-30001541.I-D@ietf.org>\r\n\r\n--NextPart--', + content_type='Multipart/Mixed; Boundary="NextPart"', + ) + + q = SendQueue.objects.create( + by=Person.objects.get(name="(System)"), + message=msg, + send_at=datetime.datetime.now() + datetime.timedelta(hours=12) + ) + + mailbox_before = len(outbox) + + send_scheduled_message_from_send_queue(q) + + self.assertEquals(len(outbox), mailbox_before + 1) + self.assertTrue("This is a test" in outbox[-1]["Subject"]) + self.assertTrue("--NextPart" in outbox[-1].as_string()) + self.assertTrue(SendQueue.objects.get(id=q.id).sent_at) diff --git a/ietf/message/utils.py b/ietf/message/utils.py index 1fc2e5133..9d1e8ffe8 100644 --- a/ietf/message/utils.py +++ b/ietf/message/utils.py @@ -1,9 +1,14 @@ +import re, datetime, email + +from django.conf import settings + +from ietf.utils.mail import send_mail_text, send_mail_mime from ietf.message.models import Message -def infer_message(s): - from email import message_from_string +first_dot_on_line_re = re.compile(r'^\.', re.MULTILINE) - parsed = message_from_string(s.encode("utf-8")) +def infer_message(s): + parsed = email.message_from_string(s.encode("utf-8")) m = Message() m.subject = parsed.get("Subject", "").decode("utf-8") @@ -14,3 +19,32 @@ def infer_message(s): m.body = parsed.get_payload().decode("utf-8") return m + +def send_scheduled_message_from_send_queue(send_queue): + message = send_queue.message + + # for some reason, the old Perl code base substituted away . on line starts + body = first_dot_on_line_re.sub("", message.body) + + extra = {} + if message.reply_to: + extra['Reply-To'] = message.reply_to + + # announcement.content_type can contain a case-sensitive parts separator, + # so we need to keep it as is, not lowercased, but we want a lowercased + # version for the coming comparisons. + content_type_lowercase = message.content_type.lower() + if not content_type_lowercase or 'text/plain' in content_type_lowercase: + send_mail_text(None, message.to, message.frm, message.subject, + body, cc=message.cc, bcc=message.bcc) + elif 'multipart' in content_type_lowercase: + # make body a real message so we can parse it + body = ("MIME-Version: 1.0\r\nContent-Type: %s\r\n" % message.content_type) + body + + msg = email.message_from_string(body.encode("utf-8")) + send_mail_mime(None, message.to, message.frm, message.subject, + msg, cc=message.cc, bcc=message.bcc) + + send_queue.sent_at = datetime.datetime.now() + send_queue.save() + diff --git a/ietf/message/views.py b/ietf/message/views.py new file mode 100644 index 000000000..b701f7fd6 --- /dev/null +++ b/ietf/message/views.py @@ -0,0 +1,15 @@ +from django.shortcuts import render_to_response, get_object_or_404 +from django.template import RequestContext + +from ietf.group.models import Group +from ietf.message.models import Message + + +def message(request, message_id, group_type): + possible_messages = Message.objects.filter(related_groups__type=group_type) + + message = get_object_or_404(possible_messages, id=message_id) + + return render_to_response("message/message.html", + dict(message=message), + context_instance=RequestContext(request)) diff --git a/ietf/name/fixtures/names.json b/ietf/name/fixtures/names.json new file mode 100644 index 000000000..fe8b99f58 --- /dev/null +++ b/ietf/name/fixtures/names.json @@ -0,0 +1,3756 @@ +[ + { + "pk": "yes", + "model": "name.ballotpositionname", + "fields": { + "order": 1, + "used": true, + "name": "Yes", + "blocking": false, + "desc": "" + } + }, + { + "pk": "noobj", + "model": "name.ballotpositionname", + "fields": { + "order": 2, + "used": true, + "name": "No Objection", + "blocking": false, + "desc": "" + } + }, + { + "pk": "discuss", + "model": "name.ballotpositionname", + "fields": { + "order": 3, + "used": true, + "name": "Discuss", + "blocking": true, + "desc": "" + } + }, + { + "pk": "block", + "model": "name.ballotpositionname", + "fields": { + "order": 3, + "used": true, + "name": "Block", + "blocking": true, + "desc": "" + } + }, + { + "pk": "abstain", + "model": "name.ballotpositionname", + "fields": { + "order": 4, + "used": true, + "name": "Abstain", + "blocking": false, + "desc": "" + } + }, + { + "pk": "recuse", + "model": "name.ballotpositionname", + "fields": { + "order": 5, + "used": true, + "name": "Recuse", + "blocking": false, + "desc": "" + } + }, + { + "pk": "norecord", + "model": "name.ballotpositionname", + "fields": { + "order": 6, + "used": true, + "name": "No Record", + "blocking": false, + "desc": "" + } + }, + { + "pk": "conflict", + "model": "name.constraintname", + "fields": { + "order": 0, + "penalty": 0, + "used": true, + "name": "Conflicts with", + "desc": "" + } + }, + { + "pk": "conflic2", + "model": "name.constraintname", + "fields": { + "order": 0, + "penalty": 0, + "used": true, + "name": "Conflicts with (secondary)", + "desc": "" + } + }, + { + "pk": "conflic3", + "model": "name.constraintname", + "fields": { + "order": 0, + "penalty": 0, + "used": true, + "name": "Conflicts with (tertiary)", + "desc": "" + } + }, + { + "pk": "rst", + "model": "name.dbtemplatetypename", + "fields": { + "order": 0, + "used": true, + "name": "reStructuredText", + "desc": "" + } + }, + { + "pk": "plain", + "model": "name.dbtemplatetypename", + "fields": { + "order": 0, + "used": true, + "name": "Plain", + "desc": "" + } + }, + { + "pk": "django", + "model": "name.dbtemplatetypename", + "fields": { + "order": 0, + "used": true, + "name": "Django", + "desc": "" + } + }, + { + "pk": "obs", + "model": "name.docrelationshipname", + "fields": { + "order": 0, + "revname": "Obsoleted by", + "used": true, + "name": "Obsoletes", + "desc": "" + } + }, + { + "pk": "updates", + "model": "name.docrelationshipname", + "fields": { + "order": 0, + "revname": "Updated by", + "used": true, + "name": "Updates", + "desc": "" + } + }, + { + "pk": "replaces", + "model": "name.docrelationshipname", + "fields": { + "order": 0, + "revname": "Replaced by", + "used": true, + "name": "Replaces", + "desc": "" + } + }, + { + "pk": "conflrev", + "model": "name.docrelationshipname", + "fields": { + "order": 0, + "revname": "Conflict reviewed by", + "used": true, + "name": "conflict reviews", + "desc": "" + } + }, + { + "pk": "refnorm", + "model": "name.docrelationshipname", + "fields": { + "order": 0, + "revname": "fixme", + "used": true, + "name": "Normative Reference", + "desc": "Normative Reference" + } + }, + { + "pk": "refold", + "model": "name.docrelationshipname", + "fields": { + "order": 0, + "revname": "fixme", + "used": true, + "name": "Reference", + "desc": "A reference found in a document which does not have split normative/informative reference sections." + } + }, + { + "pk": "refinfo", + "model": "name.docrelationshipname", + "fields": { + "order": 0, + "revname": "fixme", + "used": true, + "name": "Informative Reference", + "desc": "Informative Reference" + } + }, + { + "pk": "tops", + "model": "name.docrelationshipname", + "fields": { + "order": 0, + "revname": "Moved to Proposed Standard by", + "used": true, + "name": "Moves to Proposed Standard", + "desc": "" + } + }, + { + "pk": "tois", + "model": "name.docrelationshipname", + "fields": { + "order": 0, + "revname": "Moved to Internet Standard by", + "used": true, + "name": "Moves to Internet Standard", + "desc": "" + } + }, + { + "pk": "tohist", + "model": "name.docrelationshipname", + "fields": { + "order": 0, + "revname": "Moved to Historic by", + "used": true, + "name": "Moves to Historic", + "desc": "" + } + }, + { + "pk": "toinf", + "model": "name.docrelationshipname", + "fields": { + "order": 0, + "revname": "Moved to Informational by", + "used": true, + "name": "Moves to Informational", + "desc": "" + } + }, + { + "pk": "tobcp", + "model": "name.docrelationshipname", + "fields": { + "order": 0, + "revname": "Moved to BCP by", + "used": true, + "name": "Moves to BCP", + "desc": "" + } + }, + { + "pk": "toexp", + "model": "name.docrelationshipname", + "fields": { + "order": 0, + "revname": "Moved to Experimental by", + "used": true, + "name": "Moves to Experimental", + "desc": "" + } + }, + { + "pk": "refunk", + "model": "name.docrelationshipname", + "fields": { + "order": 3, + "revname": "fixme", + "used": true, + "name": "Possible Reference", + "desc": "Reference of unknown type, likely found in the text of the document." + } + }, + { + "pk": "stream-s", + "model": "name.docremindertypename", + "fields": { + "order": 0, + "used": true, + "name": "Stream state should change", + "desc": "" + } + }, + { + "pk": "iana-crd", + "model": "name.doctagname", + "fields": { + "order": 0, + "used": true, + "name": "IANA coordination", + "desc": "RFC-Editor/IANA Registration Coordination" + } + }, + { + "pk": "ref", + "model": "name.doctagname", + "fields": { + "order": 0, + "used": true, + "name": "Holding for references", + "desc": "Holding for normative reference" + } + }, + { + "pk": "missref", + "model": "name.doctagname", + "fields": { + "order": 0, + "used": true, + "name": "Missing references", + "desc": "Awaiting missing normative reference" + } + }, + { + "pk": "errata", + "model": "name.doctagname", + "fields": { + "order": 0, + "used": true, + "name": "Has errata", + "desc": "" + } + }, + { + "pk": "rfc-rev", + "model": "name.doctagname", + "fields": { + "order": 0, + "used": true, + "name": "Review by RFC Editor", + "desc": "" + } + }, + { + "pk": "via-rfc", + "model": "name.doctagname", + "fields": { + "order": 0, + "used": true, + "name": "Via RFC Editor", + "desc": "" + } + }, + { + "pk": "app-min", + "model": "name.doctagname", + "fields": { + "order": 0, + "used": true, + "name": "Approved in minutes", + "desc": "" + } + }, + { + "pk": "need-sh", + "model": "name.doctagname", + "fields": { + "order": 0, + "used": true, + "name": "Shepherd Needed", + "desc": "" + } + }, + { + "pk": "w-dep", + "model": "name.doctagname", + "fields": { + "order": 0, + "used": true, + "name": "Waiting for Dependency on Other Document", + "desc": "" + } + }, + { + "pk": "iesg-com", + "model": "name.doctagname", + "fields": { + "order": 0, + "used": true, + "name": "IESG Review Completed", + "desc": "" + } + }, + { + "pk": "iana", + "model": "name.doctagname", + "fields": { + "order": 0, + "used": true, + "name": "IANA", + "desc": "The document has IANA actions that are not yet completed." + } + }, + { + "pk": "rev-wg", + "model": "name.doctagname", + "fields": { + "order": 0, + "used": true, + "name": "Revised I-D Needed - Issue raised by WG", + "desc": "" + } + }, + { + "pk": "point", + "model": "name.doctagname", + "fields": { + "order": 1, + "used": true, + "name": "Point Raised - writeup needed", + "desc": "IESG discussions on the document have raised some issues that need to be brought to the attention of the authors/WG, but those issues have not been written down yet. (It is common for discussions during a telechat to result in such situations. An AD may raise a possible issue during a telechat and only decide as a result of that discussion whether the issue is worth formally writing up and bringing to the attention of the authors/WG). A document stays in the \"Point Raised - Writeup Needed\" state until *ALL* IESG comments that have been raised have been documented." + } + }, + { + "pk": "w-expert", + "model": "name.doctagname", + "fields": { + "order": 1, + "used": true, + "name": "Awaiting Expert Review/Resolution of Issues Raised", + "desc": "" + } + }, + { + "pk": "need-ed", + "model": "name.doctagname", + "fields": { + "order": 1, + "used": true, + "name": "Editor Needed", + "desc": "" + } + }, + { + "pk": "ad-f-up", + "model": "name.doctagname", + "fields": { + "order": 2, + "used": true, + "name": "AD Followup", + "desc": "A generic substate indicating that the shepherding AD has the action item to determine appropriate next steps. In particular, the appropriate steps (and the corresponding next state or substate) depend entirely on the nature of the issues that were raised and can only be decided with active involvement of the shepherding AD. Examples include:\n\n- if another AD raises an issue, the shepherding AD may first iterate with the other AD to get a better understanding of the exact issue. Or, the shepherding AD may attempt to argue that the issue is not serious enough to bring to the attention of the authors/WG.\n\n- if a documented issue is forwarded to a WG, some further iteration may be needed before it can be determined whether a new revision is needed or whether the WG response to an issue clarifies the issue sufficiently.\n\n- when a new revision appears, the shepherding AD will first look at the changes to determine whether they believe all outstanding issues have been raised satisfactorily, prior to asking the ADs who raised the original issues to verify the changes." + } + }, + { + "pk": "w-extern", + "model": "name.doctagname", + "fields": { + "order": 2, + "used": true, + "name": "Awaiting External Review/Resolution of Issues Raised", + "desc": "" + } + }, + { + "pk": "w-part", + "model": "name.doctagname", + "fields": { + "order": 2, + "used": true, + "name": "Waiting for Partner Feedback", + "desc": "" + } + }, + { + "pk": "extpty", + "model": "name.doctagname", + "fields": { + "order": 3, + "used": true, + "name": "External Party", + "desc": "The document is awaiting review or input from an external party (i.e, someone other than the shepherding AD, the authors, or the WG). See the \"note\" field for more details on who has the action." + } + }, + { + "pk": "w-merge", + "model": "name.doctagname", + "fields": { + "order": 3, + "used": true, + "name": "Awaiting Merge with Other Document", + "desc": "" + } + }, + { + "pk": "w-review", + "model": "name.doctagname", + "fields": { + "order": 3, + "used": true, + "name": "Awaiting Reviews", + "desc": "" + } + }, + { + "pk": "need-aut", + "model": "name.doctagname", + "fields": { + "order": 4, + "used": true, + "name": "Author or Editor Needed", + "desc": "" + } + }, + { + "pk": "sh-f-up", + "model": "name.doctagname", + "fields": { + "order": 4, + "used": true, + "name": "Document Shepherd Followup", + "desc": "" + } + }, + { + "pk": "need-rev", + "model": "name.doctagname", + "fields": { + "order": 5, + "used": true, + "name": "Revised I-D Needed", + "desc": "An updated I-D is needed to address the issues that have been raised." + } + }, + { + "pk": "w-refdoc", + "model": "name.doctagname", + "fields": { + "order": 5, + "used": true, + "name": "Waiting for Referenced Document", + "desc": "" + } + }, + { + "pk": "w-refing", + "model": "name.doctagname", + "fields": { + "order": 6, + "used": true, + "name": "Waiting for Referencing Document", + "desc": "" + } + }, + { + "pk": "rev-wglc", + "model": "name.doctagname", + "fields": { + "order": 7, + "used": true, + "name": "Revised I-D Needed - Issue raised by WGLC", + "desc": "" + } + }, + { + "pk": "rev-ad", + "model": "name.doctagname", + "fields": { + "order": 8, + "used": true, + "name": "Revised I-D Needed - Issue raised by AD", + "desc": "" + } + }, + { + "pk": "rev-iesg", + "model": "name.doctagname", + "fields": { + "order": 9, + "used": true, + "name": "Revised I-D Needed - Issue raised by IESG", + "desc": "" + } + }, + { + "pk": "sheph-u", + "model": "name.doctagname", + "fields": { + "order": 10, + "used": true, + "name": "Doc Shepherd Follow-up Underway", + "desc": "" + } + }, + { + "pk": "other", + "model": "name.doctagname", + "fields": { + "order": 11, + "used": true, + "name": "Other - see Comment Log", + "desc": "" + } + }, + { + "pk": "charter", + "model": "name.doctypename", + "fields": { + "order": 0, + "used": true, + "name": "Charter", + "desc": "" + } + }, + { + "pk": "agenda", + "model": "name.doctypename", + "fields": { + "order": 0, + "used": true, + "name": "Agenda", + "desc": "" + } + }, + { + "pk": "minutes", + "model": "name.doctypename", + "fields": { + "order": 0, + "used": true, + "name": "Minutes", + "desc": "" + } + }, + { + "pk": "slides", + "model": "name.doctypename", + "fields": { + "order": 0, + "used": true, + "name": "Slides", + "desc": "" + } + }, + { + "pk": "draft", + "model": "name.doctypename", + "fields": { + "order": 0, + "used": true, + "name": "Draft", + "desc": "" + } + }, + { + "pk": "liai-att", + "model": "name.doctypename", + "fields": { + "order": 0, + "used": true, + "name": "Liaison Attachment", + "desc": "" + } + }, + { + "pk": "conflrev", + "model": "name.doctypename", + "fields": { + "order": 0, + "used": true, + "name": "Conflict Review", + "desc": "" + } + }, + { + "pk": "statchg", + "model": "name.doctypename", + "fields": { + "order": 0, + "used": true, + "name": "Status Change", + "desc": "" + } + }, + { + "pk": "shepwrit", + "model": "name.doctypename", + "fields": { + "order": 0, + "used": false, + "name": "Shepherd's writeup", + "desc": "" + } + }, + { + "pk": "liaison", + "model": "name.doctypename", + "fields": { + "order": 0, + "used": false, + "name": "Liaison", + "desc": "" + } + }, + { + "pk": "uploaded", + "model": "name.draftsubmissionstatename", + "fields": { + "order": 1, + "next_states": [ + "auth", + "aut-appr", + "grp-appr", + "manual", + "cancel" + ], + "used": true, + "name": "Uploaded", + "desc": "" + } + }, + { + "pk": "auth", + "model": "name.draftsubmissionstatename", + "fields": { + "order": 2, + "next_states": [ + "cancel", + "posted" + ], + "used": true, + "name": "Awaiting Submitter Authentication", + "desc": "" + } + }, + { + "pk": "aut-appr", + "model": "name.draftsubmissionstatename", + "fields": { + "order": 3, + "next_states": [ + "cancel", + "posted" + ], + "used": true, + "name": "Awaiting Approval from Previous Version Authors'", + "desc": "" + } + }, + { + "pk": "grp-appr", + "model": "name.draftsubmissionstatename", + "fields": { + "order": 4, + "next_states": [ + "cancel", + "posted" + ], + "used": true, + "name": "Awaiting Initial Version Approval", + "desc": "" + } + }, + { + "pk": "manual", + "model": "name.draftsubmissionstatename", + "fields": { + "order": 5, + "next_states": [ + "cancel", + "posted" + ], + "used": true, + "name": "Awaiting Manual Post", + "desc": "" + } + }, + { + "pk": "cancel", + "model": "name.draftsubmissionstatename", + "fields": { + "order": 6, + "next_states": [], + "used": true, + "name": "Cancelled", + "desc": "" + } + }, + { + "pk": "posted", + "model": "name.draftsubmissionstatename", + "fields": { + "order": 7, + "next_states": [], + "used": true, + "name": "Posted", + "desc": "" + } + }, + { + "pk": "comment", + "model": "name.feedbacktype", + "fields": { + "order": 0, + "used": true, + "name": "Comment", + "desc": "" + } + }, + { + "pk": "questio", + "model": "name.feedbacktype", + "fields": { + "order": 0, + "used": true, + "name": "Questionnaire response", + "desc": "" + } + }, + { + "pk": "nomina", + "model": "name.feedbacktype", + "fields": { + "order": 0, + "used": true, + "name": "Nomination", + "desc": "" + } + }, + { + "pk": "junk", + "model": "name.feedbacktype", + "fields": { + "order": 0, + "used": true, + "name": "Junk", + "desc": "" + } + }, + { + "pk": "active", + "model": "name.groupmilestonestatename", + "fields": { + "order": 1, + "used": true, + "name": "Active", + "desc": "" + } + }, + { + "pk": "deleted", + "model": "name.groupmilestonestatename", + "fields": { + "order": 2, + "used": true, + "name": "Deleted", + "desc": "" + } + }, + { + "pk": "review", + "model": "name.groupmilestonestatename", + "fields": { + "order": 3, + "used": true, + "name": "For review", + "desc": "" + } + }, + { + "pk": "charter", + "model": "name.groupmilestonestatename", + "fields": { + "order": 4, + "used": true, + "name": "Chartering/rechartering", + "desc": "" + } + }, + { + "pk": "bof", + "model": "name.groupstatename", + "fields": { + "order": 0, + "used": true, + "name": "BOF", + "desc": "" + } + }, + { + "pk": "proposed", + "model": "name.groupstatename", + "fields": { + "order": 0, + "used": true, + "name": "Proposed", + "desc": "" + } + }, + { + "pk": "active", + "model": "name.groupstatename", + "fields": { + "order": 0, + "used": true, + "name": "Active", + "desc": "" + } + }, + { + "pk": "dormant", + "model": "name.groupstatename", + "fields": { + "order": 0, + "used": true, + "name": "Dormant", + "desc": "" + } + }, + { + "pk": "conclude", + "model": "name.groupstatename", + "fields": { + "order": 0, + "used": true, + "name": "Concluded", + "desc": "" + } + }, + { + "pk": "unknown", + "model": "name.groupstatename", + "fields": { + "order": 0, + "used": true, + "name": "Unknown", + "desc": "" + } + }, + { + "pk": "abandon", + "model": "name.groupstatename", + "fields": { + "order": 0, + "used": true, + "name": "Abandonded", + "desc": "Formation of the group (most likely a BoF or Proposed WG) was abandoned" + } + }, + { + "pk": "bof-conc", + "model": "name.groupstatename", + "fields": { + "order": 0, + "used": true, + "name": "BOF Concluded", + "desc": "" + } + }, + { + "pk": "ietf", + "model": "name.grouptypename", + "fields": { + "order": 0, + "used": true, + "name": "IETF", + "desc": "" + } + }, + { + "pk": "area", + "model": "name.grouptypename", + "fields": { + "order": 0, + "used": true, + "name": "Area", + "desc": "" + } + }, + { + "pk": "ag", + "model": "name.grouptypename", + "fields": { + "order": 0, + "used": true, + "name": "AG", + "desc": "Area group" + } + }, + { + "pk": "wg", + "model": "name.grouptypename", + "fields": { + "order": 0, + "used": true, + "name": "WG", + "desc": "Working group" + } + }, + { + "pk": "rg", + "model": "name.grouptypename", + "fields": { + "order": 0, + "used": true, + "name": "RG", + "desc": "Research group" + } + }, + { + "pk": "team", + "model": "name.grouptypename", + "fields": { + "order": 0, + "used": true, + "name": "Team", + "desc": "" + } + }, + { + "pk": "individ", + "model": "name.grouptypename", + "fields": { + "order": 0, + "used": true, + "name": "Individual", + "desc": "" + } + }, + { + "pk": "sdo", + "model": "name.grouptypename", + "fields": { + "order": 0, + "used": true, + "name": "SDO", + "desc": "Standards organization" + } + }, + { + "pk": "irtf", + "model": "name.grouptypename", + "fields": { + "order": 0, + "used": true, + "name": "IRTF", + "desc": "" + } + }, + { + "pk": "rfcedtyp", + "model": "name.grouptypename", + "fields": { + "order": 0, + "used": true, + "name": "RFC Editor", + "desc": "" + } + }, + { + "pk": "nomcom", + "model": "name.grouptypename", + "fields": { + "order": 0, + "used": true, + "name": "Nomcom", + "desc": "An IETF/IAB Nominating Committee. Use 'SDO' for external nominating committees." + } + }, + { + "pk": "ps", + "model": "name.intendedstdlevelname", + "fields": { + "order": 1, + "used": true, + "name": "Proposed Standard", + "desc": "" + } + }, + { + "pk": "ds", + "model": "name.intendedstdlevelname", + "fields": { + "order": 2, + "used": false, + "name": "Draft Standard", + "desc": "" + } + }, + { + "pk": "std", + "model": "name.intendedstdlevelname", + "fields": { + "order": 3, + "used": true, + "name": "Internet Standard", + "desc": "" + } + }, + { + "pk": "bcp", + "model": "name.intendedstdlevelname", + "fields": { + "order": 4, + "used": true, + "name": "Best Current Practice", + "desc": "" + } + }, + { + "pk": "inf", + "model": "name.intendedstdlevelname", + "fields": { + "order": 5, + "used": true, + "name": "Informational", + "desc": "" + } + }, + { + "pk": "exp", + "model": "name.intendedstdlevelname", + "fields": { + "order": 6, + "used": true, + "name": "Experimental", + "desc": "" + } + }, + { + "pk": "hist", + "model": "name.intendedstdlevelname", + "fields": { + "order": 7, + "used": true, + "name": "Historic", + "desc": "" + } + }, + { + "pk": "action", + "model": "name.liaisonstatementpurposename", + "fields": { + "order": 1, + "used": true, + "name": "For action", + "desc": "" + } + }, + { + "pk": "comment", + "model": "name.liaisonstatementpurposename", + "fields": { + "order": 2, + "used": true, + "name": "For comment", + "desc": "" + } + }, + { + "pk": "info", + "model": "name.liaisonstatementpurposename", + "fields": { + "order": 3, + "used": true, + "name": "For information", + "desc": "" + } + }, + { + "pk": "response", + "model": "name.liaisonstatementpurposename", + "fields": { + "order": 4, + "used": true, + "name": "In response", + "desc": "" + } + }, + { + "pk": "ietf", + "model": "name.meetingtypename", + "fields": { + "order": 0, + "used": true, + "name": "IETF", + "desc": "" + } + }, + { + "pk": "interim", + "model": "name.meetingtypename", + "fields": { + "order": 0, + "used": true, + "name": "Interim", + "desc": "" + } + }, + { + "pk": "pending", + "model": "name.nomineepositionstate", + "fields": { + "order": 0, + "used": true, + "name": "Nominated, pending response", + "desc": "" + } + }, + { + "pk": "accepted", + "model": "name.nomineepositionstate", + "fields": { + "order": 0, + "used": true, + "name": "Accepted", + "desc": "" + } + }, + { + "pk": "declined", + "model": "name.nomineepositionstate", + "fields": { + "order": 0, + "used": true, + "name": "Declined", + "desc": "" + } + }, + { + "pk": "ad", + "model": "name.rolename", + "fields": { + "order": 0, + "used": true, + "name": "Area Director", + "desc": "" + } + }, + { + "pk": "pre-ad", + "model": "name.rolename", + "fields": { + "order": 0, + "used": true, + "name": "Incoming Area Director", + "desc": "" + } + }, + { + "pk": "chair", + "model": "name.rolename", + "fields": { + "order": 0, + "used": true, + "name": "Chair", + "desc": "" + } + }, + { + "pk": "editor", + "model": "name.rolename", + "fields": { + "order": 0, + "used": true, + "name": "Editor", + "desc": "" + } + }, + { + "pk": "secr", + "model": "name.rolename", + "fields": { + "order": 0, + "used": true, + "name": "Secretary", + "desc": "" + } + }, + { + "pk": "techadv", + "model": "name.rolename", + "fields": { + "order": 0, + "used": true, + "name": "Tech Advisor", + "desc": "" + } + }, + { + "pk": "execdir", + "model": "name.rolename", + "fields": { + "order": 0, + "used": true, + "name": "Executive Director", + "desc": "" + } + }, + { + "pk": "admdir", + "model": "name.rolename", + "fields": { + "order": 0, + "used": true, + "name": "Administrative Director", + "desc": "" + } + }, + { + "pk": "liaiman", + "model": "name.rolename", + "fields": { + "order": 0, + "used": true, + "name": "Liaison Manager", + "desc": "" + } + }, + { + "pk": "auth", + "model": "name.rolename", + "fields": { + "order": 0, + "used": true, + "name": "Authorized Individual", + "desc": "" + } + }, + { + "pk": "delegate", + "model": "name.rolename", + "fields": { + "order": 0, + "used": true, + "name": "Delegate", + "desc": "" + } + }, + { + "pk": "atlarge", + "model": "name.rolename", + "fields": { + "order": 0, + "used": true, + "name": "At Large Member", + "desc": "" + } + }, + { + "pk": "member", + "model": "name.rolename", + "fields": { + "order": 0, + "used": true, + "name": "Member", + "desc": "Regular group member in a group that has explicit membership, such as the NomCom" + } + }, + { + "pk": "liaison", + "model": "name.rolename", + "fields": { + "order": 0, + "used": true, + "name": "Liaison Member", + "desc": "Liaison group member in a group that has explicit membership, such as the NomCom" + } + }, + { + "pk": "advisor", + "model": "name.rolename", + "fields": { + "order": 0, + "used": true, + "name": "Advisor", + "desc": "Advisor in a group that has explicit membership, such as the NomCom" + } + }, + { + "pk": "schedw", + "model": "name.sessionstatusname", + "fields": { + "order": 0, + "used": true, + "name": "Waiting for Scheduling", + "desc": "" + } + }, + { + "pk": "apprw", + "model": "name.sessionstatusname", + "fields": { + "order": 0, + "used": true, + "name": "Waiting for Approval", + "desc": "" + } + }, + { + "pk": "appr", + "model": "name.sessionstatusname", + "fields": { + "order": 0, + "used": true, + "name": "Approved", + "desc": "" + } + }, + { + "pk": "sched", + "model": "name.sessionstatusname", + "fields": { + "order": 0, + "used": true, + "name": "Scheduled", + "desc": "" + } + }, + { + "pk": "canceled", + "model": "name.sessionstatusname", + "fields": { + "order": 0, + "used": true, + "name": "Canceled", + "desc": "" + } + }, + { + "pk": "disappr", + "model": "name.sessionstatusname", + "fields": { + "order": 0, + "used": true, + "name": "Disapproved", + "desc": "" + } + }, + { + "pk": "notmeet", + "model": "name.sessionstatusname", + "fields": { + "order": 0, + "used": true, + "name": "Not meeting", + "desc": "" + } + }, + { + "pk": "deleted", + "model": "name.sessionstatusname", + "fields": { + "order": 0, + "used": true, + "name": "Deleted", + "desc": "" + } + }, + { + "pk": "std", + "model": "name.stdlevelname", + "fields": { + "order": 0, + "used": true, + "name": "Internet Standard", + "desc": "" + } + }, + { + "pk": "ds", + "model": "name.stdlevelname", + "fields": { + "order": 0, + "used": false, + "name": "Draft Standard", + "desc": "" + } + }, + { + "pk": "ps", + "model": "name.stdlevelname", + "fields": { + "order": 0, + "used": true, + "name": "Proposed Standard", + "desc": "" + } + }, + { + "pk": "inf", + "model": "name.stdlevelname", + "fields": { + "order": 0, + "used": true, + "name": "Informational", + "desc": "" + } + }, + { + "pk": "exp", + "model": "name.stdlevelname", + "fields": { + "order": 0, + "used": true, + "name": "Experimental", + "desc": "" + } + }, + { + "pk": "bcp", + "model": "name.stdlevelname", + "fields": { + "order": 0, + "used": true, + "name": "Best Current Practice", + "desc": "" + } + }, + { + "pk": "hist", + "model": "name.stdlevelname", + "fields": { + "order": 0, + "used": true, + "name": "Historic", + "desc": "" + } + }, + { + "pk": "unkn", + "model": "name.stdlevelname", + "fields": { + "order": 0, + "used": true, + "name": "Unknown", + "desc": "" + } + }, + { + "pk": "ietf", + "model": "name.streamname", + "fields": { + "order": 1, + "used": true, + "name": "IETF", + "desc": "IETF stream" + } + }, + { + "pk": "ise", + "model": "name.streamname", + "fields": { + "order": 2, + "used": true, + "name": "ISE", + "desc": "Independent Submission Editor stream" + } + }, + { + "pk": "irtf", + "model": "name.streamname", + "fields": { + "order": 3, + "used": true, + "name": "IRTF", + "desc": "Independent Submission Editor stream" + } + }, + { + "pk": "iab", + "model": "name.streamname", + "fields": { + "order": 4, + "used": true, + "name": "IAB", + "desc": "IAB stream" + } + }, + { + "pk": "legacy", + "model": "name.streamname", + "fields": { + "order": 5, + "used": true, + "name": "Legacy", + "desc": "Legacy stream" + } + }, + { + "pk": "other", + "model": "name.timeslottypename", + "fields": { + "order": 0, + "used": true, + "name": "Other", + "desc": "" + } + }, + { + "pk": "session", + "model": "name.timeslottypename", + "fields": { + "order": 0, + "used": true, + "name": "Session", + "desc": "" + } + }, + { + "pk": "break", + "model": "name.timeslottypename", + "fields": { + "order": 0, + "used": true, + "name": "Break", + "desc": "" + } + }, + { + "pk": "reg", + "model": "name.timeslottypename", + "fields": { + "order": 0, + "used": true, + "name": "Registration", + "desc": "" + } + }, + { + "pk": "plenary", + "model": "name.timeslottypename", + "fields": { + "order": 0, + "used": true, + "name": "Plenary", + "desc": "" + } + }, + { + "pk": "draft", + "model": "doc.statetype", + "fields": { + "label": "State" + } + }, + { + "pk": "draft-iesg", + "model": "doc.statetype", + "fields": { + "label": "IESG state" + } + }, + { + "pk": "draft-iana", + "model": "doc.statetype", + "fields": { + "label": "IANA state" + } + }, + { + "pk": "draft-rfceditor", + "model": "doc.statetype", + "fields": { + "label": "RFC Editor state" + } + }, + { + "pk": "draft-stream-ietf", + "model": "doc.statetype", + "fields": { + "label": "IETF WG state" + } + }, + { + "pk": "draft-stream-irtf", + "model": "doc.statetype", + "fields": { + "label": "IRTF state" + } + }, + { + "pk": "draft-stream-ise", + "model": "doc.statetype", + "fields": { + "label": "ISE state" + } + }, + { + "pk": "draft-stream-iab", + "model": "doc.statetype", + "fields": { + "label": "IAB state" + } + }, + { + "pk": "slides", + "model": "doc.statetype", + "fields": { + "label": "State" + } + }, + { + "pk": "minutes", + "model": "doc.statetype", + "fields": { + "label": "State" + } + }, + { + "pk": "agenda", + "model": "doc.statetype", + "fields": { + "label": "State" + } + }, + { + "pk": "liai-att", + "model": "doc.statetype", + "fields": { + "label": "State" + } + }, + { + "pk": "charter", + "model": "doc.statetype", + "fields": { + "label": "State" + } + }, + { + "pk": "conflrev", + "model": "doc.statetype", + "fields": { + "label": "Conflict Review State" + } + }, + { + "pk": "draft-iana-action", + "model": "doc.statetype", + "fields": { + "label": "IANA Action state" + } + }, + { + "pk": "draft-iana-review", + "model": "doc.statetype", + "fields": { + "label": "IANA Review state" + } + }, + { + "pk": "statchg", + "model": "doc.statetype", + "fields": { + "label": "RFC Status Change" + } + }, + { + "pk": 81, + "model": "doc.state", + "fields": { + "used": true, + "name": "Active", + "next_states": [], + "slug": "active", + "type": "agenda", + "order": 1, + "desc": "" + } + }, + { + "pk": 82, + "model": "doc.state", + "fields": { + "used": true, + "name": "Deleted", + "next_states": [], + "slug": "deleted", + "type": "agenda", + "order": 2, + "desc": "" + } + }, + { + "pk": 83, + "model": "doc.state", + "fields": { + "used": true, + "name": "Not currently under review", + "next_states": [], + "slug": "notrev", + "type": "charter", + "order": 0, + "desc": "The proposed charter is not being considered at this time. A proposed charter will remain in this state until an AD moves it to Informal IESG review." + } + }, + { + "pk": 84, + "model": "doc.state", + "fields": { + "used": true, + "name": "Informal IESG review", + "next_states": [], + "slug": "infrev", + "type": "charter", + "order": 0, + "desc": "This is the initial state when an AD proposes a new charter. The normal next state is Internal review if the idea is accepted, or Not currently under review if the idea is abandoned." + } + }, + { + "pk": 85, + "model": "doc.state", + "fields": { + "used": true, + "name": "Internal review", + "next_states": [], + "slug": "intrev", + "type": "charter", + "order": 0, + "desc": "The IESG and IAB are reviewing the early draft of the charter; this is the initial IESG and IAB review. The usual next state is External review if the idea is adopted, or Informal IESG review if the IESG decides the idea needs more work, or Not currently under review is the idea is abandoned" + } + }, + { + "pk": 86, + "model": "doc.state", + "fields": { + "used": true, + "name": "External review", + "next_states": [], + "slug": "extrev", + "type": "charter", + "order": 0, + "desc": "The IETF community and possibly other standards development organizations (SDOs) are reviewing the proposed charter. The usual next state is IESG review, although it might move to Not currently under review is the idea is abandoned during the external review." + } + }, + { + "pk": 87, + "model": "doc.state", + "fields": { + "used": true, + "name": "IESG review", + "next_states": [], + "slug": "iesgrev", + "type": "charter", + "order": 0, + "desc": "The IESG is reviewing the discussion from the external review of the proposed charter. The usual next state is Approved, or Not currently under review if the idea is abandoned." + } + }, + { + "pk": 88, + "model": "doc.state", + "fields": { + "used": true, + "name": "Approved", + "next_states": [], + "slug": "approved", + "type": "charter", + "order": 0, + "desc": "The charter is approved by the IESG." + } + }, + { + "pk": 90, + "model": "doc.state", + "fields": { + "used": true, + "name": "Needs Shepherd", + "next_states": [ + 91, + 98, + 99 + ], + "slug": "needshep", + "type": "conflrev", + "order": 1, + "desc": "A conflict review has been requested, but a shepherding AD has not yet been assigned" + } + }, + { + "pk": 91, + "model": "doc.state", + "fields": { + "used": true, + "name": "AD Review", + "next_states": [ + 92, + 98, + 99 + ], + "slug": "adrev", + "type": "conflrev", + "order": 2, + "desc": "The sponsoring AD is reviewing the document and preparing a proposed response" + } + }, + { + "pk": 92, + "model": "doc.state", + "fields": { + "used": true, + "name": "IESG Evaluation", + "next_states": [ + 93, + 94, + 95, + 98, + 99 + ], + "slug": "iesgeval", + "type": "conflrev", + "order": 3, + "desc": "The IESG is considering the proposed conflict review response" + } + }, + { + "pk": 93, + "model": "doc.state", + "fields": { + "used": true, + "name": "IESG Evaluation - Defer", + "next_states": [ + 92, + 94, + 95, + 98, + 99 + ], + "slug": "defer", + "type": "conflrev", + "order": 4, + "desc": "The evaluation of the proposed conflict review response has been deferred to the next telechat" + } + }, + { + "pk": 100, + "model": "doc.state", + "fields": { + "used": true, + "name": "Approved Request to Not Publish - point raised", + "next_states": [ + 94 + ], + "slug": "appr-reqnopub-pr", + "type": "conflrev", + "order": 5, + "desc": "The IESG has approved the conflict review response (a request to not publish), but a point has been raised that should be cleared before moving to announcement to be sent" + } + }, + { + "pk": 101, + "model": "doc.state", + "fields": { + "used": true, + "name": "Approved No Problem - point raised", + "next_states": [ + 95 + ], + "slug": "appr-noprob-pr", + "type": "conflrev", + "order": 6, + "desc": "The IESG has approved the conflict review response, but a point has been raised that should be cleared before proceeding to announcement to be sent" + } + }, + { + "pk": 94, + "model": "doc.state", + "fields": { + "used": true, + "name": "Approved Request to Not Publish - announcement to be sent", + "next_states": [ + 96, + 98 + ], + "slug": "appr-reqnopub-pend", + "type": "conflrev", + "order": 7, + "desc": "The IESG has approved the conflict review response (a request to not publish), but the secretariat has not yet sent the response" + } + }, + { + "pk": 95, + "model": "doc.state", + "fields": { + "used": true, + "name": "Approved No Problem - announcement to be sent", + "next_states": [ + 97, + 98 + ], + "slug": "appr-noprob-pend", + "type": "conflrev", + "order": 8, + "desc": "The IESG has approved the conflict review response, but the secretariat has not yet sent the response" + } + }, + { + "pk": 96, + "model": "doc.state", + "fields": { + "used": true, + "name": "Approved Request to Not Publish - announcement sent", + "next_states": [ + 96 + ], + "slug": "appr-reqnopub-sent", + "type": "conflrev", + "order": 9, + "desc": "The secretariat has delivered the IESG's approved conflict review response (a request to not publish) to the requester" + } + }, + { + "pk": 97, + "model": "doc.state", + "fields": { + "used": true, + "name": "Approved No Problem - announcement sent", + "next_states": [ + 97 + ], + "slug": "appr-noprob-sent", + "type": "conflrev", + "order": 10, + "desc": "The secretariat has delivered the IESG's approved conflict review response to the requester" + } + }, + { + "pk": 98, + "model": "doc.state", + "fields": { + "used": true, + "name": "Withdrawn", + "next_states": [ + 90 + ], + "slug": "withdraw", + "type": "conflrev", + "order": 11, + "desc": "The request for conflict review was withdrawn" + } + }, + { + "pk": 99, + "model": "doc.state", + "fields": { + "used": true, + "name": "Dead", + "next_states": [ + 90 + ], + "slug": "dead", + "type": "conflrev", + "order": 12, + "desc": "The conflict review has been abandoned" + } + }, + { + "pk": 1, + "model": "doc.state", + "fields": { + "used": true, + "name": "Active", + "next_states": [], + "slug": "active", + "type": "draft", + "order": 1, + "desc": "" + } + }, + { + "pk": 2, + "model": "doc.state", + "fields": { + "used": true, + "name": "Expired", + "next_states": [], + "slug": "expired", + "type": "draft", + "order": 2, + "desc": "" + } + }, + { + "pk": 3, + "model": "doc.state", + "fields": { + "used": true, + "name": "RFC", + "next_states": [], + "slug": "rfc", + "type": "draft", + "order": 3, + "desc": "" + } + }, + { + "pk": 4, + "model": "doc.state", + "fields": { + "used": true, + "name": "Replaced", + "next_states": [], + "slug": "repl", + "type": "draft", + "order": 4, + "desc": "" + } + }, + { + "pk": 5, + "model": "doc.state", + "fields": { + "used": true, + "name": "Withdrawn by Submitter", + "next_states": [], + "slug": "auth-rm", + "type": "draft", + "order": 5, + "desc": "" + } + }, + { + "pk": 6, + "model": "doc.state", + "fields": { + "used": true, + "name": "Withdrawn by IETF", + "next_states": [], + "slug": "ietf-rm", + "type": "draft", + "order": 6, + "desc": "" + } + }, + { + "pk": 102, + "model": "doc.state", + "fields": { + "used": true, + "name": "New Document", + "next_states": [], + "slug": "newdoc", + "type": "draft-iana-action", + "order": 1, + "desc": "A new document has been received by IANA, but no actions have been taken" + } + }, + { + "pk": 103, + "model": "doc.state", + "fields": { + "used": true, + "name": "In Progress", + "next_states": [], + "slug": "inprog", + "type": "draft-iana-action", + "order": 2, + "desc": "IANA is currently processing the actions for this document" + } + }, + { + "pk": 104, + "model": "doc.state", + "fields": { + "used": true, + "name": "Waiting on Authors", + "next_states": [], + "slug": "waitauth", + "type": "draft-iana-action", + "order": 3, + "desc": "IANA is waiting on the document's authors to respond" + } + }, + { + "pk": 105, + "model": "doc.state", + "fields": { + "used": true, + "name": "Waiting on ADs", + "next_states": [], + "slug": "waitad", + "type": "draft-iana-action", + "order": 4, + "desc": "IANA is waiting on the IETF Area Directors to respond" + } + }, + { + "pk": 106, + "model": "doc.state", + "fields": { + "used": true, + "name": "Waiting on WGC", + "next_states": [], + "slug": "waitwgc", + "type": "draft-iana-action", + "order": 5, + "desc": "IANA is waiting on the IETF Working Group Chairs to respond" + } + }, + { + "pk": 107, + "model": "doc.state", + "fields": { + "used": true, + "name": "Waiting on RFC Editor", + "next_states": [], + "slug": "waitrfc", + "type": "draft-iana-action", + "order": 6, + "desc": "IANA has notified the RFC Editor that the actions have been completed" + } + }, + { + "pk": 108, + "model": "doc.state", + "fields": { + "used": true, + "name": "RFC-Ed-Ack", + "next_states": [], + "slug": "rfcedack", + "type": "draft-iana-action", + "order": 7, + "desc": "Request completed. The RFC Editor has acknowledged receipt of IANA's message that the actions have been completed" + } + }, + { + "pk": 109, + "model": "doc.state", + "fields": { + "used": true, + "name": "On Hold", + "next_states": [], + "slug": "onhold", + "type": "draft-iana-action", + "order": 8, + "desc": "IANA has suspended work on the document" + } + }, + { + "pk": 110, + "model": "doc.state", + "fields": { + "used": true, + "name": "No IC", + "next_states": [], + "slug": "noic", + "type": "draft-iana-action", + "order": 9, + "desc": "Request completed. There were no IANA actions for this document" + } + }, + { + "pk": 111, + "model": "doc.state", + "fields": { + "used": true, + "name": "IANA - Review Needed", + "next_states": [], + "slug": "need-rev", + "type": "draft-iana-review", + "order": 1, + "desc": "Document has not yet been reviewed by IANA." + } + }, + { + "pk": 112, + "model": "doc.state", + "fields": { + "used": true, + "name": "IANA OK - Actions Needed", + "next_states": [], + "slug": "ok-act", + "type": "draft-iana-review", + "order": 2, + "desc": "Document requires IANA actions, and the IANA Considerations section indicates the details of the actions correctly." + } + }, + { + "pk": 113, + "model": "doc.state", + "fields": { + "used": true, + "name": "IANA OK - No Actions Needed", + "next_states": [], + "slug": "ok-noact", + "type": "draft-iana-review", + "order": 3, + "desc": "Document requires no IANA action, and the IANA Considerations section indicates this correctly." + } + }, + { + "pk": 114, + "model": "doc.state", + "fields": { + "used": true, + "name": "IANA - Not OK", + "next_states": [], + "slug": "not-ok", + "type": "draft-iana-review", + "order": 4, + "desc": "IANA has issues with the text of the IANA Considerations section of the document." + } + }, + { + "pk": 115, + "model": "doc.state", + "fields": { + "used": true, + "name": "Version Changed - Review Needed", + "next_states": [], + "slug": "changed", + "type": "draft-iana-review", + "order": 5, + "desc": "Document revision has changed after review by IANA." + } + }, + { + "pk": 16, + "model": "doc.state", + "fields": { + "used": true, + "name": "Publication Requested", + "next_states": [ + 13, + 11, + 8 + ], + "slug": "pub-req", + "type": "draft-iesg", + "order": 10, + "desc": "A formal request has been made to advance/publish the document, following the procedures in Section 7.5 of RFC 2418. The request could be from a WG chair, from an individual through the RFC Editor, etc. (The Secretariat (iesg-secretary@ietf.org) is copied on these requests to ensure that the request makes it into the ID tracker.) A document in this state has not (yet) been reviewed by an AD nor has any official action been taken on it yet (other than to note that its publication has been requested." + } + }, + { + "pk": 13, + "model": "doc.state", + "fields": { + "used": true, + "name": "AD Evaluation", + "next_states": [ + 21, + 14, + 12, + 11 + ], + "slug": "ad-eval", + "type": "draft-iesg", + "order": 11, + "desc": "A specific AD (e.g., the Area Advisor for the WG) has begun reviewing the document to verify that it is ready for advancement. The shepherding AD is responsible for doing any necessary review before starting an IETF Last Call or sending the document directly to the IESG as a whole." + } + }, + { + "pk": 21, + "model": "doc.state", + "fields": { + "used": true, + "name": "Expert Review", + "next_states": [ + 13 + ], + "slug": "review-e", + "type": "draft-iesg", + "order": 12, + "desc": "An AD sometimes asks for an external review by an outside party as part of evaluating whether a document is ready for advancement. MIBs, for example, are reviewed by the \"MIB doctors\". Other types of reviews may also be requested (e.g., security, operations impact, etc.). Documents stay in this state until the review is complete and possibly until the issues raised in the review are addressed. See the \"note\" field for specific details on the nature of the review." + } + }, + { + "pk": 14, + "model": "doc.state", + "fields": { + "used": true, + "name": "Last Call Requested", + "next_states": [ + 15 + ], + "slug": "lc-req", + "type": "draft-iesg", + "order": 15, + "desc": "The AD has requested that the Secretariat start an IETF Last Call, but the the actual Last Call message has not been sent yet." + } + }, + { + "pk": 15, + "model": "doc.state", + "fields": { + "used": true, + "name": "In Last Call", + "next_states": [ + 19, + 20 + ], + "slug": "lc", + "type": "draft-iesg", + "order": 16, + "desc": "The document is currently waiting for IETF Last Call to complete. Last Calls for WG documents typically last 2 weeks, those for individual submissions last 4 weeks." + } + }, + { + "pk": 19, + "model": "doc.state", + "fields": { + "used": true, + "name": "Waiting for Writeup", + "next_states": [ + 20 + ], + "slug": "writeupw", + "type": "draft-iesg", + "order": 18, + "desc": "Before a standards-track or BCP document is formally considered by the entire IESG, the AD must write up a protocol action. The protocol action is included in the approval message that the Secretariat sends out when the document is approved for publication as an RFC." + } + }, + { + "pk": 20, + "model": "doc.state", + "fields": { + "used": true, + "name": "Waiting for AD Go-Ahead", + "next_states": [ + 12 + ], + "slug": "goaheadw", + "type": "draft-iesg", + "order": 19, + "desc": "As a result of the IETF Last Call, comments may need to be responded to and a revision of the ID may be needed as well. The AD is responsible for verifying that all Last Call comments have been adequately addressed and that the (possibly revised) document is in the ID directory and ready for consideration by the IESG as a whole." + } + }, + { + "pk": 12, + "model": "doc.state", + "fields": { + "used": true, + "name": "IESG Evaluation", + "next_states": [ + 18, + 9, + 22 + ], + "slug": "iesg-eva", + "type": "draft-iesg", + "order": 20, + "desc": "The document is now (finally!) being formally reviewed by the entire IESG. Documents are discussed in email or during a bi-weekly IESG telechat. In this phase, each AD reviews the document and airs any issues they may have. Unresolvable issues are documented as \"discuss\" comments that can be forwarded to the authors/WG. See the description of substates for additional details about the current state of the IESG discussion." + } + }, + { + "pk": 18, + "model": "doc.state", + "fields": { + "used": true, + "name": "IESG Evaluation - Defer", + "next_states": [ + 12 + ], + "slug": "defer", + "type": "draft-iesg", + "order": 21, + "desc": "During a telechat, one or more ADs requested an additional 2 weeks to review the document. A defer is designed to be an exception mechanism, and can only be invoked once, the first time the document comes up for discussion during a telechat." + } + }, + { + "pk": 9, + "model": "doc.state", + "fields": { + "used": true, + "name": "Approved-announcement to be sent", + "next_states": [ + 10 + ], + "slug": "approved", + "type": "draft-iesg", + "order": 27, + "desc": "The IESG has approved the document for publication, but the Secretariat has not yet sent out on official approval message." + } + }, + { + "pk": 10, + "model": "doc.state", + "fields": { + "used": true, + "name": "Approved-announcement sent", + "next_states": [ + 17 + ], + "slug": "ann", + "type": "draft-iesg", + "order": 30, + "desc": "The IESG has approved the document for publication, and the Secretariat has sent out the official approval message to the RFC editor." + } + }, + { + "pk": 17, + "model": "doc.state", + "fields": { + "used": true, + "name": "RFC Ed Queue", + "next_states": [ + 7 + ], + "slug": "rfcqueue", + "type": "draft-iesg", + "order": 31, + "desc": "The document is in the RFC editor Queue (as confirmed by http://www.rfc-editor.org/queue.html)." + } + }, + { + "pk": 7, + "model": "doc.state", + "fields": { + "used": true, + "name": "RFC Published", + "next_states": [ + 8 + ], + "slug": "pub", + "type": "draft-iesg", + "order": 32, + "desc": "The ID has been published as an RFC." + } + }, + { + "pk": 22, + "model": "doc.state", + "fields": { + "used": true, + "name": "DNP-waiting for AD note", + "next_states": [ + 23 + ], + "slug": "nopubadw", + "type": "draft-iesg", + "order": 33, + "desc": "Do Not Publish: The IESG recommends against publishing the document, but the writeup explaining its reasoning has not yet been produced. DNPs apply primarily to individual submissions received through the RFC editor. See the \"note\" field for more details on who has the action item." + } + }, + { + "pk": 23, + "model": "doc.state", + "fields": { + "used": true, + "name": "DNP-announcement to be sent", + "next_states": [ + 8 + ], + "slug": "nopubanw", + "type": "draft-iesg", + "order": 34, + "desc": "The IESG recommends against publishing the document, the writeup explaining its reasoning has been produced, but the Secretariat has not yet sent out the official \"do not publish\" recommendation message." + } + }, + { + "pk": 11, + "model": "doc.state", + "fields": { + "used": true, + "name": "AD is watching", + "next_states": [ + 16 + ], + "slug": "watching", + "type": "draft-iesg", + "order": 42, + "desc": "An AD is aware of the document and has chosen to place the document in a separate state in order to keep a closer eye on it (for whatever reason). Documents in this state are still not being actively tracked in the sense that no formal request has been made to publish or advance the document. The sole difference between this state and \"I-D Exists\" is that an AD has chosen to put it in a separate state, to make it easier to keep track of (for the AD's own reasons)." + } + }, + { + "pk": 8, + "model": "doc.state", + "fields": { + "used": true, + "name": "Dead", + "next_states": [ + 16 + ], + "slug": "dead", + "type": "draft-iesg", + "order": 99, + "desc": "Document is \"dead\" and is no longer being tracked. (E.g., it has been replaced by another document with a different name, it has been withdrawn, etc.)" + } + }, + { + "pk": 24, + "model": "doc.state", + "fields": { + "used": true, + "name": "AUTH", + "next_states": [], + "slug": "auth", + "type": "draft-rfceditor", + "order": 0, + "desc": "Awaiting author action" + } + }, + { + "pk": 25, + "model": "doc.state", + "fields": { + "used": true, + "name": "AUTH48", + "next_states": [], + "slug": "auth48", + "type": "draft-rfceditor", + "order": 0, + "desc": "Awaiting final author approval" + } + }, + { + "pk": 26, + "model": "doc.state", + "fields": { + "used": false, + "name": "EDIT", + "next_states": [], + "slug": "edit", + "type": "draft-rfceditor", + "order": 0, + "desc": "Approved by the stream manager (e.g., IESG, IAB, IRSG, ISE), awaiting processing and publishing" + } + }, + { + "pk": 27, + "model": "doc.state", + "fields": { + "used": true, + "name": "IANA", + "next_states": [], + "slug": "iana", + "type": "draft-rfceditor", + "order": 0, + "desc": "Document has been edited, but is holding for completion of IANA actions" + } + }, + { + "pk": 28, + "model": "doc.state", + "fields": { + "used": false, + "name": "IESG", + "next_states": [], + "slug": "iesg", + "type": "draft-rfceditor", + "order": 0, + "desc": "Awaiting IESG action" + } + }, + { + "pk": 29, + "model": "doc.state", + "fields": { + "used": true, + "name": "ISR", + "next_states": [], + "slug": "isr", + "type": "draft-rfceditor", + "order": 0, + "desc": "Independent Submission Review by the ISE " + } + }, + { + "pk": 30, + "model": "doc.state", + "fields": { + "used": false, + "name": "ISR-AUTH", + "next_states": [], + "slug": "isr-auth", + "type": "draft-rfceditor", + "order": 0, + "desc": "Independent submission awaiting author action, or in discussion between author and ISE" + } + }, + { + "pk": 31, + "model": "doc.state", + "fields": { + "used": true, + "name": "REF", + "next_states": [], + "slug": "ref", + "type": "draft-rfceditor", + "order": 0, + "desc": "Holding for normative reference" + } + }, + { + "pk": 32, + "model": "doc.state", + "fields": { + "used": true, + "name": "RFC-EDITOR", + "next_states": [], + "slug": "rfc-edit", + "type": "draft-rfceditor", + "order": 0, + "desc": "Awaiting final RFC Editor review before AUTH48" + } + }, + { + "pk": 33, + "model": "doc.state", + "fields": { + "used": true, + "name": "TO", + "next_states": [], + "slug": "timeout", + "type": "draft-rfceditor", + "order": 0, + "desc": "Time-out period during which the IESG reviews document for conflict/concurrence with other IETF working group work" + } + }, + { + "pk": 34, + "model": "doc.state", + "fields": { + "used": true, + "name": "MISSREF", + "next_states": [], + "slug": "missref", + "type": "draft-rfceditor", + "order": 0, + "desc": "Awaiting missing normative reference" + } + }, + { + "pk": 89, + "model": "doc.state", + "fields": { + "used": false, + "name": "AUTH48-DONE", + "next_states": [ + 74 + ], + "slug": "auth48done", + "type": "draft-rfceditor", + "order": 0, + "desc": "Final approvals are complete" + } + }, + { + "pk": 116, + "model": "doc.state", + "fields": { + "used": true, + "name": "AUTH48-DONE", + "next_states": [], + "slug": "auth48-done", + "type": "draft-rfceditor", + "order": 0, + "desc": "Final approvals are complete" + } + }, + { + "pk": 117, + "model": "doc.state", + "fields": { + "used": true, + "name": "EDIT", + "next_states": [], + "slug": "edit", + "type": "draft-rfceditor", + "order": 0, + "desc": "Approved by the stream manager (e.g., IESG, IAB, IRSG, ISE), awaiting processing and publishing" + } + }, + { + "pk": 118, + "model": "doc.state", + "fields": { + "used": true, + "name": "IANA", + "next_states": [], + "slug": "iana-crd", + "type": "draft-rfceditor", + "order": 0, + "desc": "RFC-Editor/IANA Registration Coordination" + } + }, + { + "pk": 119, + "model": "doc.state", + "fields": { + "used": true, + "name": "IESG", + "next_states": [], + "slug": "iesg", + "type": "draft-rfceditor", + "order": 0, + "desc": "Holding for IESG action" + } + }, + { + "pk": 120, + "model": "doc.state", + "fields": { + "used": true, + "name": "ISR-AUTH", + "next_states": [], + "slug": "isr-auth", + "type": "draft-rfceditor", + "order": 0, + "desc": "Independent Submission awaiting author update, or in discussion between author and ISE" + } + }, + { + "pk": 133, + "model": "doc.state", + "fields": { + "used": true, + "name": "Pending", + "next_states": [], + "slug": "pending", + "type": "draft-rfceditor", + "order": 0, + "desc": "" + } + }, + { + "pk": 45, + "model": "doc.state", + "fields": { + "used": true, + "name": "Candidate IAB Document", + "next_states": [], + "slug": "candidat", + "type": "draft-stream-iab", + "order": 1, + "desc": "A document being considered for the IAB stream." + } + }, + { + "pk": 46, + "model": "doc.state", + "fields": { + "used": true, + "name": "Active IAB Document", + "next_states": [], + "slug": "active", + "type": "draft-stream-iab", + "order": 2, + "desc": "This document has been adopted by the IAB and is being actively developed." + } + }, + { + "pk": 47, + "model": "doc.state", + "fields": { + "used": true, + "name": "Parked IAB Document", + "next_states": [], + "slug": "parked", + "type": "draft-stream-iab", + "order": 3, + "desc": "This document has lost its author or editor, is waiting for another document to be written, or cannot currently be worked on by the IAB for some other reason. Annotations probably explain why this document is parked." + } + }, + { + "pk": 48, + "model": "doc.state", + "fields": { + "used": true, + "name": "IAB Review", + "next_states": [], + "slug": "review-i", + "type": "draft-stream-iab", + "order": 4, + "desc": "This document is awaiting the IAB itself to come to internal consensus." + } + }, + { + "pk": 49, + "model": "doc.state", + "fields": { + "used": true, + "name": "Community Review", + "next_states": [], + "slug": "review-c", + "type": "draft-stream-iab", + "order": 5, + "desc": "This document has completed internal consensus within the IAB and is now under community review." + } + }, + { + "pk": 50, + "model": "doc.state", + "fields": { + "used": true, + "name": "Approved by IAB, To Be Sent to RFC Editor", + "next_states": [], + "slug": "approved", + "type": "draft-stream-iab", + "order": 6, + "desc": "The consideration of this document is complete, but it has not yet been sent to the RFC Editor for publication (although that is going to happen soon)." + } + }, + { + "pk": 51, + "model": "doc.state", + "fields": { + "used": true, + "name": "Sent to a Different Organization for Publication", + "next_states": [], + "slug": "diff-org", + "type": "draft-stream-iab", + "order": 7, + "desc": "The IAB does not expect to publish the document itself, but has passed it on to a different organization that might continue work on the document. The expectation is that the other organization will eventually publish the document." + } + }, + { + "pk": 52, + "model": "doc.state", + "fields": { + "used": true, + "name": "Sent to the RFC Editor", + "next_states": [], + "slug": "rfc-edit", + "type": "draft-stream-iab", + "order": 8, + "desc": "The IAB processing of this document is complete and it has been sent to the RFC Editor for publication. The document may be in the RFC Editor's queue, or it may have been published as an RFC; this state doesn't distinguish between different states occurring after the document has left the IAB." + } + }, + { + "pk": 53, + "model": "doc.state", + "fields": { + "used": true, + "name": "Published RFC", + "next_states": [], + "slug": "pub", + "type": "draft-stream-iab", + "order": 9, + "desc": "The document has been published as an RFC." + } + }, + { + "pk": 54, + "model": "doc.state", + "fields": { + "used": true, + "name": "Dead IAB Document", + "next_states": [], + "slug": "dead", + "type": "draft-stream-iab", + "order": 10, + "desc": "This document was an active IAB document, but for some reason it is no longer being pursued for the IAB stream. It is possible that the document might be revived later, possibly in another stream." + } + }, + { + "pk": 134, + "model": "doc.state", + "fields": { + "used": true, + "name": "Candidate for WG Adoption", + "next_states": [ + 35 + ], + "slug": "wg-cand", + "type": "draft-stream-ietf", + "order": 0, + "desc": "The document has been marked as a candidate for WG adoption by the WG Chair. This state can be used before a call for adoption is issued (and the document is put in the \"Call For Adoption By WG Issued\" state), to indicate that the document is in the queue for a call for adoption, even if none has been issued yet." + } + }, + { + "pk": 35, + "model": "doc.state", + "fields": { + "used": true, + "name": "Call For Adoption By WG Issued", + "next_states": [ + 36, + 37 + ], + "slug": "c-adopt", + "type": "draft-stream-ietf", + "order": 1, + "desc": "4.2.1. Call for Adoption by WG Issued\n\n The \"Call for Adoption by WG Issued\" state should be used to indicate when an I-D is being considered for adoption by an IETF WG. An I-D that is in this state is actively being considered for adoption and has not yet achieved consensus, preference, or selection in the WG.\n\n This state may be used to describe an I-D that someone has asked a WG to consider for adoption, if the WG Chair has agreed with the request. This state may also be used to identify an I-D that a WG Chair asked an author to write specifically for consideration as a candidate WG item [WGDTSPEC], and/or an I-D that is listed as a 'candidate draft' in the WG's charter.\n\n Under normal conditions, it should not be possible for an I-D to be in the \"Call for Adoption by WG Issued\" state in more than one working group at the same time. This said, it is not uncommon for authors to \"shop\" their I-Ds to more than one WG at a time, with the hope of getting their documents adopted somewhere.\n\n After this state is implemented in the Datatracker, an I-D that is in the \"Call for Adoption by WG Issued\" state will not be able to be \"shopped\" to any other WG without the consent of the WG Chairs and the responsible ADs impacted by the shopping.\n\n Note that Figure 1 includes an arc leading from this state to outside of the WG state machine. This illustrates that some I-Ds that are considered do not get adopted as WG drafts. An I-D that is not adopted as a WG draft will transition out of the WG state machine and revert back to having no stream-specific state; however, the status change history log of the I-D will record that the I-D was previously in the \"Call for Adoption by WG Issued\" state." + } + }, + { + "pk": 36, + "model": "doc.state", + "fields": { + "used": true, + "name": "Adopted by a WG", + "next_states": [ + 38 + ], + "slug": "adopt-wg", + "type": "draft-stream-ietf", + "order": 2, + "desc": "4.2.2. Adopted by a WG\n\n The \"Adopted by a WG\" state describes an individual submission I-D that an IETF WG has agreed to adopt as one of its WG drafts.\n\n WG Chairs who use this state will be able to clearly indicate when their WGs adopt individual submission I-Ds. This will facilitate the Datatracker's ability to correctly capture \"Replaces\" information for WG drafts and correct \"Replaced by\" information for individual submission I-Ds that have been replaced by WG drafts.\n\n This state is needed because the Datatracker uses the filename of an I-D as a key to search its database for status information about the I-D, and because the filename of a WG I-D is supposed to be different from the filename of an individual submission I-D. The filename of an individual submission I-D will typically be formatted as 'draft-author-wgname-topic-nn'.\n\n The filename of a WG document is supposed to be formatted as 'draft- ietf-wgname-topic-nn'.\n\n An individual I-D that is adopted by a WG may take weeks or months to be resubmitted by the author as a new (version-00) WG draft. If the \"Adopted by a WG\" state is not used, the Datatracker has no way to determine that an I-D has been adopted until a new version of the I-D is submitted to the WG by the author and until the I-D is approved for posting by a WG Chair." + } + }, + { + "pk": 37, + "model": "doc.state", + "fields": { + "used": true, + "name": "Adopted for WG Info Only", + "next_states": [], + "slug": "info", + "type": "draft-stream-ietf", + "order": 3, + "desc": "4.2.3. Adopted for WG Info Only\n\n The \"Adopted for WG Info Only\" state describes a document that contains useful information for the WG that adopted it, but the document is not intended to be published as an RFC. The WG will not actively develop the contents of the I-D or progress it for publication as an RFC. The only purpose of the I-D is to provide information for internal use by the WG." + } + }, + { + "pk": 38, + "model": "doc.state", + "fields": { + "used": true, + "name": "WG Document", + "next_states": [ + 39, + 40, + 41, + 43 + ], + "slug": "wg-doc", + "type": "draft-stream-ietf", + "order": 4, + "desc": "4.2.4. WG Document\n\n The \"WG Document\" state describes an I-D that has been adopted by an IETF WG and is being actively developed.\n\n A WG Chair may transition an I-D into the \"WG Document\" state at any time as long as the I-D is not being considered or developed in any other WG.\n\n Alternatively, WG Chairs may rely upon new functionality to be added to the Datatracker to automatically move version-00 drafts into the \"WG Document\" state as described in Section 4.1.\n\n Under normal conditions, it should not be possible for an I-D to be in the \"WG Document\" state in more than one WG at a time. This said, I-Ds may be transferred from one WG to another with the consent of the WG Chairs and the responsible ADs." + } + }, + { + "pk": 39, + "model": "doc.state", + "fields": { + "used": true, + "name": "Parked WG Document", + "next_states": [ + 38 + ], + "slug": "parked", + "type": "draft-stream-ietf", + "order": 5, + "desc": "4.2.5. Parked WG Document\n\n A \"Parked WG Document\" is an I-D that has lost its author or editor, is waiting for another document to be written or for a review to be completed, or cannot be progressed by the working group for some other reason.\n\n Some of the annotation tags described in Section 4.3 may be used in conjunction with this state to indicate why an I-D has been parked, and/or what may need to happen for the I-D to be un-parked.\n\n Parking a WG draft will not prevent it from expiring; however, this state can be used to indicate why the I-D has stopped progressing in the WG.\n\n A \"Parked WG Document\" that is not expired may be transferred from one WG to another with the consent of the WG Chairs and the responsible ADs." + } + }, + { + "pk": 40, + "model": "doc.state", + "fields": { + "used": true, + "name": "Dead WG Document", + "next_states": [ + 38 + ], + "slug": "dead", + "type": "draft-stream-ietf", + "order": 6, + "desc": "4.2.6. Dead WG Document\n\n A \"Dead WG Document\" is an I-D that has been abandoned. Note that 'Dead' is not always a final state for a WG I-D. If consensus is subsequently achieved, a \"Dead WG Document\" may be resurrected. A \"Dead WG Document\" that is not resurrected will eventually expire.\n\n Note that an I-D that is declared to be \"Dead\" in one WG and that is not expired may be transferred to a non-dead state in another WG with the consent of the WG Chairs and the responsible ADs." + } + }, + { + "pk": 41, + "model": "doc.state", + "fields": { + "used": true, + "name": "In WG Last Call", + "next_states": [ + 38, + 42, + 43 + ], + "slug": "wg-lc", + "type": "draft-stream-ietf", + "order": 7, + "desc": "4.2.7. In WG Last Call\n\n A document \"In WG Last Call\" is an I-D for which a WG Last Call (WGLC) has been issued and is in progress.\n\n Note that conducting a WGLC is an optional part of the IETF WG process, per Section 7.4 of RFC 2418 [RFC2418].\n\n If a WG Chair decides to conduct a WGLC on an I-D, the \"In WG Last Call\" state can be used to track the progress of the WGLC. The Chair may configure the Datatracker to send a WGLC message to one or more mailing lists when the Chair moves the I-D into this state. The WG Chair may also be able to select a different set of mailing lists for a different document undergoing a WGLC; some documents may deserve coordination with other WGs.\n\n A WG I-D in this state should remain \"In WG Last Call\" until the WG Chair moves it to another state. The WG Chair may configure the Datatracker to send an e-mail after a specified period of time to remind or 'nudge' the Chair to conclude the WGLC and to determine the next state for the document.\n\n It is possible for one WGLC to lead into another WGLC for the same document. For example, an I-D that completed a WGLC as an \"Informational\" document may need another WGLC if a decision is taken to convert the I-D into a Standards Track document." + } + }, + { + "pk": 42, + "model": "doc.state", + "fields": { + "used": true, + "name": "Waiting for WG Chair Go-Ahead", + "next_states": [ + 41, + 43 + ], + "slug": "chair-w", + "type": "draft-stream-ietf", + "order": 8, + "desc": "4.2.8. Waiting for WG Chair Go-Ahead\n\n A WG Chair may wish to place an I-D that receives a lot of comments during a WGLC into the \"Waiting for WG Chair Go-Ahead\" state. This state describes an I-D that has undergone a WGLC; however, the Chair is not yet ready to call consensus on the document.\n\n If comments from the WGLC need to be responded to, or a revision to the I-D is needed, the Chair may place an I-D into this state until all of the WGLC comments are adequately addressed and the (possibly revised) document is in the I-D repository." + } + }, + { + "pk": 43, + "model": "doc.state", + "fields": { + "used": true, + "name": "WG Consensus: Waiting for Write-Up", + "next_states": [ + 44 + ], + "slug": "writeupw", + "type": "draft-stream-ietf", + "order": 9, + "desc": "4.2.9. WG Consensus: Waiting for Writeup\n\n A document in the \"WG Consensus: Waiting for Writeup\" state has essentially completed its development within the working group, and is nearly ready to be sent to the IESG for publication. The last thing to be done is the preparation of a protocol writeup by a Document Shepherd. The IESG requires that a document shepherd writeup be completed before publication of the I-D is requested. The IETF document shepherding process and the role of a WG Document Shepherd is described in RFC 4858 [RFC4858]\n\n A WG Chair may call consensus on an I-D without a formal WGLC and transition an I-D that was in the \"WG Document\" state directly into this state.\n\n The name of this state includes the words \"Waiting for Writeup\" because a good document shepherd writeup takes time to prepare." + } + }, + { + "pk": 44, + "model": "doc.state", + "fields": { + "used": true, + "name": "Submitted to IESG for Publication", + "next_states": [ + 38 + ], + "slug": "sub-pub", + "type": "draft-stream-ietf", + "order": 10, + "desc": "4.2.10. Submitted to IESG for Publication\n\n This state describes a WG document that has been submitted to the IESG for publication and that has not been sent back to the working group for revision.\n\n An I-D in this state may be under review by the IESG, it may have been approved and be in the RFC Editor's queue, or it may have been published as an RFC. Other possibilities exist too. The document may be \"Dead\" (in the IESG state machine) or in a \"Do Not Publish\" state." + } + }, + { + "pk": 55, + "model": "doc.state", + "fields": { + "used": true, + "name": "Candidate RG Document", + "next_states": [], + "slug": "candidat", + "type": "draft-stream-irtf", + "order": 1, + "desc": "This document is under consideration in an RG for becoming an IRTF document. A document in this state does not imply any RG consensus and does not imply any precedence or selection. It's simply a way to indicate that somebody has asked for a document to be considered for adoption by an RG." + } + }, + { + "pk": 56, + "model": "doc.state", + "fields": { + "used": true, + "name": "Active RG Document", + "next_states": [], + "slug": "active", + "type": "draft-stream-irtf", + "order": 2, + "desc": "This document has been adopted by the RG and is being actively developed." + } + }, + { + "pk": 57, + "model": "doc.state", + "fields": { + "used": true, + "name": "Parked RG Document", + "next_states": [], + "slug": "parked", + "type": "draft-stream-irtf", + "order": 3, + "desc": "This document has lost its author or editor, is waiting for another document to be written, or cannot currently be worked on by the RG for some other reason." + } + }, + { + "pk": 58, + "model": "doc.state", + "fields": { + "used": true, + "name": "In RG Last Call", + "next_states": [], + "slug": "rg-lc", + "type": "draft-stream-irtf", + "order": 4, + "desc": "The document is in its final review in the RG." + } + }, + { + "pk": 59, + "model": "doc.state", + "fields": { + "used": true, + "name": "Waiting for Document Shepherd", + "next_states": [], + "slug": "sheph-w", + "type": "draft-stream-irtf", + "order": 5, + "desc": "IRTF documents have document shepherds who help RG documents through the process after the RG has finished with the document." + } + }, + { + "pk": 60, + "model": "doc.state", + "fields": { + "used": true, + "name": "Waiting for IRTF Chair", + "next_states": [], + "slug": "chair-w", + "type": "draft-stream-irtf", + "order": 6, + "desc": "The IRTF Chair is meant to be performing some task such as sending a request for IESG Review." + } + }, + { + "pk": 61, + "model": "doc.state", + "fields": { + "used": true, + "name": "Awaiting IRSG Reviews", + "next_states": [], + "slug": "irsg-w", + "type": "draft-stream-irtf", + "order": 7, + "desc": "The document shepherd has taken the document to the IRSG and solicited reviews from one or more IRSG members." + } + }, + { + "pk": 62, + "model": "doc.state", + "fields": { + "used": true, + "name": "In IRSG Poll", + "next_states": [], + "slug": "irsgpoll", + "type": "draft-stream-irtf", + "order": 8, + "desc": "The IRSG is taking a poll on whether or not the document is ready to be published." + } + }, + { + "pk": 63, + "model": "doc.state", + "fields": { + "used": true, + "name": "In IESG Review", + "next_states": [], + "slug": "iesg-rev", + "type": "draft-stream-irtf", + "order": 9, + "desc": "The IRSG has asked the IESG to do a review of the document, as described in RFC5742." + } + }, + { + "pk": 64, + "model": "doc.state", + "fields": { + "used": true, + "name": "Sent to the RFC Editor", + "next_states": [], + "slug": "rfc-edit", + "type": "draft-stream-irtf", + "order": 10, + "desc": "The RG processing of this document is complete and it has been sent to the RFC Editor for publication. The document may be in the RFC Editor's queue, or it may have been published as an RFC; this state doesn't distinguish between different states occurring after the document has left the RG." + } + }, + { + "pk": 65, + "model": "doc.state", + "fields": { + "used": true, + "name": "Published RFC", + "next_states": [], + "slug": "pub", + "type": "draft-stream-irtf", + "order": 11, + "desc": "The document has been published as an RFC." + } + }, + { + "pk": 66, + "model": "doc.state", + "fields": { + "used": true, + "name": "Document on Hold Based On IESG Request", + "next_states": [], + "slug": "iesghold", + "type": "draft-stream-irtf", + "order": 12, + "desc": "The IESG has requested that the document be held pending further review, as specified in RFC 5742, and the IRTF has agreed to such a hold." + } + }, + { + "pk": 67, + "model": "doc.state", + "fields": { + "used": true, + "name": "Dead IRTF Document", + "next_states": [], + "slug": "dead", + "type": "draft-stream-irtf", + "order": 13, + "desc": "This document was an active IRTF document, but for some reason it is no longer being pursued for the IRTF stream. It is possible that the document might be revived later, possibly in another stream." + } + }, + { + "pk": 68, + "model": "doc.state", + "fields": { + "used": true, + "name": "Submission Received", + "next_states": [], + "slug": "receive", + "type": "draft-stream-ise", + "order": 1, + "desc": "The draft has been sent to the ISE with a request for publication." + } + }, + { + "pk": 69, + "model": "doc.state", + "fields": { + "used": true, + "name": "Finding Reviewers", + "next_states": [], + "slug": "find-rev", + "type": "draft-stream-ise", + "order": 2, + "desc": " The ISE is finding initial reviewers for the document." + } + }, + { + "pk": 70, + "model": "doc.state", + "fields": { + "used": true, + "name": "In ISE Review", + "next_states": [], + "slug": "ise-rev", + "type": "draft-stream-ise", + "order": 3, + "desc": "The ISE is actively working on the document." + } + }, + { + "pk": 71, + "model": "doc.state", + "fields": { + "used": true, + "name": "Response to Review Needed", + "next_states": [], + "slug": "need-res", + "type": "draft-stream-ise", + "order": 4, + "desc": " One or more reviews have been sent to the author, and the ISE is awaiting response." + } + }, + { + "pk": 72, + "model": "doc.state", + "fields": { + "used": true, + "name": "In IESG Review", + "next_states": [], + "slug": "iesg-rev", + "type": "draft-stream-ise", + "order": 5, + "desc": "The ISE has asked the IESG to do a review of the document, as described in RFC5742." + } + }, + { + "pk": 73, + "model": "doc.state", + "fields": { + "used": true, + "name": "Sent to the RFC Editor", + "next_states": [], + "slug": "rfc-edit", + "type": "draft-stream-ise", + "order": 6, + "desc": "The ISE processing of this document is complete and it has been sent to the RFC Editor for publication. The document may be in the RFC Editor's queue, or it may have been published as an RFC; this state doesn't distinguish between different states occurring after the document has left the ISE." + } + }, + { + "pk": 74, + "model": "doc.state", + "fields": { + "used": true, + "name": "Published RFC", + "next_states": [], + "slug": "pub", + "type": "draft-stream-ise", + "order": 7, + "desc": "The document has been published as an RFC." + } + }, + { + "pk": 75, + "model": "doc.state", + "fields": { + "used": true, + "name": "No Longer In Independent Submission Stream", + "next_states": [], + "slug": "dead", + "type": "draft-stream-ise", + "order": 8, + "desc": "This document was actively considered in the Independent Submission stream, but the ISE chose not to publish it. It is possible that the document might be revived later. A document in this state may have a comment explaining the reasoning of the ISE (such as if the document was going to move to a different stream)." + } + }, + { + "pk": 76, + "model": "doc.state", + "fields": { + "used": true, + "name": "Document on Hold Based On IESG Request", + "next_states": [], + "slug": "iesghold", + "type": "draft-stream-ise", + "order": 9, + "desc": "The IESG has requested that the document be held pending further review, as specified in RFC 5742, and the ISE has agreed to such a hold." + } + }, + { + "pk": 79, + "model": "doc.state", + "fields": { + "used": true, + "name": "Active", + "next_states": [], + "slug": "active", + "type": "minutes", + "order": 1, + "desc": "" + } + }, + { + "pk": 80, + "model": "doc.state", + "fields": { + "used": true, + "name": "Deleted", + "next_states": [], + "slug": "deleted", + "type": "minutes", + "order": 2, + "desc": "" + } + }, + { + "pk": 77, + "model": "doc.state", + "fields": { + "used": true, + "name": "Active", + "next_states": [], + "slug": "active", + "type": "slides", + "order": 1, + "desc": "" + } + }, + { + "pk": 78, + "model": "doc.state", + "fields": { + "used": true, + "name": "Deleted", + "next_states": [], + "slug": "deleted", + "type": "slides", + "order": 2, + "desc": "" + } + }, + { + "pk": 121, + "model": "doc.state", + "fields": { + "used": true, + "name": "Needs Shepherd", + "next_states": [ + 122, + 129 + ], + "slug": "needshep", + "type": "statchg", + "order": 1, + "desc": "An RFC status change has been requested, but a shepherding AD has not yet been assigned" + } + }, + { + "pk": 122, + "model": "doc.state", + "fields": { + "used": true, + "name": "AD Review", + "next_states": [ + 130, + 123, + 129 + ], + "slug": "adrev", + "type": "statchg", + "order": 2, + "desc": "The sponsoring AD is preparing an RFC status change document" + } + }, + { + "pk": 130, + "model": "doc.state", + "fields": { + "used": true, + "name": "Last Call Requested", + "next_states": [ + 131 + ], + "slug": "lc-req", + "type": "statchg", + "order": 3, + "desc": "Last Call has been requested for this proposed status change" + } + }, + { + "pk": 131, + "model": "doc.state", + "fields": { + "used": true, + "name": "In Last Call", + "next_states": [ + 132 + ], + "slug": "in-lc", + "type": "statchg", + "order": 4, + "desc": "This proposed status change is in IETF Last Call" + } + }, + { + "pk": 132, + "model": "doc.state", + "fields": { + "used": true, + "name": "Waiting for AD Go-Ahead", + "next_states": [ + 123, + 129 + ], + "slug": "goahead", + "type": "statchg", + "order": 5, + "desc": "The AD is following up on IETF LC comments" + } + }, + { + "pk": 123, + "model": "doc.state", + "fields": { + "used": true, + "name": "IESG Evaluation", + "next_states": [ + 124, + 125, + 126, + 129 + ], + "slug": "iesgeval", + "type": "statchg", + "order": 6, + "desc": "The IESG is considering the proposed RFC status changes" + } + }, + { + "pk": 124, + "model": "doc.state", + "fields": { + "used": true, + "name": "IESG Evaluation - Defer", + "next_states": [ + 123, + 125, + 126, + 129 + ], + "slug": "defer", + "type": "statchg", + "order": 7, + "desc": "The evaluation of the proposed RFC status changes have been deferred to the next telechat" + } + }, + { + "pk": 125, + "model": "doc.state", + "fields": { + "used": true, + "name": "Approved - point raised", + "next_states": [ + 126, + 127 + ], + "slug": "appr-pr", + "type": "statchg", + "order": 8, + "desc": "The IESG has approved the RFC status changes, but a point has been raised that should be cleared before proceeding to announcement to be sent" + } + }, + { + "pk": 126, + "model": "doc.state", + "fields": { + "used": true, + "name": "Approved - announcement to be sent", + "next_states": [ + 127 + ], + "slug": "appr-pend", + "type": "statchg", + "order": 9, + "desc": "The IESG has approved the RFC status changes, but the secretariat has not yet sent the announcement" + } + }, + { + "pk": 127, + "model": "doc.state", + "fields": { + "used": true, + "name": "Approved - announcement sent", + "next_states": [], + "slug": "appr-sent", + "type": "statchg", + "order": 10, + "desc": "The secretariat has announced the IESG's approved RFC status changes" + } + }, + { + "pk": 129, + "model": "doc.state", + "fields": { + "used": true, + "name": "Dead", + "next_states": [ + 121 + ], + "slug": "dead", + "type": "statchg", + "order": 11, + "desc": "The RFC status changes have been abandoned" + } + }, + { + "pk": 5, + "model": "doc.ballottype", + "fields": { + "doc_type": "conflrev", + "used": true, + "name": "Approve", + "positions": [ + "yes", + "noobj", + "discuss", + "abstain", + "recuse", + "norecord" + ], + "question": "Is this the correct conflict review response?", + "slug": "conflrev", + "order": 0 + } + }, + { + "pk": 6, + "model": "doc.ballottype", + "fields": { + "doc_type": "statchg", + "used": true, + "name": "Approve", + "positions": [ + "yes", + "noobj", + "discuss", + "abstain", + "recuse", + "norecord" + ], + "question": "Do we approve these RFC status changes?", + "slug": "statchg", + "order": 0 + } + }, + { + "pk": 1, + "model": "doc.ballottype", + "fields": { + "doc_type": "charter", + "used": true, + "name": "Ready for external review", + "positions": [ + "yes", + "noobj", + "block", + "abstain", + "norecord" + ], + "question": "Is this charter ready for external review?", + "slug": "r-extrev", + "order": 1 + } + }, + { + "pk": 4, + "model": "doc.ballottype", + "fields": { + "doc_type": "draft", + "used": true, + "name": "Approve", + "positions": [ + "yes", + "noobj", + "discuss", + "abstain", + "recuse", + "norecord" + ], + "question": "", + "slug": "approve", + "order": 1 + } + }, + { + "pk": 2, + "model": "doc.ballottype", + "fields": { + "doc_type": "charter", + "used": true, + "name": "Ready w/o external review", + "positions": [ + "yes", + "noobj", + "block", + "abstain", + "norecord" + ], + "question": "Is this charter ready for external review? Is this charter ready for approval without external review?", + "slug": "r-wo-ext", + "order": 2 + } + }, + { + "pk": 3, + "model": "doc.ballottype", + "fields": { + "doc_type": "charter", + "used": true, + "name": "Approve", + "positions": [ + "yes", + "noobj", + "block", + "abstain", + "norecord" + ], + "question": "Do we approve of this charter?", + "slug": "approve", + "order": 3 + } + } +] \ No newline at end of file diff --git a/ietf/name/fixtures/names.xml b/ietf/name/fixtures/names.xml deleted file mode 100644 index 93b326aa7..000000000 --- a/ietf/name/fixtures/names.xml +++ /dev/null @@ -1,2280 +0,0 @@ - - - - Yes - - True - 1 - False - - - No Objection - - True - 2 - False - - - Discuss - - True - 3 - True - - - Block - - True - 3 - True - - - Abstain - - True - 4 - False - - - Recuse - - True - 5 - False - - - No Record - - True - 6 - False - - - Conflicts with - - True - 0 - - - Conflicts with (secondary) - - True - 0 - - - Conflicts with (tertiary) - - True - 0 - - - Person must be present - - True - 0 - - - Obsoletes - - True - 0 - Obsoleted by - - - Updates - - True - 0 - Updated by - - - Replaces - - True - 0 - Replaced by - - - conflict reviews - - True - 0 - Conflict reviewed by - - - Normative Reference - Normative Reference - True - 0 - fixme - - - Reference - A reference found in a document which does not have split normative/informative reference sections. - True - 0 - fixme - - - Informative Reference - Informative Reference - True - 0 - fixme - - - Moves to Proposed Standard - - True - 0 - Moved to Proposed Standard by - - - Moves to Internet Standard - - True - 0 - Moved to Internet Standard by - - - Moves to Historic - - True - 0 - Moved to Historic by - - - Moves to Informational - - True - 0 - Moved to Informational by - - - Moves to BCP - - True - 0 - Moved to BCP by - - - Moves to Experimental - - True - 0 - Moved to Experimental by - - - Possible Reference - Reference of unknown type, likely found in the text of the document. - True - 3 - fixme - - - Stream state should change - - True - 0 - - - IANA coordination - RFC-Editor/IANA Registration Coordination - True - 0 - - - Holding for references - Holding for normative reference - True - 0 - - - Missing references - Awaiting missing normative reference - True - 0 - - - Has errata - - True - 0 - - - Review by RFC Editor - - True - 0 - - - Via RFC Editor - - True - 0 - - - Approved in minutes - - True - 0 - - - Shepherd Needed - - True - 0 - - - Waiting for Dependency on Other Document - - True - 0 - - - IESG Review Completed - - True - 0 - - - IANA - The document has IANA actions that are not yet completed. - True - 0 - - - Revised I-D Needed - Issue raised by WG - - True - 0 - - - Point Raised - writeup needed - IESG discussions on the document have raised some issues that need to be brought to the attention of the authors/WG, but those issues have not been written down yet. (It is common for discussions during a telechat to result in such situations. An AD may raise a possible issue during a telechat and only decide as a result of that discussion whether the issue is worth formally writing up and bringing to the attention of the authors/WG). A document stays in the "Point Raised - Writeup Needed" state until *ALL* IESG comments that have been raised have been documented. - True - 1 - - - Awaiting Expert Review/Resolution of Issues Raised - - True - 1 - - - Editor Needed - - True - 1 - - - AD Followup - A generic substate indicating that the shepherding AD has the action item to determine appropriate next steps. In particular, the appropriate steps (and the corresponding next state or substate) depend entirely on the nature of the issues that were raised and can only be decided with active involvement of the shepherding AD. Examples include: - -- if another AD raises an issue, the shepherding AD may first iterate with the other AD to get a better understanding of the exact issue. Or, the shepherding AD may attempt to argue that the issue is not serious enough to bring to the attention of the authors/WG. - -- if a documented issue is forwarded to a WG, some further iteration may be needed before it can be determined whether a new revision is needed or whether the WG response to an issue clarifies the issue sufficiently. - -- when a new revision appears, the shepherding AD will first look at the changes to determine whether they believe all outstanding issues have been raised satisfactorily, prior to asking the ADs who raised the original issues to verify the changes. - True - 2 - - - Awaiting External Review/Resolution of Issues Raised - - True - 2 - - - Waiting for Partner Feedback - - True - 2 - - - External Party - The document is awaiting review or input from an external party (i.e, someone other than the shepherding AD, the authors, or the WG). See the "note" field for more details on who has the action. - True - 3 - - - Awaiting Merge with Other Document - - True - 3 - - - Awaiting Reviews - - True - 3 - - - Author or Editor Needed - - True - 4 - - - Document Shepherd Followup - - True - 4 - - - Revised I-D Needed - An updated I-D is needed to address the issues that have been raised. - True - 5 - - - Waiting for Referenced Document - - True - 5 - - - Waiting for Referencing Document - - True - 6 - - - Revised I-D Needed - Issue raised by WGLC - - True - 7 - - - Revised I-D Needed - Issue raised by AD - - True - 8 - - - Revised I-D Needed - Issue raised by IESG - - True - 9 - - - Doc Shepherd Follow-up Underway - - True - 10 - - - Other - see Comment Log - - True - 11 - - - Charter - - True - 0 - - - Agenda - - True - 0 - - - Minutes - - True - 0 - - - Slides - - True - 0 - - - Draft - - True - 0 - - - Liaison Attachment - - True - 0 - - - Conflict Review - - True - 0 - - - Status Change - - True - 0 - - - Active - - True - 1 - - - Deleted - - True - 2 - - - For review - - True - 3 - - - Chartering/rechartering - - True - 4 - - - BOF - - True - 0 - - - Proposed - - True - 0 - - - Active - - True - 0 - - - Dormant - - True - 0 - - - Concluded - - True - 0 - - - Unknown - - True - 0 - - - Abandonded - Formation of the group (most likely a BoF or Proposed WG) was abandoned - True - 0 - - - BOF Concluded - - True - 0 - - - IETF - - True - 0 - - - Area - - True - 0 - - - AG - Area group - True - 0 - - - WG - Working group - True - 0 - - - RG - Research group - True - 0 - - - Team - - True - 0 - - - Individual - - True - 0 - - - SDO - Standards organization - True - 0 - - - IRTF - - True - 0 - - - RFC Editor - - True - 0 - - - NomCom - - True - 0 - - - Proposed Standard - - True - 1 - - - Draft Standard - - False - 2 - - - Internet Standard - - True - 3 - - - Best Current Practice - - True - 4 - - - Informational - - True - 5 - - - Experimental - - True - 6 - - - Historic - - True - 7 - - - For action - - True - 1 - - - For comment - - True - 2 - - - For information - - True - 3 - - - In response - - True - 4 - - - Pending - - True - 0 - - - Accepted - - True - 0 - - - Declined - - True - 0 - - - Comment - - True - 0 - - - Questionnaire response - - True - 0 - - - Nomination - - True - 0 - - - Offtopic - - True - 0 - - - reStructuredText - - True - 0 - - - Plain - - True - 0 - - - Django - - True - 0 - - - IETF - - True - 0 - - - Interim - - True - 0 - - - Area Director - - True - 0 - - - Incoming Area Director - - True - 0 - - - Chair - - True - 0 - - - Editor - - True - 0 - - - Secretary - - True - 0 - - - Tech Advisor - - True - 0 - - - Executive Director - - True - 0 - - - Administrative Director - - True - 0 - - - Liaison Manager - - True - 0 - - - Authorized Individual - - True - 0 - - - Delegate - - True - 0 - - - At Large Member - - True - 0 - - - Member - - True - 0 - - - Waiting for Scheduling - - True - 0 - - - Waiting for Approval - - True - 0 - - - Approved - - True - 0 - - - Scheduled - - True - 0 - - - Canceled - - True - 0 - - - Disapproved - - True - 0 - - - Not meeting - - True - 0 - - - Deleted - - True - 0 - - - Internet Standard - - True - 0 - - - Draft Standard - - False - 0 - - - Proposed Standard - - True - 0 - - - Informational - - True - 0 - - - Experimental - - True - 0 - - - Best Current Practice - - True - 0 - - - Historic - - True - 0 - - - Unknown - - True - 0 - - - IETF - IETF stream - True - 1 - - - ISE - Independent Submission Editor stream - True - 2 - - - IRTF - Independent Submission Editor stream - True - 3 - - - IAB - IAB stream - True - 4 - - - Legacy - Legacy stream - True - 5 - - - Other - - True - 0 - - - Session - - True - 0 - - - Break - - True - 0 - - - Registration - - True - 0 - - - Plenary - - True - 0 - - - State - - - IESG state - - - IANA state - - - RFC Editor state - - - IETF WG state - - - IRTF state - - - ISE state - - - IAB state - - - State - - - State - - - State - - - State - - - State - - - Conflict Review State - - - IANA Action state - - - IANA Review state - - - RFC Status Change - - - agenda - active - Active - True - - 1 - - - - agenda - deleted - Deleted - True - - 2 - - - - charter - notrev - Not currently under review - True - The proposed charter is not being considered at this time. A proposed charter will remain in this state until an AD moves it to Informal IESG review. - 0 - - - - charter - infrev - Informal IESG review - True - This is the initial state when an AD proposes a new charter. The normal next state is Internal review if the idea is accepted, or Not currently under review if the idea is abandoned. - 0 - - - - charter - intrev - Internal review - True - The IESG and IAB are reviewing the early draft of the charter; this is the initial IESG and IAB review. The usual next state is External review if the idea is adopted, or Informal IESG review if the IESG decides the idea needs more work, or Not currently under review is the idea is abandoned - 0 - - - - charter - extrev - External review - True - The IETF community and possibly other standards development organizations (SDOs) are reviewing the proposed charter. The usual next state is IESG review, although it might move to Not currently under review is the idea is abandoned during the external review. - 0 - - - - charter - iesgrev - IESG review - True - The IESG is reviewing the discussion from the external review of the proposed charter. The usual next state is Approved, or Not currently under review if the idea is abandoned. - 0 - - - - charter - approved - Approved - True - The charter is approved by the IESG. - 0 - - - - conflrev - needshep - Needs Shepherd - True - A conflict review has been requested, but a shepherding AD has not yet been assigned - 1 - - - - conflrev - adrev - AD Review - True - The sponsoring AD is reviewing the document and preparing a proposed response - 2 - - - - conflrev - iesgeval - IESG Evaluation - True - The IESG is considering the proposed conflict review response - 3 - - - - conflrev - defer - IESG Evaluation - Defer - True - The evaluation of the proposed conflict review response has been deferred to the next telechat - 4 - - - - conflrev - appr-reqnopub-pr - Approved Request to Not Publish - point raised - True - The IESG has approved the conflict review response (a request to not publish), but a point has been raised that should be cleared before moving to announcement to be sent - 5 - - - - conflrev - appr-noprob-pr - Approved No Problem - point raised - True - The IESG has approved the conflict review response, but a point has been raised that should be cleared before proceeding to announcement to be sent - 6 - - - - conflrev - appr-reqnopub-pend - Approved Request to Not Publish - announcement to be sent - True - The IESG has approved the conflict review response (a request to not publish), but the secretariat has not yet sent the response - 7 - - - - conflrev - appr-noprob-pend - Approved No Problem - announcement to be sent - True - The IESG has approved the conflict review response, but the secretariat has not yet sent the response - 8 - - - - conflrev - appr-reqnopub-sent - Approved Request to Not Publish - announcement sent - True - The secretariat has delivered the IESG's approved conflict review response (a request to not publish) to the requester - 9 - - - - conflrev - appr-noprob-sent - Approved No Problem - announcement sent - True - The secretariat has delivered the IESG's approved conflict review response to the requester - 10 - - - - conflrev - withdraw - Withdrawn - True - The request for conflict review was withdrawn - 11 - - - - conflrev - dead - Dead - True - The conflict review has been abandoned - 12 - - - - draft - active - Active - True - - 1 - - - - draft - expired - Expired - True - - 2 - - - - draft - rfc - RFC - True - - 3 - - - - draft - repl - Replaced - True - - 4 - - - - draft - auth-rm - Withdrawn by Submitter - True - - 5 - - - - draft - ietf-rm - Withdrawn by IETF - True - - 6 - - - - draft-iana-action - newdoc - New Document - True - A new document has been received by IANA, but no actions have been taken - 1 - - - - draft-iana-action - inprog - In Progress - True - IANA is currently processing the actions for this document - 2 - - - - draft-iana-action - waitauth - Waiting on Authors - True - IANA is waiting on the document's authors to respond - 3 - - - - draft-iana-action - waitad - Waiting on ADs - True - IANA is waiting on the IETF Area Directors to respond - 4 - - - - draft-iana-action - waitwgc - Waiting on WGC - True - IANA is waiting on the IETF Working Group Chairs to respond - 5 - - - - draft-iana-action - waitrfc - Waiting on RFC Editor - True - IANA has notified the RFC Editor that the actions have been completed - 6 - - - - draft-iana-action - rfcedack - RFC-Ed-Ack - True - Request completed. The RFC Editor has acknowledged receipt of IANA's message that the actions have been completed - 7 - - - - draft-iana-action - onhold - On Hold - True - IANA has suspended work on the document - 8 - - - - draft-iana-action - noic - No IC - True - Request completed. There were no IANA actions for this document - 9 - - - - draft-iana-review - need-rev - IANA - Review Needed - True - Document has not yet been reviewed by IANA. - 1 - - - - draft-iana-review - ok-act - IANA OK - Actions Needed - True - Document requires IANA actions, and the IANA Considerations section indicates the details of the actions correctly. - 2 - - - - draft-iana-review - ok-noact - IANA OK - No Actions Needed - True - Document requires no IANA action, and the IANA Considerations section indicates this correctly. - 3 - - - - draft-iana-review - not-ok - IANA - Not OK - True - IANA has issues with the text of the IANA Considerations section of the document. - 4 - - - - draft-iana-review - changed - Version Changed - Review Needed - True - Document revision has changed after review by IANA. - 5 - - - - draft-iesg - pub-req - Publication Requested - True - A formal request has been made to advance/publish the document, following the procedures in Section 7.5 of RFC 2418. The request could be from a WG chair, from an individual through the RFC Editor, etc. (The Secretariat (iesg-secretary@ietf.org) is copied on these requests to ensure that the request makes it into the ID tracker.) A document in this state has not (yet) been reviewed by an AD nor has any official action been taken on it yet (other than to note that its publication has been requested. - 10 - - - - draft-iesg - ad-eval - AD Evaluation - True - A specific AD (e.g., the Area Advisor for the WG) has begun reviewing the document to verify that it is ready for advancement. The shepherding AD is responsible for doing any necessary review before starting an IETF Last Call or sending the document directly to the IESG as a whole. - 11 - - - - draft-iesg - review-e - Expert Review - True - An AD sometimes asks for an external review by an outside party as part of evaluating whether a document is ready for advancement. MIBs, for example, are reviewed by the "MIB doctors". Other types of reviews may also be requested (e.g., security, operations impact, etc.). Documents stay in this state until the review is complete and possibly until the issues raised in the review are addressed. See the "note" field for specific details on the nature of the review. - 12 - - - - draft-iesg - lc-req - Last Call Requested - True - The AD has requested that the Secretariat start an IETF Last Call, but the the actual Last Call message has not been sent yet. - 15 - - - - draft-iesg - lc - In Last Call - True - The document is currently waiting for IETF Last Call to complete. Last Calls for WG documents typically last 2 weeks, those for individual submissions last 4 weeks. - 16 - - - - draft-iesg - writeupw - Waiting for Writeup - True - Before a standards-track or BCP document is formally considered by the entire IESG, the AD must write up a protocol action. The protocol action is included in the approval message that the Secretariat sends out when the document is approved for publication as an RFC. - 18 - - - - draft-iesg - goaheadw - Waiting for AD Go-Ahead - True - As a result of the IETF Last Call, comments may need to be responded to and a revision of the ID may be needed as well. The AD is responsible for verifying that all Last Call comments have been adequately addressed and that the (possibly revised) document is in the ID directory and ready for consideration by the IESG as a whole. - 19 - - - - draft-iesg - iesg-eva - IESG Evaluation - True - The document is now (finally!) being formally reviewed by the entire IESG. Documents are discussed in email or during a bi-weekly IESG telechat. In this phase, each AD reviews the document and airs any issues they may have. Unresolvable issues are documented as "discuss" comments that can be forwarded to the authors/WG. See the description of substates for additional details about the current state of the IESG discussion. - 20 - - - - draft-iesg - defer - IESG Evaluation - Defer - True - During a telechat, one or more ADs requested an additional 2 weeks to review the document. A defer is designed to be an exception mechanism, and can only be invoked once, the first time the document comes up for discussion during a telechat. - 21 - - - - draft-iesg - approved - Approved-announcement to be sent - True - The IESG has approved the document for publication, but the Secretariat has not yet sent out on official approval message. - 27 - - - - draft-iesg - ann - Approved-announcement sent - True - The IESG has approved the document for publication, and the Secretariat has sent out the official approval message to the RFC editor. - 30 - - - - draft-iesg - rfcqueue - RFC Ed Queue - True - The document is in the RFC editor Queue (as confirmed by http://www.rfc-editor.org/queue.html). - 31 - - - - draft-iesg - pub - RFC Published - True - The ID has been published as an RFC. - 32 - - - - draft-iesg - nopubadw - DNP-waiting for AD note - True - Do Not Publish: The IESG recommends against publishing the document, but the writeup explaining its reasoning has not yet been produced. DNPs apply primarily to individual submissions received through the RFC editor. See the "note" field for more details on who has the action item. - 33 - - - - draft-iesg - nopubanw - DNP-announcement to be sent - True - The IESG recommends against publishing the document, the writeup explaining its reasoning has been produced, but the Secretariat has not yet sent out the official "do not publish" recommendation message. - 34 - - - - draft-iesg - watching - AD is watching - True - An AD is aware of the document and has chosen to place the document in a separate state in order to keep a closer eye on it (for whatever reason). Documents in this state are still not being actively tracked in the sense that no formal request has been made to publish or advance the document. The sole difference between this state and "I-D Exists" is that an AD has chosen to put it in a separate state, to make it easier to keep track of (for the AD's own reasons). - 42 - - - - draft-iesg - dead - Dead - True - Document is "dead" and is no longer being tracked. (E.g., it has been replaced by another document with a different name, it has been withdrawn, etc.) - 99 - - - - draft-rfceditor - auth - AUTH - True - Awaiting author action - 0 - - - - draft-rfceditor - auth48 - AUTH48 - True - Awaiting final author approval - 0 - - - - draft-rfceditor - edit - EDIT - False - Approved by the stream manager (e.g., IESG, IAB, IRSG, ISE), awaiting processing and publishing - 0 - - - - draft-rfceditor - iana - IANA - True - Document has been edited, but is holding for completion of IANA actions - 0 - - - - draft-rfceditor - iesg - IESG - False - Awaiting IESG action - 0 - - - - draft-rfceditor - isr - ISR - True - Independent Submission Review by the ISE - 0 - - - - draft-rfceditor - isr-auth - ISR-AUTH - False - Independent submission awaiting author action, or in discussion between author and ISE - 0 - - - - draft-rfceditor - ref - REF - True - Holding for normative reference - 0 - - - - draft-rfceditor - rfc-edit - RFC-EDITOR - True - Awaiting final RFC Editor review before AUTH48 - 0 - - - - draft-rfceditor - timeout - TO - True - Time-out period during which the IESG reviews document for conflict/concurrence with other IETF working group work - 0 - - - - draft-rfceditor - missref - MISSREF - True - Awaiting missing normative reference - 0 - - - - draft-rfceditor - auth48done - AUTH48-DONE - False - Final approvals are complete - 0 - - - - draft-rfceditor - auth48-done - AUTH48-DONE - True - Final approvals are complete - 0 - - - - draft-rfceditor - edit - EDIT - True - Approved by the stream manager (e.g., IESG, IAB, IRSG, ISE), awaiting processing and publishing - 0 - - - - draft-rfceditor - iana-crd - IANA - True - RFC-Editor/IANA Registration Coordination - 0 - - - - draft-rfceditor - iesg - IESG - True - Holding for IESG action - 0 - - - - draft-rfceditor - isr-auth - ISR-AUTH - True - Independent Submission awaiting author update, or in discussion between author and ISE - 0 - - - - draft-stream-iab - candidat - Candidate IAB Document - True - A document being considered for the IAB stream. - 1 - - - - draft-stream-iab - active - Active IAB Document - True - This document has been adopted by the IAB and is being actively developed. - 2 - - - - draft-stream-iab - parked - Parked IAB Document - True - This document has lost its author or editor, is waiting for another document to be written, or cannot currently be worked on by the IAB for some other reason. Annotations probably explain why this document is parked. - 3 - - - - draft-stream-iab - review-i - IAB Review - True - This document is awaiting the IAB itself to come to internal consensus. - 4 - - - - draft-stream-iab - review-c - Community Review - True - This document has completed internal consensus within the IAB and is now under community review. - 5 - - - - draft-stream-iab - approved - Approved by IAB, To Be Sent to RFC Editor - True - The consideration of this document is complete, but it has not yet been sent to the RFC Editor for publication (although that is going to happen soon). - 6 - - - - draft-stream-iab - diff-org - Sent to a Different Organization for Publication - True - The IAB does not expect to publish the document itself, but has passed it on to a different organization that might continue work on the document. The expectation is that the other organization will eventually publish the document. - 7 - - - - draft-stream-iab - rfc-edit - Sent to the RFC Editor - True - The IAB processing of this document is complete and it has been sent to the RFC Editor for publication. The document may be in the RFC Editor's queue, or it may have been published as an RFC; this state doesn't distinguish between different states occurring after the document has left the IAB. - 8 - - - - draft-stream-iab - pub - Published RFC - True - The document has been published as an RFC. - 9 - - - - draft-stream-iab - dead - Dead IAB Document - True - This document was an active IAB document, but for some reason it is no longer being pursued for the IAB stream. It is possible that the document might be revived later, possibly in another stream. - 10 - - - - draft-stream-ietf - c-adopt - Call For Adoption By WG Issued - True - <a href="http://tools.ietf.org/html/rfc6174#section-4.2.1" target="_blank">4.2.1. Call for Adoption by WG Issued</a> - - The "Call for Adoption by WG Issued" state should be used to indicate when an I-D is being considered for adoption by an IETF WG. An I-D that is in this state is actively being considered for adoption and has not yet achieved consensus, preference, or selection in the WG. - - This state may be used to describe an I-D that someone has asked a WG to consider for adoption, if the WG Chair has agreed with the request. This state may also be used to identify an I-D that a WG Chair asked an author to write specifically for consideration as a candidate WG item [WGDTSPEC], and/or an I-D that is listed as a 'candidate draft' in the WG's charter. - - Under normal conditions, it should not be possible for an I-D to be in the "Call for Adoption by WG Issued" state in more than one working group at the same time. This said, it is not uncommon for authors to "shop" their I-Ds to more than one WG at a time, with the hope of getting their documents adopted somewhere. - - After this state is implemented in the Datatracker, an I-D that is in the "Call for Adoption by WG Issued" state will not be able to be "shopped" to any other WG without the consent of the WG Chairs and the responsible ADs impacted by the shopping. - - Note that Figure 1 includes an arc leading from this state to outside of the WG state machine. This illustrates that some I-Ds that are considered do not get adopted as WG drafts. An I-D that is not adopted as a WG draft will transition out of the WG state machine and revert back to having no stream-specific state; however, the status change history log of the I-D will record that the I-D was previously in the "Call for Adoption by WG Issued" state. - 1 - - - - draft-stream-ietf - adopt-wg - Adopted by a WG - True - <a href="http://tools.ietf.org/html/rfc6174#section-4.2.2" target="_blank">4.2.2. Adopted by a WG</a> - - The "Adopted by a WG" state describes an individual submission I-D that an IETF WG has agreed to adopt as one of its WG drafts. - - WG Chairs who use this state will be able to clearly indicate when their WGs adopt individual submission I-Ds. This will facilitate the Datatracker's ability to correctly capture "Replaces" information for WG drafts and correct "Replaced by" information for individual submission I-Ds that have been replaced by WG drafts. - - This state is needed because the Datatracker uses the filename of an I-D as a key to search its database for status information about the I-D, and because the filename of a WG I-D is supposed to be different from the filename of an individual submission I-D. The filename of an individual submission I-D will typically be formatted as 'draft-author-wgname-topic-nn'. - - The filename of a WG document is supposed to be formatted as 'draft- ietf-wgname-topic-nn'. - - An individual I-D that is adopted by a WG may take weeks or months to be resubmitted by the author as a new (version-00) WG draft. If the "Adopted by a WG" state is not used, the Datatracker has no way to determine that an I-D has been adopted until a new version of the I-D is submitted to the WG by the author and until the I-D is approved for posting by a WG Chair. - 2 - - - - draft-stream-ietf - info - Adopted for WG Info Only - True - <a href="http://tools.ietf.org/html/rfc6174#section-4.2.3" target="_blank">4.2.3. Adopted for WG Info Only</a> - - The "Adopted for WG Info Only" state describes a document that contains useful information for the WG that adopted it, but the document is not intended to be published as an RFC. The WG will not actively develop the contents of the I-D or progress it for publication as an RFC. The only purpose of the I-D is to provide information for internal use by the WG. - 3 - - - - draft-stream-ietf - wg-doc - WG Document - True - <a href="http://tools.ietf.org/html/rfc6174#section-4.2.4" target="_blank">4.2.4. WG Document</a> - - The "WG Document" state describes an I-D that has been adopted by an IETF WG and is being actively developed. - - A WG Chair may transition an I-D into the "WG Document" state at any time as long as the I-D is not being considered or developed in any other WG. - - Alternatively, WG Chairs may rely upon new functionality to be added to the Datatracker to automatically move version-00 drafts into the "WG Document" state as described in Section 4.1. - - Under normal conditions, it should not be possible for an I-D to be in the "WG Document" state in more than one WG at a time. This said, I-Ds may be transferred from one WG to another with the consent of the WG Chairs and the responsible ADs. - 4 - - - - draft-stream-ietf - parked - Parked WG Document - True - <a href="http://tools.ietf.org/html/rfc6174#section-4.2.5" target="_blank">4.2.5. Parked WG Document</a> - - A "Parked WG Document" is an I-D that has lost its author or editor, is waiting for another document to be written or for a review to be completed, or cannot be progressed by the working group for some other reason. - - Some of the annotation tags described in Section 4.3 may be used in conjunction with this state to indicate why an I-D has been parked, and/or what may need to happen for the I-D to be un-parked. - - Parking a WG draft will not prevent it from expiring; however, this state can be used to indicate why the I-D has stopped progressing in the WG. - - A "Parked WG Document" that is not expired may be transferred from one WG to another with the consent of the WG Chairs and the responsible ADs. - 5 - - - - draft-stream-ietf - dead - Dead WG Document - True - <a href="http://tools.ietf.org/html/rfc6174#section-4.2.6" target="_blank">4.2.6. Dead WG Document</a> - - A "Dead WG Document" is an I-D that has been abandoned. Note that 'Dead' is not always a final state for a WG I-D. If consensus is subsequently achieved, a "Dead WG Document" may be resurrected. A "Dead WG Document" that is not resurrected will eventually expire. - - Note that an I-D that is declared to be "Dead" in one WG and that is not expired may be transferred to a non-dead state in another WG with the consent of the WG Chairs and the responsible ADs. - 6 - - - - draft-stream-ietf - wg-lc - In WG Last Call - True - <a href="http://tools.ietf.org/html/rfc6174#section-4.2.7" target="_blank">4.2.7. In WG Last Call</a> - - A document "In WG Last Call" is an I-D for which a WG Last Call (WGLC) has been issued and is in progress. - - Note that conducting a WGLC is an optional part of the IETF WG process, per Section 7.4 of RFC 2418 [RFC2418]. - - If a WG Chair decides to conduct a WGLC on an I-D, the "In WG Last Call" state can be used to track the progress of the WGLC. The Chair may configure the Datatracker to send a WGLC message to one or more mailing lists when the Chair moves the I-D into this state. The WG Chair may also be able to select a different set of mailing lists for a different document undergoing a WGLC; some documents may deserve coordination with other WGs. - - A WG I-D in this state should remain "In WG Last Call" until the WG Chair moves it to another state. The WG Chair may configure the Datatracker to send an e-mail after a specified period of time to remind or 'nudge' the Chair to conclude the WGLC and to determine the next state for the document. - - It is possible for one WGLC to lead into another WGLC for the same document. For example, an I-D that completed a WGLC as an "Informational" document may need another WGLC if a decision is taken to convert the I-D into a Standards Track document. - 7 - - - - draft-stream-ietf - chair-w - Waiting for WG Chair Go-Ahead - True - <a href="http://tools.ietf.org/html/rfc6174#section-4.2.8" target="_blank">4.2.8. Waiting for WG Chair Go-Ahead</a> - - A WG Chair may wish to place an I-D that receives a lot of comments during a WGLC into the "Waiting for WG Chair Go-Ahead" state. This state describes an I-D that has undergone a WGLC; however, the Chair is not yet ready to call consensus on the document. - - If comments from the WGLC need to be responded to, or a revision to the I-D is needed, the Chair may place an I-D into this state until all of the WGLC comments are adequately addressed and the (possibly revised) document is in the I-D repository. - 8 - - - - draft-stream-ietf - writeupw - WG Consensus: Waiting for Write-Up - True - <a href="http://tools.ietf.org/html/rfc6174#section-4.2.9" target="_blank">4.2.9. WG Consensus: Waiting for Writeup</a> - - A document in the "WG Consensus: Waiting for Writeup" state has essentially completed its development within the working group, and is nearly ready to be sent to the IESG for publication. The last thing to be done is the preparation of a protocol writeup by a Document Shepherd. The IESG requires that a document shepherd writeup be completed before publication of the I-D is requested. The IETF document shepherding process and the role of a WG Document Shepherd is described in RFC 4858 [RFC4858] - - A WG Chair may call consensus on an I-D without a formal WGLC and transition an I-D that was in the "WG Document" state directly into this state. - - The name of this state includes the words "Waiting for Writeup" because a good document shepherd writeup takes time to prepare. - 9 - - - - draft-stream-ietf - sub-pub - Submitted to IESG for Publication - True - <a href="http://tools.ietf.org/html/rfc6174#section-4.2.10" target="_blank">4.2.10. Submitted to IESG for Publication</a> - - This state describes a WG document that has been submitted to the IESG for publication and that has not been sent back to the working group for revision. - - An I-D in this state may be under review by the IESG, it may have been approved and be in the RFC Editor's queue, or it may have been published as an RFC. Other possibilities exist too. The document may be "Dead" (in the IESG state machine) or in a "Do Not Publish" state. - 10 - - - - draft-stream-irtf - candidat - Candidate RG Document - True - This document is under consideration in an RG for becoming an IRTF document. A document in this state does not imply any RG consensus and does not imply any precedence or selection. It's simply a way to indicate that somebody has asked for a document to be considered for adoption by an RG. - 1 - - - - draft-stream-irtf - active - Active RG Document - True - This document has been adopted by the RG and is being actively developed. - 2 - - - - draft-stream-irtf - parked - Parked RG Document - True - This document has lost its author or editor, is waiting for another document to be written, or cannot currently be worked on by the RG for some other reason. - 3 - - - - draft-stream-irtf - rg-lc - In RG Last Call - True - The document is in its final review in the RG. - 4 - - - - draft-stream-irtf - sheph-w - Waiting for Document Shepherd - True - IRTF documents have document shepherds who help RG documents through the process after the RG has finished with the document. - 5 - - - - draft-stream-irtf - chair-w - Waiting for IRTF Chair - True - The IRTF Chair is meant to be performing some task such as sending a request for IESG Review. - 6 - - - - draft-stream-irtf - irsg-w - Awaiting IRSG Reviews - True - The document shepherd has taken the document to the IRSG and solicited reviews from one or more IRSG members. - 7 - - - - draft-stream-irtf - irsgpoll - In IRSG Poll - True - The IRSG is taking a poll on whether or not the document is ready to be published. - 8 - - - - draft-stream-irtf - iesg-rev - In IESG Review - True - The IRSG has asked the IESG to do a review of the document, as described in RFC5742. - 9 - - - - draft-stream-irtf - rfc-edit - Sent to the RFC Editor - True - The RG processing of this document is complete and it has been sent to the RFC Editor for publication. The document may be in the RFC Editor's queue, or it may have been published as an RFC; this state doesn't distinguish between different states occurring after the document has left the RG. - 10 - - - - draft-stream-irtf - pub - Published RFC - True - The document has been published as an RFC. - 11 - - - - draft-stream-irtf - iesghold - Document on Hold Based On IESG Request - True - The IESG has requested that the document be held pending further review, as specified in RFC 5742, and the IRTF has agreed to such a hold. - 12 - - - - draft-stream-irtf - dead - Dead IRTF Document - True - This document was an active IRTF document, but for some reason it is no longer being pursued for the IRTF stream. It is possible that the document might be revived later, possibly in another stream. - 13 - - - - draft-stream-ise - receive - Submission Received - True - The draft has been sent to the ISE with a request for publication. - 1 - - - - draft-stream-ise - find-rev - Finding Reviewers - True - The ISE is finding initial reviewers for the document. - 2 - - - - draft-stream-ise - ise-rev - In ISE Review - True - The ISE is actively working on the document. - 3 - - - - draft-stream-ise - need-res - Response to Review Needed - True - One or more reviews have been sent to the author, and the ISE is awaiting response. - 4 - - - - draft-stream-ise - iesg-rev - In IESG Review - True - The ISE has asked the IESG to do a review of the document, as described in RFC5742. - 5 - - - - draft-stream-ise - rfc-edit - Sent to the RFC Editor - True - The ISE processing of this document is complete and it has been sent to the RFC Editor for publication. The document may be in the RFC Editor's queue, or it may have been published as an RFC; this state doesn't distinguish between different states occurring after the document has left the ISE. - 6 - - - - draft-stream-ise - pub - Published RFC - True - The document has been published as an RFC. - 7 - - - - draft-stream-ise - dead - No Longer In Independent Submission Stream - True - This document was actively considered in the Independent Submission stream, but the ISE chose not to publish it. It is possible that the document might be revived later. A document in this state may have a comment explaining the reasoning of the ISE (such as if the document was going to move to a different stream). - 8 - - - - draft-stream-ise - iesghold - Document on Hold Based On IESG Request - True - The IESG has requested that the document be held pending further review, as specified in RFC 5742, and the ISE has agreed to such a hold. - 9 - - - - minutes - active - Active - True - - 1 - - - - minutes - deleted - Deleted - True - - 2 - - - - slides - active - Active - True - - 1 - - - - slides - deleted - Deleted - True - - 2 - - - - statchg - needshep - Needs Shepherd - True - An RFC status change has been requested, but a shepherding AD has not yet been assigned - 1 - - - - statchg - adrev - AD Review - True - The sponsoring AD is preparing an RFC status change document - 2 - - - - statchg - lc-req - Last Call Requested - True - Last Call has been requested for this proposed status change - 3 - - - - statchg - in-lc - In Last Call - True - This proposed status change is in IETF Last Call - 4 - - - - statchg - goahead - Waiting for AD Go-Ahead - True - The AD is following up on IETF LC comments - 5 - - - - statchg - iesgeval - IESG Evaluation - True - The IESG is considering the proposed RFC status changes - 6 - - - - statchg - defer - IESG Evaluation - Defer - True - The evaluation of the proposed RFC status changes have been deferred to the next telechat - 7 - - - - statchg - appr-pr - Approved - point raised - True - The IESG has approved the RFC status changes, but a point has been raised that should be cleared before proceeding to announcement to be sent - 8 - - - - statchg - appr-pend - Approved - announcement to be sent - True - The IESG has approved the RFC status changes, but the secretariat has not yet sent the announcement - 9 - - - - statchg - appr-sent - Approved - announcement sent - True - The secretariat has announced the IESG's approved RFC status changes - 10 - - - - statchg - dead - Dead - True - The RFC status changes have been abandoned - 11 - - - - conflrev - conflrev - Approve - Is this the correct conflict review response? - True - 0 - - - - statchg - statchg - Approve - Do we approve these RFC status changes? - True - 0 - - - - charter - r-extrev - Ready for external review - Is this charter ready for external review? - True - 1 - - - - draft - approve - Approve - - True - 1 - - - - charter - r-wo-ext - Ready w/o external review - Is this charter ready for external review? Is this charter ready for approval without external review? - True - 2 - - - - charter - approve - Approve - Do we approve of this charter? - True - 3 - - - diff --git a/ietf/name/generate_fixtures.py b/ietf/name/generate_fixtures.py index c4b8bed35..144f17475 100644 --- a/ietf/name/generate_fixtures.py +++ b/ietf/name/generate_fixtures.py @@ -17,8 +17,8 @@ from django.db.models import Q def output(name, qs): try: - f = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "fixtures/%s.xml" % name), 'w') - f.write(serialize("xml", qs, indent=4)) + f = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "fixtures/%s.json" % name), 'w') + f.write(serialize("json", qs, indent=1)) f.close() except: from django.db import connection @@ -29,12 +29,13 @@ def output(name, qs): # pick all name models directly out of the module objects = [] +import inspect import ietf.name.models for n in dir(ietf.name.models): - if n[:1].upper() == n[:1] and n.endswith("Name"): - model = getattr(ietf.name.models, n) - if not model._meta.abstract: - objects.extend(model.objects.all()) + symbol = getattr(ietf.name.models, n) + if inspect.isclass(symbol) and issubclass(symbol, ietf.name.models.NameModel): + if not symbol._meta.abstract: + objects.extend(symbol.objects.all()) import ietf.doc.models # also pick some other name-like types while we're at it diff --git a/ietf/name/migrations/0018_auto__add_draftsubmissionstatename.py b/ietf/name/migrations/0018_auto__add_draftsubmissionstatename.py new file mode 100644 index 000000000..c1891f69b --- /dev/null +++ b/ietf/name/migrations/0018_auto__add_draftsubmissionstatename.py @@ -0,0 +1,214 @@ +# encoding: utf-8 +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + +class Migration(SchemaMigration): + + def forwards(self, orm): + + # Adding model 'DraftSubmissionStateName' + db.create_table('name_draftsubmissionstatename', ( + ('slug', self.gf('django.db.models.fields.CharField')(max_length=8, 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('name', ['DraftSubmissionStateName']) + + # Adding M2M table for field next_states on 'DraftSubmissionStateName' + db.create_table('name_draftsubmissionstatename_next_states', ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('from_draftsubmissionstatename', models.ForeignKey(orm['name.draftsubmissionstatename'], null=False)), + ('to_draftsubmissionstatename', models.ForeignKey(orm['name.draftsubmissionstatename'], null=False)) + )) + db.create_unique('name_draftsubmissionstatename_next_states', ['from_draftsubmissionstatename_id', 'to_draftsubmissionstatename_id']) + + + def backwards(self, orm): + + # Deleting model 'DraftSubmissionStateName' + db.delete_table('name_draftsubmissionstatename') + + # Removing M2M table for field next_states on 'DraftSubmissionStateName' + db.delete_table('name_draftsubmissionstatename_next_states') + + + models = { + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': "orm['name.DraftSubmissionStateName']"}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + 'name.feedbacktype': { + 'Meta': {'ordering': "['order']", 'object_name': 'FeedbackType'}, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + 'name.nomineepositionstate': { + 'Meta': {'ordering': "['order']", 'object_name': 'NomineePositionState'}, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + } + } + + complete_apps = ['name'] diff --git a/ietf/name/migrations/0019_populate_draftsubmissionstate.py b/ietf/name/migrations/0019_populate_draftsubmissionstate.py new file mode 100644 index 000000000..0d91bfa02 --- /dev/null +++ b/ietf/name/migrations/0019_populate_draftsubmissionstate.py @@ -0,0 +1,204 @@ +# encoding: utf-8 +import datetime +from south.db import db +from south.v2 import DataMigration +from django.db import models + +class Migration(DataMigration): + + def forwards(self, orm): + uploaded, _ = orm.DraftSubmissionStateName.objects.get_or_create(slug="uploaded", order=1, name="Uploaded") + submitter, _ = orm.DraftSubmissionStateName.objects.get_or_create(slug="auth", order=2, name="Awaiting Submitter Authentication") + author_approval, _ = orm.DraftSubmissionStateName.objects.get_or_create(slug="aut-appr", order=3, name="Awaiting Approval from Previous Version Authors'") + group_approval, _ = orm.DraftSubmissionStateName.objects.get_or_create(slug="grp-appr", order=4, name="Awaiting Initial Version Approval") + manual_post, _ = orm.DraftSubmissionStateName.objects.get_or_create(slug="manual", order=5, name="Awaiting Manual Post") + cancel, _ = orm.DraftSubmissionStateName.objects.get_or_create(slug="cancel", order=6, name="Cancelled") + posted, _ = orm.DraftSubmissionStateName.objects.get_or_create(slug="posted", order=7, name="Posted") + + uploaded.next_states = [submitter, author_approval, group_approval, manual_post, cancel] + submitter.next_states = [cancel, posted] + author_approval.next_states = [cancel, posted] + group_approval.next_states = [cancel, posted] + manual_post.next_states = [cancel, posted] + + + def backwards(self, orm): + "Write your backwards methods here." + + + models = { + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': "orm['name.DraftSubmissionStateName']"}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + 'name.feedbacktype': { + 'Meta': {'ordering': "['order']", 'object_name': 'FeedbackType'}, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + 'name.nomineepositionstate': { + 'Meta': {'ordering': "['order']", 'object_name': 'NomineePositionState'}, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + } + } + + complete_apps = ['name'] diff --git a/ietf/name/models.py b/ietf/name/models.py index 0f97aaa14..7403256d1 100644 --- a/ietf/name/models.py +++ b/ietf/name/models.py @@ -66,3 +66,8 @@ class FeedbackType(NameModel): """Type of feedback: questionnaires, nominations, comments""" class DBTemplateTypeName(NameModel): """reStructuredText, Plain, Django""" +class DraftSubmissionStateName(NameModel): + """Uploaded, Awaiting Submitter Authentication, Awaiting Approval from + Previous Version Authors, Awaiting Initial Version Approval, Awaiting + Manual Post, Cancelled, Posted""" + next_states = models.ManyToManyField('DraftSubmissionStateName', related_name="previous_states", blank=True) diff --git a/ietf/name/proxy.py b/ietf/name/proxy.py deleted file mode 100644 index dfe75371e..000000000 --- a/ietf/name/proxy.py +++ /dev/null @@ -1,63 +0,0 @@ -from ietf.utils.proxy import TranslatingManager -from models import * - -class IDSubStateManager(TranslatingManager): - def __init__(self, *args): - super(IDSubStateManager, self).__init__(*args) - - def all(self): - return self.filter(slug__in=['extpty', 'need-rev', 'ad-f-up', 'point']) - -class IDSubState(DocTagName): - objects = IDSubStateManager(dict(pk="order")) - - def from_object(self, base): - for f in base._meta.fields: - setattr(self, f.name, getattr(base, f.name)) - return self - - #sub_state_id = models.AutoField(primary_key=True) - @property - def sub_state_id(self): - return self.order - - #sub_state = models.CharField(max_length=55, db_column='sub_state_val') - @property - def sub_state(self): - return self.name - - #description = models.TextField(blank=True, db_column='sub_state_desc') - @property - def description(self): - return self.desc - - def __str__(self): - return self.sub_state - - class Meta: - proxy = True - - -class AnnotationTagObjectRelationProxy(DocTagName): - objects = TranslatingManager(dict(annotation_tag__name="name")) - - @property - def annotation_tag(self): - return self - - class Meta: - proxy = True - -class StreamProxy(StreamName): - def get_chairs(self): - from ietf.group.models import Role - from ietf.utils.proxy import proxy_personify_role - return [proxy_personify_role(r) for r in Role.objects.filter(group__acronym=self.slug, name="chair")] - - def get_delegates(self): - from ietf.group.models import Role - from ietf.utils.proxy import proxy_personify_role - return [proxy_personify_role(r) for r in Role.objects.filter(group__acronym=self.slug, name="delegate")] - - class Meta: - proxy = True diff --git a/ietf/nomcom/decorators.py b/ietf/nomcom/decorators.py index ed0d715c9..89c19e9c5 100644 --- a/ietf/nomcom/decorators.py +++ b/ietf/nomcom/decorators.py @@ -2,7 +2,7 @@ from django.core.urlresolvers import reverse from django.http import HttpResponseRedirect from django.utils.http import urlquote -from ietf.ietfauth.decorators import passes_test_decorator +from ietf.ietfauth.utils import passes_test_decorator from ietf.nomcom.utils import get_nomcom_by_year diff --git a/ietf/nomcom/forms.py b/ietf/nomcom/forms.py index 75f8cac3d..dfdaad59c 100644 --- a/ietf/nomcom/forms.py +++ b/ietf/nomcom/forms.py @@ -11,7 +11,7 @@ from django.template.context import RequestContext from ietf.dbtemplate.forms import DBTemplateForm from ietf.utils.mail import send_mail -from ietf.ietfauth.decorators import role_required +from ietf.ietfauth.utils import role_required from ietf.utils import fields as custom_fields from ietf.group.models import Group, Role from ietf.name.models import RoleName, FeedbackType, NomineePositionState diff --git a/ietf/nomcom/models.py b/ietf/nomcom/models.py index 410a20cee..ff6d8c8f4 100644 --- a/ietf/nomcom/models.py +++ b/ietf/nomcom/models.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# -*- coding: utf-8 -*- import os from django.db import models diff --git a/ietf/nomcom/redirect_ann_urls.py b/ietf/nomcom/redirect_ann_urls.py new file mode 100644 index 000000000..993680f78 --- /dev/null +++ b/ietf/nomcom/redirect_ann_urls.py @@ -0,0 +1,7 @@ +from django.conf.urls.defaults import patterns +from django.views.generic.simple import redirect_to + +urlpatterns = patterns('', + (r'^nomcom/$', 'django.views.generic.simple.redirect_to', { 'url': "/nomcom/ann/", 'permanent': True }), + (r'^nomcom/(?P\d+)/$', 'django.views.generic.simple.redirect_to', { 'url': "/nomcom/ann/%(message_id)s/", 'permanent': True }), +) diff --git a/ietf/nomcom/templatetags/nomcom_tags.py b/ietf/nomcom/templatetags/nomcom_tags.py index 29a640492..43f421a6a 100644 --- a/ietf/nomcom/templatetags/nomcom_tags.py +++ b/ietf/nomcom/templatetags/nomcom_tags.py @@ -7,7 +7,7 @@ from django.template.defaultfilters import linebreaksbr, force_escape from ietf.utils.pipe import pipe from ietf.utils.log import log -from ietf.ietfauth.decorators import has_role +from ietf.ietfauth.utils import has_role from ietf.doc.templatetags.ietf_filters import wrap_text from ietf.person.models import Person @@ -25,7 +25,7 @@ def is_chair(user, year): nomcom = get_nomcom_by_year(year=year) if has_role(user, "Secretariat"): return True - return nomcom.group.is_chair(user) + return nomcom.group.has_role(user, "chair") @register.filter diff --git a/ietf/nomcom/test_data.py b/ietf/nomcom/test_data.py index bd20b8b94..96f31b739 100644 --- a/ietf/nomcom/test_data.py +++ b/ietf/nomcom/test_data.py @@ -6,7 +6,7 @@ from django.core.files import File from django.conf import settings from ietf.utils.pipe import pipe -from ietf.group.models import Group, Role +from ietf.group.models import Group, Role, ChangeStateGroupEvent from ietf.person.models import Email, Person from ietf.name.models import RoleName from ietf.nomcom.models import NomCom, Position, Nominee @@ -101,6 +101,7 @@ def nomcom_test_data(): state_id='active', type_id='nomcom', acronym='nomcom%s' % NOMCOM_YEAR) + nomcom, created = NomCom.objects.get_or_create(group=group) cert_file, privatekey_file = generate_cert() @@ -159,3 +160,9 @@ def nomcom_test_data(): description=description, is_open=True, incumbent=email) + + ChangeStateGroupEvent.objects.get_or_create(group=group, + type="changed_state", + state_id="active", + time=group.time, + by=Person.objects.all()[0]) diff --git a/ietf/nomcom/tests.py b/ietf/nomcom/tests.py index 73061570e..3d8acc65d 100644 --- a/ietf/nomcom/tests.py +++ b/ietf/nomcom/tests.py @@ -8,13 +8,15 @@ from django.db import IntegrityError from django.core.urlresolvers import reverse from django.core.files import File from django.contrib.formtools.preview import security_hash +from django.contrib.auth.models import User from ietf.utils.test_utils import login_testing_unauthorized from ietf.utils.mail import outbox from ietf.person.models import Email, Person -from django.contrib.auth.models import User +from ietf.group.models import Group +from ietf.message.models import Message from ietf.nomcom.test_data import nomcom_test_data, generate_cert, check_comments, \ COMMUNITY_USER, CHAIR_USER, \ @@ -30,7 +32,7 @@ from ietf.nomcom.management.commands.send_reminders import Command, is_time_to_s class NomcomViewsTest(TestCase): """Tests to create a new nomcom""" # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names', 'nomcom_templates'] + perma_fixtures = ['nomcom_templates'] def check_url_status(self, url, status): response = self.client.get(url) @@ -365,6 +367,25 @@ class NomcomViewsTest(TestCase): """Verify home view""" self.check_url_status(self.index_url, 200) + def test_announcements_view(self): + nomcom = Group.objects.get(acronym="nomcom%s" % self.year, type="nomcom") + msg = Message.objects.create( + by=Person.objects.all()[0], + subject="This is a test", + to="test@example.com", + frm="nomcomchair@example.com", + body="Hello World!", + content_type="", + ) + msg.related_groups.add(nomcom) + + r = self.client.get(reverse('ietf.nomcom.views.announcements')) + self.assertEqual(r.status_code, 200) + self.assertTrue(("Messages from %s" % nomcom.time.year) in r.content) + self.assertTrue(nomcom.role_set.filter(name="chair")[0].person.email_address() in r.content) + self.assertTrue(msg.subject in r.content) + + def test_requirements_view(self): """Verify requirements view""" self.check_url_status(self.requirements_url, 200) @@ -595,7 +616,7 @@ class NomcomViewsTest(TestCase): class NomineePositionStateSaveTest(TestCase): """Tests for the NomineePosition save override method""" # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names', 'nomcom_templates'] + perma_fixtures = ['nomcom_templates'] def setUp(self): nomcom_test_data() @@ -627,7 +648,7 @@ class NomineePositionStateSaveTest(TestCase): class FeedbackTest(TestCase): - perma_fixtures = ['names', 'nomcom_templates'] + perma_fixtures = ['nomcom_templates'] def setUp(self): nomcom_test_data() @@ -659,7 +680,7 @@ class FeedbackTest(TestCase): os.unlink(self.cert_file.name) class ReminderTest(TestCase): - perma_fixtures = ['names', 'nomcom_templates'] + perma_fixtures = ['nomcom_templates'] def setUp(self): nomcom_test_data() diff --git a/ietf/nomcom/urls.py b/ietf/nomcom/urls.py index 4bfdbfca0..595cdcbc3 100644 --- a/ietf/nomcom/urls.py +++ b/ietf/nomcom/urls.py @@ -6,6 +6,7 @@ from ietf.nomcom.forms import EditChairForm, EditChairFormPreview, \ urlpatterns = patterns('ietf.nomcom.views', url(r'^$', 'index'), + url(r'^ann/$', 'announcements'), url(r'^(?P\d{4})/private/$', 'private_index', name='nomcom_private_index'), url(r'^(?P\d{4})/private/key/$', 'private_key', name='nomcom_private_key'), url(r'^(?P\d{4})/private/nominate/$', 'private_nominate', name='nomcom_private_nominate'), @@ -42,3 +43,7 @@ urlpatterns = patterns('ietf.nomcom.views', url(r'^ajax/position-text/(?P\d+)/$', 'ajax_position_text', name='nomcom_ajax_position_text'), ) + +urlpatterns += patterns('', + url(r'^ann/(?P\d+)/$', 'ietf.message.views.message', {'group_type': "nomcom" }, "nomcom_announcement"), +) diff --git a/ietf/nomcom/utils.py b/ietf/nomcom/utils.py index 152da53c2..c2deffd9a 100644 --- a/ietf/nomcom/utils.py +++ b/ietf/nomcom/utils.py @@ -84,18 +84,6 @@ def get_user_email(user): pass return user._email_cache -def is_nomcom_member(user, nomcom): - is_group_member = nomcom.group.is_member(user) - if not is_group_member: - raise PermissionDenied("Must be nomcom member") - - -def is_nomcom_chair(user, nomcom): - is_group_chair = nomcom.group.is_chair(user) - if not is_group_chair: - raise PermissionDenied("Must be nomcom chair") - - def get_hash_nominee_position(date, nominee_position_id): return hashlib.md5('%s%s%s' % (settings.SECRET_KEY, date, nominee_position_id)).hexdigest() diff --git a/ietf/nomcom/views.py b/ietf/nomcom/views.py index 05381d07d..c69e6f0ac 100644 --- a/ietf/nomcom/views.py +++ b/ietf/nomcom/views.py @@ -1,6 +1,6 @@ - # -*- coding: utf-8 -*- + # -*- coding: utf-8 -*- -import datetime +import datetime, re from django.views.generic.create_update import delete_object from django.conf import settings @@ -20,7 +20,8 @@ from django.forms.models import modelformset_factory, inlineformset_factory from ietf.dbtemplate.models import DBTemplate from ietf.dbtemplate.views import template_edit from ietf.name.models import NomineePositionState, FeedbackType -from ietf.group.models import Group +from ietf.group.models import Group, GroupEvent +from ietf.message.models import Message from ietf.nomcom.decorators import nomcom_private_key_required from ietf.nomcom.forms import (NominateForm, FeedbackForm, QuestionnaireForm, @@ -53,7 +54,7 @@ def index(request): else: nomcom.url = None if year >= 2002: - nomcom.ann_url = "/ann/nomcom/#%4d" % year + nomcom.ann_url = "/nomcom/ann/#%4d" % year else: nomcom.ann_url = None return render_to_response('nomcom/index.html', @@ -70,6 +71,41 @@ def year_index(request, year): 'selected': 'index', 'template': template}, RequestContext(request)) +def announcements(request): + address_re = re.compile("<.*>") + + nomcoms = Group.objects.filter(type="nomcom") + + regimes = [] + + for n in nomcoms: + e = GroupEvent.objects.filter(group=n, type="changed_state", changestategroupevent__state="active").order_by('time')[:1] + n.start_year = e[0].time.year if e else 0 + e = GroupEvent.objects.filter(group=n, type="changed_state", changestategroupevent__state="conclude").order_by('time')[:1] + n.end_year = e[0].time.year if e else n.start_year + 1 + + r = n.role_set.select_related().filter(name="chair") + chair = None + if r: + chair = r[0] + + announcements = Message.objects.filter(related_groups=n).order_by('-time') + for a in announcements: + a.to_name = address_re.sub("", a.to) + + if not announcements: + continue + + regimes.append(dict(chair=chair, + announcements=announcements, + group=n)) + + regimes.sort(key=lambda x: x["group"].start_year, reverse=True) + + return render_to_response("nomcom/announcements.html", + { 'curr_chair' : regimes[0]["chair"] if regimes else None, + 'regimes' : regimes }, + context_instance=RequestContext(request)) @role_required("Nomcom") def private_key(request, year): @@ -101,7 +137,7 @@ def private_key(request, year): def private_index(request, year): nomcom = get_nomcom_by_year(year) all_nominee_positions = NomineePosition.objects.get_by_nomcom(nomcom).not_duplicated() - is_chair = nomcom.group.is_chair(request.user) + is_chair = nomcom.group.has_role(request.user, "chair") message = None if is_chair and request.method == 'POST': action = request.POST.get('action') diff --git a/ietf/person/ajax.py b/ietf/person/ajax.py index 4a10043a0..3db648c25 100644 --- a/ietf/person/ajax.py +++ b/ietf/person/ajax.py @@ -1,17 +1,15 @@ -from django.utils import simplejson as json -from dajaxice.core import dajaxice_functions -from dajaxice.decorators import dajaxice_register -from ietf.ietfauth.decorators import group_required -from django.shortcuts import get_object_or_404 -from django.http import HttpResponseRedirect, HttpResponse, Http404 - -from ietf.person.models import Person import datetime import logging import sys -from ietf.settings import LOG_DIR -log = logging.getLogger(__name__) +from django.utils import simplejson as json +from django.shortcuts import get_object_or_404 +from django.http import HttpResponseRedirect, HttpResponse, Http404 + +from dajaxice.core import dajaxice_functions +from dajaxice.decorators import dajaxice_register + +from ietf.person.models import Person def person_json(request, personid): person = get_object_or_404(Person, pk=personid) diff --git a/ietf/person/models.py b/ietf/person/models.py index 62df0806a..62530ccb7 100644 --- a/ietf/person/models.py +++ b/ietf/person/models.py @@ -93,9 +93,6 @@ class Person(PersonInfo): #this variable, if not None, may be used by url() to keep the sitefqdn. default_hostscheme = None - def person(self): # little temporary wrapper to help porting to new schema - return self - @property def defurl(self): return urljoin(self.default_hostscheme,self.json_url()) diff --git a/ietf/person/proxy.py b/ietf/person/proxy.py deleted file mode 100644 index 50a8ef117..000000000 --- a/ietf/person/proxy.py +++ /dev/null @@ -1,55 +0,0 @@ -from ietf.utils.proxy import TranslatingManager - -from models import * - -class IESGLogin(Person): - objects = TranslatingManager(dict(user_level__in=None, - first_name="name" - )) - - def from_object(self, base): - for f in base._meta.fields: - setattr(self, f.name, getattr(base, f.name)) - return self - - SECRETARIAT_LEVEL = 0 - AD_LEVEL = 1 - INACTIVE_AD_LEVEL = 2 - - #login_name = models.CharField(blank=True, max_length=255) - @property - def login_name(self): raise NotImplemented - #password = models.CharField(max_length=25) - @property - def password(self): raise NotImplemented - #user_level = models.IntegerField(choices=USER_LEVEL_CHOICES) - @property - def user_level(self): raise NotImplemented - - #first_name = models.CharField(blank=True, max_length=25) - @property - def first_name(self): - return self.name_parts()[1] - - #last_name = models.CharField(blank=True, max_length=25) - @property - def last_name(self): - return self.name_parts()[3] - - # FIXME: person isn't wrapped yet - #person = BrokenForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag', unique=True, null_values=(0, 888888), null=True) - - # apparently unused - #pgp_id = models.CharField(blank=True, null=True, max_length=20) - #default_search = models.NullBooleanField() - - def __str__(self): - return self.plain_name() - def is_current_ad(self): - return bool(self.role_set.filter(name="ad", group__state="active")) - @staticmethod - def active_iesg(): - return IESGLogin.objects.filter(role__name="ad", role__group__state="active").distinct().order_by('name') - - class Meta: - proxy = True diff --git a/ietf/proceedings/.gitignore b/ietf/proceedings/.gitignore deleted file mode 100644 index a74b07aee..000000000 --- a/ietf/proceedings/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/*.pyc diff --git a/ietf/proceedings/__init__.py b/ietf/proceedings/__init__.py deleted file mode 100644 index a4b306690..000000000 --- a/ietf/proceedings/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# Copyright The IETF Trust 2007, All Rights Reserved - diff --git a/ietf/proceedings/feeds.py b/ietf/proceedings/feeds.py deleted file mode 100644 index 7483df0d1..000000000 --- a/ietf/proceedings/feeds.py +++ /dev/null @@ -1,90 +0,0 @@ -import re, os -from django.contrib.syndication.feeds import Feed -from django.utils.feedgenerator import Atom1Feed -from django.conf import settings -from ietf.proceedings.models import WgProceedingsActivities -from ietf.proceedings.models import Slide, WgAgenda, Proceeding -from datetime import datetime, time - -class LatestWgProceedingsActivity(Feed): - feed_type = Atom1Feed - link = "/foo" - description = "foobar" - language = "en" - feed_url = "/feed/wg-proceedings/" - base_url = "http://www3.ietf.org/proceedings/" - - def items(self): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - objs = [] - from ietf.doc.models import Document - for doc in Document.objects.filter(type__in=("agenda", "minutes", "slides")).order_by('-time')[:60]: - obj = dict( - title=doc.type_id, - group_acronym=doc.name.split("-")[2], - date=doc.time, - link=self.base_url + os.path.join(doc.get_file_path(), doc.external_url)[len(settings.AGENDA_PATH):], - author="" - ) - objs.append(obj) - - return objs - - objs = [] - for act in WgProceedingsActivities.objects.order_by('-act_date')[:60]: - obj = {} - - m = re.match("^slide, '(.*)', was uploaded$", act.activity) - if m: - obj['title'] = m.group(1) - obj['title'] = re.sub("[^ -~]+", "", obj['title']) - slides = Slide.objects.filter(meeting=act.meeting).filter(slide_name=m.group(1)).filter(group_acronym_id=act.group_acronym_id) - if len(slides) == 1: - obj['link'] = self.base_url + slides[0].file_loc() - - m = re.match("^agenda was uploaded$", act.activity) - if m: - obj['title'] = "agenda"; - agendas = WgAgenda.objects.filter(meeting=act.meeting).filter(group_acronym_id=act.group_acronym_id) - if len(agendas) == 1: - dir = Proceeding.objects.get(meeting_num=act.meeting).dir_name - obj['link'] = self.base_url + dir + "/agenda/" + agendas[0].filename - - if len(obj) > 0: - try: - act.irtf = False - obj['group_acronym'] = act.acronym() - except: - act.irtf = True - try: - obj['group_acronym'] = act.acronym() - except: - obj['group_acronym'] = "?" - obj['date'] = datetime.combine(act.act_date, time(int(act.act_time[0:2]), int(act.act_time[3:5]), int(act.act_time[6:8]))) - obj['author'] = str(act.act_by) - objs.append(obj) - - return objs - - def get_object(self, bits): - obj = {} - obj['title'] = "This is the title"; - return obj - - def title(self, obj): - return "Meeting Materials Activity" - - def item_link(self, item): - if 'link' in item: - return item['link'] - else: - return "" - - def item_pubdate(self, item): - return item['date'] - - def item_author_name(self, item): - return item['author'] - - def item_author_email(self, item): - return None; diff --git a/ietf/proceedings/models.py b/ietf/proceedings/models.py deleted file mode 100644 index 5603c4f03..000000000 --- a/ietf/proceedings/models.py +++ /dev/null @@ -1,623 +0,0 @@ -# Copyright The IETF Trust 2007, All Rights Reserved - -######################################################################## -######################################################################## -######################################################################## -##### ##### -##### WARNING WARNING WARNING WARNING WARNING WARNING WARNING ##### -##### ##### -##### These models are old, deprecated, and should not be ##### -##### used. Use the models in the meetings directory ##### -##### instead. ##### -##### ##### -##### WARNING WARNING WARNING WARNING WARNING WARNING WARNING ##### -##### ##### -######################################################################## -######################################################################## -######################################################################## - -from django.db import models -from django.conf import settings -from ietf.idtracker.models import Acronym, PersonOrOrgInfo, IRTF, AreaGroup, Area, IETFWG -from ietf.utils.broken_foreign_key import BrokenForeignKey -import datetime -#from ietf.utils import log - -# group_acronym is either an IETF Acronym -# or an IRTF one, depending on the value of irtf. -# Multiple inheritance to the rescue. -# -# interim = i prefix (complicated because you have to check if self has -# an interim attribute first) -class ResolveAcronym(object): - def acronym(self): - if hasattr(self, '_acronym_acronym'): - return self._acronym_acronym - try: - interim = self.interim - except AttributeError: - interim = False - if self.irtf: - o = IRTF.objects.get(pk=self.group_acronym_id) - else: - o = Acronym.objects.get(pk=self.group_acronym_id) - self._acronym_acronym = o.acronym - self._acronym_name = o.name - acronym = self._acronym_acronym - if interim: - return "i" + acronym - else: - return acronym - def acronym_lower(self): - return self.acronym().lower() - def acronym_name(self): - if not hasattr(self, '_acronym_name'): - self.acronym() - try: - interim = self.interim - except AttributeError: - interim = False - acronym_name = self._acronym_name - if interim: - return acronym_name + " (interim)" - else: - return acronym_name - def area(self): - if hasattr(self, '_area'): - return self._area - if self.irtf: - area = "irtf" - elif self.group_acronym_id < 0 and self.group_acronym_id > -3: - area = "1plenary" - elif self.group_acronym_id < -2: - area = "" - else: - try: - area = AreaGroup.objects.select_related().get(group=self.group_acronym_id).area.area_acronym.acronym - except AreaGroup.DoesNotExist: - area = "" - self._area = area - return area - def area_name(self): - if self.irtf: - area_name = "IRTF" - elif self.group_acronym_id < 0 and self.group_acronym_id > -3: - area_name = "Plenary Sessions" - elif self.group_acronym_id < -2: - area_name = "Training" - else: - try: - area_name = AreaGroup.objects.get(group=self.group_acronym_id).area.area_acronym.name - except AreaGroup.DoesNotExist: - area_name = "" - return area_name - def isWG(self): - if self.irtf: - return False - if not hasattr(self,'_ietfwg'): - try: - self._ietfwg = IETFWG.objects.get(pk=self.group_acronym_id) - except IETFWG.DoesNotExist: - self._ietfwg = None - if self._ietfwg and self._ietfwg.group_type_id == 1: - return True - else: - return False - def group_type_str(self): - if self.irtf: - return "" - else: - self.isWG() - if not self._ietfwg: - return "" - elif self._ietfwg.group_type_id == 1: - return "WG" - elif self._ietfwg.group_type_id == 3: - return "BOF" - else: - return "" - -TIME_ZONE_CHOICES = ( - (0, 'UTC'), - (-1, 'UTC -1'), - (-2, 'UTC -2'), - (-3, 'UTC -3'), - (-4, 'UTC -4 (Eastern Summer)'), - (-5, 'UTC -5 (Eastern Winter)'), - (-6, 'UTC -6'), - (-7, 'UTC -7'), - (-8, 'UTC -8 (Pacific Winter)'), - (-9, 'UTC -9'), - (-10, 'UTC -10 (Hawaii Winter)'), - (-11, 'UTC -11'), - (+12, 'UTC +12'), - (+11, 'UTC +11'), - (+10, 'UTC +10 (Brisbane)'), - (+9, 'UTC +9'), - (+8, 'UTC +8 (Perth Winter)'), - (+7, 'UTC +7'), - (+6, 'UTC +6'), - (+5, 'UTC +5'), - (+4, 'UTC +4'), - (+3, 'UTC +3 (Moscow Winter)'), - (+2, 'UTC +2 (Western Europe Summer'), - (+1, 'UTC +1 (Western Europe Winter)'), -) - -class Meeting(models.Model): - meeting_num = models.IntegerField(primary_key=True) - start_date = models.DateField() - end_date = models.DateField() - city = models.CharField(blank=True, max_length=255) - state = models.CharField(blank=True, max_length=255) - country = models.CharField(blank=True, max_length=255) - time_zone = models.IntegerField(null=True, blank=True, choices=TIME_ZONE_CHOICES) - ack = models.TextField(blank=True) - agenda_html = models.TextField(blank=True) - agenda_text = models.TextField(blank=True) - future_meeting = models.TextField(blank=True) - overview1 = models.TextField(blank=True) - overview2 = models.TextField(blank=True) - def __str__(self): - return "IETF-%s" % (self.meeting_num) - def get_meeting_date (self,offset): - return self.start_date + datetime.timedelta(days=offset) - def num(self): - return self.meeting_num - class Meta: - db_table = 'meetings' - - @classmethod - def get_first_cut_off(cls): - start_date = cls.objects.all().order_by('-start_date')[0].start_date - offset = datetime.timedelta(days=settings.FIRST_CUTOFF_DAYS) - return start_date - offset - - @classmethod - def get_second_cut_off(cls): - start_date = cls.objects.all().order_by('-start_date')[0].start_date - offset = datetime.timedelta(days=settings.SECOND_CUTOFF_DAYS) - return start_date - offset - - @classmethod - def get_ietf_monday(cls): - start_date = cls.objects.all().order_by('-start_date')[0].start_date - return start_date + datetime.timedelta(days=-start_date.weekday(), weeks=1) - -class MeetingVenue(models.Model): - meeting_num = models.ForeignKey(Meeting, db_column='meeting_num', unique=True) - break_area_name = models.CharField(max_length=255) - reg_area_name = models.CharField(max_length=255) - def __str__(self): - return "IETF %s" % (self.meeting_num_id) - class Meta: - db_table = 'meeting_venues' - verbose_name = "Meeting public areas" - verbose_name_plural = "Meeting public areas" - -class NonSessionRef(models.Model): - name = models.CharField(max_length=255) - def __str__(self): - return self.name - class Meta: - db_table = 'non_session_ref' - verbose_name = "Non-session slot name" - -class NonSession(models.Model): - non_session_id = models.AutoField(primary_key=True) - day_id = models.IntegerField(blank=True, null=True) # NULL means all days - non_session_ref = models.ForeignKey(NonSessionRef) - meeting = models.ForeignKey(Meeting, db_column='meeting_num') - time_desc = models.CharField(blank=True, max_length=75) - show_break_location = models.BooleanField() - def __str__(self): - if self.day_id: - return "%s %s %s @%s" % ((self.meeting.start_date + datetime.timedelta(self.day_id)).strftime('%A'), self.time_desc, self.non_session_ref, self.meeting_id) - else: - return "** %s %s @%s" % (self.time_desc, self.non_session_ref, self.meeting_id) - def day(self): - if self.day_id: - return (self.meeting.start_date + datetime.timedelta(self.day_id)).strftime('%A') - else: - return "All" - class Meta: - db_table = 'non_session' - verbose_name = "Meeting non-session slot" - -class Proceeding(models.Model): - meeting_num = models.ForeignKey(Meeting, db_column='meeting_num', unique=True, primary_key=True) - dir_name = models.CharField(blank=True, max_length=25) - sub_begin_date = models.DateField(null=True, blank=True) - sub_cut_off_date = models.DateField(null=True, blank=True) - frozen = models.IntegerField(null=True, blank=True) - c_sub_cut_off_date = models.DateField(null=True, blank=True) - pr_from_date = models.DateField(null=True, blank=True) - pr_to_date = models.DateField(null=True, blank=True) - def __str__(self): - return "IETF %s" % (self.meeting_num_id) - class Meta: - db_table = 'proceedings' - ordering = ['?'] # workaround for FK primary key - -class SessionConflict(models.Model): - group_acronym = models.ForeignKey(Acronym, related_name='conflicts_set') - conflict_gid = models.ForeignKey(Acronym, related_name='conflicts_with_set', db_column='conflict_gid') - meeting_num = models.ForeignKey(Meeting, db_column='meeting_num') - def __str__(self): - try: - return "At IETF %s, %s conflicts with %s" % ( self.meeting_num_id, self.group_acronym.acronym, self.conflict_gid.acronym) - except BaseException: - return "At IETF %s, something conflicts with something" % ( self.meeting_num_id ) - - class Meta: - db_table = 'session_conflicts' - -class SessionName(models.Model): - session_name_id = models.AutoField(primary_key=True) - session_name = models.CharField(blank=True, max_length=255) - def __str__(self): - return self.session_name - class Meta: - db_table = 'session_names' - verbose_name = "Slot name" - - -class IESGHistory(models.Model): - meeting = models.ForeignKey(Meeting, db_column='meeting_num') - area = models.ForeignKey(Area, db_column='area_acronym_id') - person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag') - def __str__(self): - return "IESG%s: %s (%s)" % (self.meeting_id, self.person,self.area) - class Meta: - db_table = 'iesg_history' - verbose_name = "Meeting AD info" - verbose_name_plural = "Meeting AD info" - -class MeetingTime(models.Model): - time_id = models.AutoField(primary_key=True) - time_desc = models.CharField(max_length=100) - meeting = models.ForeignKey(Meeting, db_column='meeting_num') - day_id = models.IntegerField() - session_name = models.ForeignKey(SessionName,null=True) - def __str__(self): - return "[%d] |%s| %s" % (self.meeting_id, (self.meeting.start_date + datetime.timedelta(self.day_id)).strftime('%A'), self.time_desc) - def sessions(self): - """ - Get all sessions that are scheduled at this time. - """ - sessions = WgMeetingSession.objects.filter( - models.Q(sched_time_id1=self.time_id) | - models.Q(sched_time_id2=self.time_id) | - models.Q(sched_time_id3=self.time_id) | - models.Q(combined_time_id1=self.time_id) | - models.Q(combined_time_id2=self.time_id)) - for s in sessions: - if s.sched_time_id1_id == self.time_id: - s.room_id = s.sched_room_id1 - s.ordinality = 1 - elif s.sched_time_id2_id == self.time_id: - s.room_id = s.sched_room_id2 - s.ordinality = 2 - elif s.sched_time_id3_id == self.time_id: - s.room_id = s.sched_room_id3 - s.ordinality = 3 - elif s.combined_time_id1_id == self.time_id: - s.room_id = s.combined_room_id1 - s.ordinality = 4 - elif s.combined_time_id2_id == self.time_id: - s.room_id = s.combined_room_id2 - s.ordinality = 5 - else: - s.room_id = 0 - s.ordinality = 0 - return sessions - def sessions_by_area(self): - return [ {"area":session.area()+session.acronym(), "info":session} for session in self.sessions() ] - def meeting_date(self): - return self.meeting.get_meeting_date(self.day_id) - def registration(self): - if hasattr(self, '_reg_info'): - return self._reg_info - reg = NonSession.objects.get(meeting=self.meeting, day_id=self.day_id, non_session_ref=1) - reg.name = reg.non_session_ref.name - self._reg_info = reg - return reg - def reg_info(self): - reg_info = self.registration() - if reg_info.time_desc: - return "%s %s" % (reg_info.time_desc, reg_info.name) - else: - return "" - def break_info(self): - breaks = NonSession.objects.filter(meeting=self.meeting).exclude(non_session_ref=1).filter(models.Q(day_id=self.day_id) | models.Q(day_id__isnull=True)).order_by('time_desc') - for brk in breaks: - if brk.time_desc[-4:] == self.time_desc[:4]: - brk.name = brk.non_session_ref.name - return brk - return None - def is_plenary(self): - return self.session_name_id in [9, 10] - class Meta: - db_table = 'meeting_times' - verbose_name = "Meeting slot time" - -class MeetingRoom(models.Model): - room_id = models.AutoField(primary_key=True) - meeting = models.ForeignKey(Meeting, db_column='meeting_num') - room_name = models.CharField(max_length=255) - def __str__(self): - return "[%d] %s" % (self.meeting_id, self.room_name) - class Meta: - db_table = 'meeting_rooms' - verbose_name = "Meeting room name" - -class SessionStatus(models.Model): - id = models.AutoField(primary_key=True, db_column='status_id') - name = models.CharField(max_length=32, db_column='status') - def __str__(self): - return self.name - class Meta: - db_table = 'session_status' - - -class WgMeetingSession(models.Model, ResolveAcronym): - session_id = models.AutoField(primary_key=True) - meeting = models.ForeignKey(Meeting, db_column='meeting_num') - group_acronym_id = models.IntegerField() - irtf = models.NullBooleanField() - num_session = models.IntegerField() - length_session1 = models.CharField(blank=True, max_length=100) - length_session2 = models.CharField(blank=True, max_length=100) - length_session3 = models.CharField(blank=True, max_length=100) - conflict1 = models.CharField(blank=True, max_length=255) - conflict2 = models.CharField(blank=True, max_length=255) - conflict3 = models.CharField(blank=True, max_length=255) - conflict_other = models.TextField(blank=True) - special_req = models.TextField(blank=True) - number_attendee = models.IntegerField(null=True, blank=True) - approval_ad = models.IntegerField(null=True, blank=True) - status = models.ForeignKey(SessionStatus, null=True, blank=True) - ts_status_id = models.IntegerField(null=True, blank=True) - requested_date = models.DateField(null=True, blank=True) - approved_date = models.DateField(null=True, blank=True) - requested_by = BrokenForeignKey(PersonOrOrgInfo, db_column='requested_by', null=True, null_values=(0, 888888)) - scheduled_date = models.DateField(null=True, blank=True) - last_modified_date = models.DateField(null=True, blank=True) - ad_comments = models.TextField(blank=True,null=True) - sched_room_id1 = models.ForeignKey(MeetingRoom, db_column='sched_room_id1', null=True, blank=True, related_name='here1') - sched_time_id1 = BrokenForeignKey(MeetingTime, db_column='sched_time_id1', null=True, blank=True, related_name='now1') - sched_date1 = models.DateField(null=True, blank=True) - sched_room_id2 = models.ForeignKey(MeetingRoom, db_column='sched_room_id2', null=True, blank=True, related_name='here2') - sched_time_id2 = BrokenForeignKey(MeetingTime, db_column='sched_time_id2', null=True, blank=True, related_name='now2') - sched_date2 = models.DateField(null=True, blank=True) - sched_room_id3 = models.ForeignKey(MeetingRoom, db_column='sched_room_id3', null=True, blank=True, related_name='here3') - sched_time_id3 = BrokenForeignKey(MeetingTime, db_column='sched_time_id3', null=True, blank=True, related_name='now3') - sched_date3 = models.DateField(null=True, blank=True) - special_agenda_note = models.CharField(blank=True, max_length=255) - combined_room_id1 = models.ForeignKey(MeetingRoom, db_column='combined_room_id1', null=True, blank=True, related_name='here4') - combined_time_id1 = BrokenForeignKey(MeetingTime, db_column='combined_time_id1', null=True, blank=True, related_name='now4') - combined_room_id2 = models.ForeignKey(MeetingRoom, db_column='combined_room_id2', null=True, blank=True, related_name='here5') - combined_time_id2 = BrokenForeignKey(MeetingTime, db_column='combined_time_id2', null=True, blank=True, related_name='now5') - def __str__(self): - return "%s at %s" % (self.acronym(), self.meeting) - def agenda_file(self,interimvar=0): - if hasattr(self, '_agenda_file'): - return self._agenda_file - irtfvar = 0 - if self.irtf: - irtfvar = self.group_acronym_id - if interimvar == 0: - try: - if self.interim: - interimvar = 1 - except AttributeError: - interimvar = 0 - try: - filename = WgAgenda.objects.get(meeting=self.meeting, group_acronym_id=self.group_acronym_id,irtf=irtfvar,interim=interimvar).filename - if self.meeting_id in WgMeetingSession._dirs: - dir = WgMeetingSession._dirs[self.meeting_id] - else: - dir = Proceeding.objects.get(meeting_num=self.meeting).dir_name - WgMeetingSession._dirs[self.meeting_id]=dir - retvar = "%s/agenda/%s" % (dir,filename) - except WgAgenda.DoesNotExist: - retvar = "" - self._agenda_file = retvar - return retvar - def minute_file(self,interimvar=0): - irtfvar = 0 - if self.irtf: - irtfvar = self.group_acronym_id - if interimvar == 0: - try: - if self.interim: - interimvar = 1 - except AttributeError: - interimvar = 0 - try: - filename = Minute.objects.get(meeting=self.meeting, group_acronym_id=self.group_acronym_id,irtf=irtfvar,interim=interimvar).filename - dir = Proceeding.objects.get(meeting_num=self.meeting).dir_name - retvar = "%s/minutes/%s" % (dir,filename) - except Minute.DoesNotExist: - retvar = "" - return retvar - def slides(self,interimvar=0): - """ - Get all slides of this session. - """ - irtfvar = 0 - if self.irtf: - irtfvar = self.group_acronym_id - if interimvar == 0: - try: - if self.interim: - interimvar = 1 - except AttributeError: - interimvar = 0 - slides = Slide.objects.filter(meeting=self.meeting,group_acronym_id=self.group_acronym_id,irtf=irtfvar,interim=interimvar).order_by("order_num") - return slides - def interim_meeting (self): - if self.minute_file(1): - return True - elif self.agenda_file(1): - return True - elif self.slides(1): - return True - else: - return False - def length_session1_desc (self): - mh = MeetingHour.objects.get(hour_id=self.length_session1) - return mh.hour_desc - def length_session2_desc (self): - mh = MeetingHour.objects.get(hour_id=self.length_session2) - return mh.hour_desc - def length_session3_desc (self): - mh = MeetingHour.objects.get(hour_id=self.length_session3) - return mh.hour_desc - class Meta: - db_table = 'wg_meeting_sessions' - verbose_name = "WG meeting session" - - _dirs = {} - -class WgAgenda(models.Model, ResolveAcronym): - meeting = models.ForeignKey(Meeting, db_column='meeting_num') - group_acronym_id = models.IntegerField() - filename = models.CharField(max_length=255) - irtf = models.IntegerField() - interim = models.BooleanField() - def __str__(self): - return "Agenda for %s at IETF %s" % (self.acronym(), self.meeting_id) - class Meta: - db_table = 'wg_agenda' - verbose_name = "WG agenda info" - verbose_name_plural = "WG agenda info" - -class Minute(models.Model, ResolveAcronym): - meeting = models.ForeignKey(Meeting, db_column='meeting_num') - group_acronym_id = models.IntegerField() - filename = models.CharField(blank=True, max_length=255) - irtf = models.IntegerField() - interim = models.BooleanField() - def __str__(self): - return "Minutes for %s at IETF %s" % (self.acronym(), self.meeting_id) - class Meta: - db_table = 'minutes' - verbose_name = "WG minutes info" - - -# It looks like Switches was meant for something bigger, but -# is only used for the agenda generation right now so we'll -# put it here. -class Switches(models.Model): - name = models.CharField(max_length=100) - val = models.IntegerField(null=True, blank=True) - updated_date = models.DateField(null=True, blank=True) - updated_time = models.TimeField(null=True, blank=True) - def updated(self): - return datetime.datetime.combine( self.updated_date, self.updated_time ) - def __str__(self): - return self.name - class Meta: - db_table = 'switches' - verbose_name = "Switch" - verbose_name_plural = "Switches" - -# Empty table, don't pretend that it exists. -#class SlideTypes(models.Model): -# type_id = models.AutoField(primary_key=True) -# type = models.CharField(max_length=255, db_column='type_name') -# def __str__(self): -# return self.type -# class Meta: -# db_table = 'slide_types' - -class Slide(models.Model, ResolveAcronym): - SLIDE_TYPE_CHOICES=( - ('1', '(converted) HTML'), - ('2', 'PDF'), - ('3', 'Text'), - ('4', 'PowerPoint -2003 (PPT)'), - ('5', 'Microsoft Word'), - ('6', 'PowerPoint 2007- (PPTX)'), - ) - meeting = models.ForeignKey(Meeting, db_column='meeting_num') - group_acronym_id = models.IntegerField(null=True, blank=True) - slide_num = models.IntegerField(null=True, blank=True) - slide_type_id = models.IntegerField(choices=SLIDE_TYPE_CHOICES) - slide_name = models.CharField(blank=True, max_length=255) - irtf = models.IntegerField() - interim = models.BooleanField() - order_num = models.IntegerField(null=True, blank=True) - in_q = models.IntegerField(null=True, blank=True) - def __str__(self): - return "IETF%d: %s slides (%s)" % (self.meeting_id, self.acronym(), self.slide_name) - def file_loc(self): - dir = Proceeding.objects.get(meeting_num=self.meeting).dir_name - if self.slide_type_id==1: - #return "%s/slides/%s-%s/sld1.htm" % (dir,self.acronym(),self.slide_num) - return "%s/slides/%s-%s/%s-%s.htm" % (dir,self.acronym(),self.slide_num,self.acronym(),self.slide_num) - else: - if self.slide_type_id == 2: - ext = ".pdf" - elif self.slide_type_id == 3: - ext = ".txt" - elif self.slide_type_id == 4: - ext = ".ppt" - elif self.slide_type_id == 5: - ext = ".doc" - elif self.slide_type_id == 6: - ext = ".pptx" - else: - ext = "" - return "%s/slides/%s-%s%s" % (dir,self.acronym(),self.slide_num,ext) - class Meta: - db_table = 'slides' - -class WgProceedingsActivities(models.Model, ResolveAcronym): - id = models.AutoField(primary_key=True) - #group_acronym_id = models.IntegerField(null=True, blank=True) - group_acronym = models.ForeignKey(Acronym) - - meeting = models.ForeignKey(Meeting, db_column='meeting_num') - activity = models.CharField(blank=True, max_length=255) - act_date = models.DateField(null=True, blank=True) - act_time = models.CharField(blank=True, max_length=100) - act_by = models.ForeignKey(PersonOrOrgInfo, db_column='act_by') - irtf = None - - def __str__(self): - return "IETF%d: %s %s" % (self.meeting_id, self.acronym(), self.activity) - class Meta: - db_table = 'wg_proceedings_activities' - verbose_name = "WG material upload" - -class MeetingHour(models.Model): - hour_id = models.IntegerField(primary_key=True) - hour_desc = models.CharField(max_length=60, blank=True) - def __unicode__(self): - return self.hour_desc - class Meta: - db_table = u'meeting_hours' - -class NotMeetingGroup(models.Model): - # note: phony key, there's no primary key in db - group_acronym = models.ForeignKey(Acronym, primary_key=True, null=True, blank=True) - meeting = models.ForeignKey(Meeting, db_column='meeting_num', null=True, blank=True) - class Meta: - db_table = u'not_meeting_groups' - -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - MeetingOld = Meeting - ProceedingOld = Proceeding - MeetingVenueOld = MeetingVenue - MeetingTimeOld = MeetingTime - WgMeetingSessionOld = WgMeetingSession - SlideOld = Slide - SwitchesOld = Switches - IESGHistoryOld = IESGHistory - from ietf.meeting.proxy import MeetingProxy as Meeting, ProceedingProxy as Proceeding, MeetingVenueProxy as MeetingVenue, MeetingTimeProxy as MeetingTime, WgMeetingSessionProxy as WgMeetingSession, SlideProxy as Slide, SwitchesProxy as Switches, IESGHistoryProxy as IESGHistory - -# changes done by convert-096.py:changed maxlength to max_length -# removed core -# removed raw_id_admin diff --git a/ietf/proceedings/views.py b/ietf/proceedings/views.py deleted file mode 100644 index f9a44e3f2..000000000 --- a/ietf/proceedings/views.py +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright The IETF Trust 2007, All Rights Reserved - -# Create your views here. diff --git a/ietf/redirects/tests.py b/ietf/redirects/tests.py index c9b4bde84..38361cb78 100644 --- a/ietf/redirects/tests.py +++ b/ietf/redirects/tests.py @@ -33,7 +33,7 @@ import unittest, os, re from django.test.client import Client from django.conf import settings -from ietf.utils.test_utils import SimpleUrlTestCase, RealDatabaseTest, split_url, read_testurls +from ietf.utils.test_utils import split_url, read_testurls, TestCase import ietf.urls import ietf.utils.test_runner as test_runner @@ -60,6 +60,10 @@ REDIRECT_TESTS = { '/drafts/10845/related/', '/public/idindex.cgi?command=id_detail&filename=draft-l3vpn-as4octet-ext-community': '/drafts/draft-l3vpn-as4octet-ext-community/', + # non-ASCII parameter + '/public/pidtracker.cgi?command=view_id&dTag=11171%D182&rfc_flag=0': + '/idtracker/', + '/idtracker/': '/doc/', # ipr @@ -86,118 +90,20 @@ REDIRECT_TESTS = { } -class RedirectsTestCase(unittest.TestCase, RealDatabaseTest): - def setUp(self): - self.setUpRealDatabase() - def tearDown(self): - self.tearDownRealDatabase() - - def testRedirects(self): - print " Testing redirects" - - c = Client() +class RedirectsTests(TestCase): + def test_redirects(self): for src, dst in REDIRECT_TESTS.items(): baseurl, args = split_url(src) - try: - response = c.get(baseurl, args) - self.assert_(str(response.status_code).startswith("3")) - location = response['Location'] - if location.startswith("http://testserver/"): - location = location[17:] - self.assertEqual(location, dst) - print "OK "+src - except: - print "Fail "+src - raise + response = self.client.get(baseurl, args) + self.assertTrue(str(response.status_code).startswith("3")) + location = response['Location'] + if location.startswith("http://testserver/"): + location = location[17:] + self.assertEqual(location, dst, (src, dst, location)) -def get_patterns(module): - all = [] - try: - patterns = module.urlpatterns - except AttributeError: - patterns = [] - for item in patterns: - try: - subpatterns = get_patterns(item.urlconf_module) - except: - subpatterns = [""] - for sub in subpatterns: - if not sub: - all.append(item.regex.pattern) - elif sub.startswith("^"): - all.append(item.regex.pattern + sub[1:]) - else: - all.append(item.regex.pattern + ".*" + sub) - return all - -class UrlCoverageTestCase(unittest.TestCase): - def testUrlCoverage(self): - print " Testing testurl.list coverage" - testtuples = [] - for root, dirs, files in os.walk(settings.BASE_DIR): - if "testurl.list" in files: - testtuples += read_testurls(root+"/testurl.list") - - patterns = get_patterns(ietf.urls) - covered = [] - for codes, testurl, goodurl in testtuples: - for pattern in patterns: - if re.match(pattern, testurl[1:]): - covered.append(pattern) - - if not set(patterns) == set(covered): - missing = list(set(patterns) - set(covered)) - print "The following URLs are not tested by any testurl.list" - for pattern in missing: - if not pattern[1:].split("/")[0] in [ "admin", "accounts" ]: - print " NoTest", pattern - print "" - else: - print "All URLs are included in some testurl.list" - -class MainUrlTestCase(SimpleUrlTestCase): - def testUrls(self): - self.doTestUrls(__file__) - -def get_templates(): - templates = set() - # Shoud we teach this to use TEMPLATE_DIRS? - templatepath = os.path.join(settings.BASE_DIR,"templates") - for root, dirs, files in os.walk(templatepath): - if ".svn" in dirs: - dirs.remove(".svn") - relative_path = root[len(templatepath)+1:] - for file in files: - if file.endswith("~") or file.startswith("#"): - continue - if relative_path == "": - templates.add(file) - else: - templates.add(os.path.join(relative_path, file)) - return templates - -class TemplateCoverageTestCase(unittest.TestCase): - def testTemplateCoverage(self): - if not test_runner.loaded_templates: - print " Skipping template coverage test" - return - - print " Testing template coverage" - all_templates = get_templates() - - #notexist = list(test_runner.loaded_templates - all_templates) - #if notexist: - # notexist.sort() - # print "The following templates do not exist" - # for x in notexist: - # print "NotExist", x - - notloaded = list(all_templates - test_runner.loaded_templates) - if notloaded: - notloaded.sort() - print "The following templates were never loaded during test" - for x in notloaded: - print " NotLoaded", x - else: - print " All templates were loaded during test" - +class MainUrlTests(TestCase): + def test_urls(self): + self.assertEqual(self.client.get("/_doesnotexist/").status_code, 404) + self.assertEqual(self.client.get("/sitemap.xml").status_code, 200) + # Google webmaster tool verification page + self.assertEqual(self.client.get("/googlea30ad1dacffb5e5b.html").status_code, 200) diff --git a/ietf/redirects/testurl.list b/ietf/redirects/testurl.list deleted file mode 100644 index a572120e4..000000000 --- a/ietf/redirects/testurl.list +++ /dev/null @@ -1,16 +0,0 @@ -# Top-level test URL list. Should probably be empty; all test URls should be -# specified in the application level testurl.list - -200 /googlea30ad1dacffb5e5b.html # Google webmaster tool verification page -200 /sitemap.xml -404 /_doesnotexist/ -#skip /_test500/ - -# non-ASCII parameter -301 /public/pidtracker.cgi?command=view_id&dTag=11171%D182&rfc_flag=0 - -#301 /list/request.... # test middleware that strips periods and redirects instead of 404 -#skip /images/ietf-icon.bmp -#skip /css/base.css -#skip /js/ - diff --git a/ietf/secr/announcement/forms.py b/ietf/secr/announcement/forms.py index eca264aac..a22a35e74 100644 --- a/ietf/secr/announcement/forms.py +++ b/ietf/secr/announcement/forms.py @@ -6,8 +6,7 @@ from ietf.secr.utils.mail import MultiEmailField from ietf.secr.utils.group import current_nomcom from ietf.message.models import Message -from ietf.ietfauth.decorators import has_role -from ietf.wgchairs.accounts import get_person_for_user +from ietf.ietfauth.utils import has_role # --------------------------------------------- # Globals @@ -136,7 +135,6 @@ def get_to_choices(): # --------------------------------------------- # Select Choices # --------------------------------------------- -#TO_CHOICES = tuple(AnnouncedTo.objects.values_list('announced_to_id','announced_to')) TO_CHOICES = get_to_choices() #FROM_CHOICES = get_from_choices() @@ -185,7 +183,7 @@ class AnnounceForm(forms.ModelForm): def save(self, *args, **kwargs): user = kwargs.pop('user') message = super(AnnounceForm, self).save(commit=False) - message.by = get_person_for_user(user) + message.by = user.get_profile() if self.cleaned_data['to'] == 'Other...': message.to = self.cleaned_data['to_custom'] if kwargs['commit']: diff --git a/ietf/secr/announcement/models.py b/ietf/secr/announcement/models.py index 948c3a258..d3855c5b0 100644 --- a/ietf/secr/announcement/models.py +++ b/ietf/secr/announcement/models.py @@ -1,4 +1,3 @@ from django.db import models -from ietf.announcements.models import AnnouncedTo #from ietf.message.models import Message from ietf.group.models import Group, Role diff --git a/ietf/secr/announcement/tests.py b/ietf/secr/announcement/tests.py index 1884843f3..0a120d61d 100644 --- a/ietf/secr/announcement/tests.py +++ b/ietf/secr/announcement/tests.py @@ -4,11 +4,10 @@ from ietf.utils import TestCase from django.contrib.auth.models import User from ietf.group.models import Group -from ietf.ietfauth.decorators import has_role +from ietf.ietfauth.utils import has_role from ietf.person.models import Person from ietf.utils.mail import outbox from ietf.utils.test_data import make_test_data -from ietf.utils.test_utils import SimpleUrlTestCase, RealDatabaseTest from pyquery import PyQuery @@ -16,15 +15,7 @@ SECR_USER='secretary' WG_USER='' AD_USER='' -#class AnnouncementUrlTestCase(SimpleUrlTestCase): -# def testUrls(self): -# self.doTestUrls(__file__) - - class MainTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] - # ------- Test View -------- # def test_main(self): "Main Test" @@ -37,8 +28,6 @@ class DummyCase(TestCase): name = connection.settings_dict['NAME'] class UnauthorizedCase(TestCase): - perma_fixtures = ['names'] - def test_unauthorized(self): "Unauthorized Test" draft = make_test_data() @@ -48,8 +37,6 @@ class UnauthorizedCase(TestCase): self.assertEquals(r.status_code, 403) class SubmitCase(TestCase): - perma_fixtures = ['names'] - def test_invalid_submit(self): "Invalid Submit" draft = make_test_data() diff --git a/ietf/secr/announcement/testurl.list b/ietf/secr/announcement/testurl.list deleted file mode 100644 index feb87e008..000000000 --- a/ietf/secr/announcement/testurl.list +++ /dev/null @@ -1 +0,0 @@ -200 /secr/announcement/ diff --git a/ietf/secr/announcement/views.py b/ietf/secr/announcement/views.py index a32ec44f5..61f3e92b3 100644 --- a/ietf/secr/announcement/views.py +++ b/ietf/secr/announcement/views.py @@ -4,9 +4,8 @@ from django.http import HttpResponseRedirect, HttpResponse, HttpResponseForbidde from django.shortcuts import render_to_response, get_object_or_404 from django.template import RequestContext -from ietf.ietfauth.decorators import has_role +from ietf.ietfauth.utils import has_role from ietf.utils.mail import send_mail_text -from ietf.wgchairs.accounts import get_person_for_user from ietf.group.models import Group from ietf.secr.utils.group import current_nomcom from ietf.secr.utils.decorators import check_for_cancel @@ -111,4 +110,4 @@ def confirm(request): 'message': data, 'to': to}, RequestContext(request, {}), - ) \ No newline at end of file + ) diff --git a/ietf/secr/areas/tests.py b/ietf/secr/areas/tests.py index 9b70fc916..497f8ea79 100644 --- a/ietf/secr/areas/tests.py +++ b/ietf/secr/areas/tests.py @@ -3,7 +3,7 @@ from ietf.utils import TestCase from django.contrib.auth.models import User from ietf.group.models import Group, GroupEvent -from ietf.ietfauth.decorators import has_role +from ietf.ietfauth.utils import has_role from ietf.person.models import Person from ietf.utils.test_data import make_test_data @@ -14,7 +14,7 @@ import datetime SECR_USER='secretary' def augment_data(): - system = Person.objects.get(name="(system)") + system = Person.objects.get(name="(System)") area = Group.objects.get(acronym='farfut') GroupEvent.objects.create(group=area, type='started', @@ -22,7 +22,7 @@ def augment_data(): class MainTestCase(TestCase): # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names', 'persons', 'groupgroup', 'groupevents'] + perma_fixtures = ['groupgroup', 'groupevents'] def test_main(self): "Main Test" diff --git a/ietf/secr/drafts/email.py b/ietf/secr/drafts/email.py index d72af76e9..688400557 100644 --- a/ietf/secr/drafts/email.py +++ b/ietf/secr/drafts/email.py @@ -3,7 +3,7 @@ from django.core.exceptions import ObjectDoesNotExist from django.template.loader import render_to_string from ietf.message.models import Message, SendQueue -from ietf.announcements.send_scheduled import send_scheduled_announcement +from ietf.message.utils import send_scheduled_message_from_send_queue from ietf.doc.models import DocumentAuthor from ietf.person.models import Person from ietf.secr.utils.document import get_start_date @@ -41,7 +41,7 @@ def announcement_from_form(data, **kwargs): send_queue = SendQueue.objects.create(by=by,message=message) # uncomment for testing - send_scheduled_announcement(send_queue) + send_scheduled_message_from_send_queue(send_queue) return message @@ -78,19 +78,6 @@ def get_abbr_authors(draft): return result -def get_authors_email(draft): - """ - Takes a draft object and returns a string of authors suitable for an email to or cc field - """ - authors = [] - for a in draft.authors.all(): - initial = '' - if a.person.first_name: - initial = a.person.first_name[0] + '. ' - entry = '%s%s <%s>' % (initial,a.person.last_name,a.person.email()) - authors.append(entry) - return ', '.join(authors) - def get_last_revision(filename): """ This function takes a filename, in the same form it appears in the InternetDraft record, diff --git a/ietf/secr/drafts/forms.py b/ietf/secr/drafts/forms.py index 5d4d13846..e5ced7dc3 100644 --- a/ietf/secr/drafts/forms.py +++ b/ietf/secr/drafts/forms.py @@ -375,7 +375,7 @@ class UploadForm(forms.Form): # ensure that the basename is unique base = splitext(txt.name)[0] if Document.objects.filter(name=base[:-3]): - raise forms.ValidationError, "This doucment filename already exists: %s" % base[:-3] + raise forms.ValidationError, "This document filename already exists: %s" % base[:-3] # ensure that rev is 00 if base[-2:] != '00': diff --git a/ietf/secr/drafts/tests.py b/ietf/secr/drafts/tests.py index 53c5e89ef..c905dc250 100644 --- a/ietf/secr/drafts/tests.py +++ b/ietf/secr/drafts/tests.py @@ -9,9 +9,6 @@ from pyquery import PyQuery SECR_USER='secretary' class MainTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] - def test_main(self): "Main Test" draft = make_test_data() @@ -25,4 +22,4 @@ class MainTestCase(TestCase): drafts = Document.objects.filter(type='draft') url = reverse('drafts_view', kwargs={'id':drafts[0].name}) response = self.client.get(url, REMOTE_USER=SECR_USER) - self.assertEquals(response.status_code, 200) \ No newline at end of file + self.assertEquals(response.status_code, 200) diff --git a/ietf/secr/drafts/views.py b/ietf/secr/drafts/views.py index b0ebc9126..1191aea14 100644 --- a/ietf/secr/drafts/views.py +++ b/ietf/secr/drafts/views.py @@ -17,7 +17,7 @@ from ietf.meeting.models import Meeting from ietf.name.models import StreamName from ietf.doc.models import Document, DocumentAuthor from ietf.doc.utils import augment_with_start_time -from ietf.submit.models import IdSubmissionDetail, Preapproval +from ietf.submit.models import Submission, Preapproval, DraftSubmissionStateName, SubmissionEvent from ietf.utils.draft import Draft from ietf.secr.proceedings.proc_utils import get_progress_stats from ietf.secr.sreq.views import get_meeting @@ -107,7 +107,7 @@ def process_files(request,draft): the basename, revision number and a list of file types. Basename and revision are assumed to be the same for all because this is part of the validation process. - It also creates the IdSubmissionDetail record WITHOUT saving, and places it in the + It also creates the Submission record WITHOUT saving, and places it in the session for saving in the final action step. ''' files = request.FILES @@ -124,29 +124,37 @@ def process_files(request,draft): wrapper = Draft(file.read(),file.name) handle_uploaded_file(file) - # create IdSubmissionDetail record, leaved unsaved - idsub = IdSubmissionDetail( - id_document_name=draft.title, - filename=basename, - revision=revision, - txt_page_count=draft.pages, - filesize=txt_size, - creation_date=wrapper.get_creation_date(), + # create Submission record, leaved unsaved + idsub = Submission( + name=basename, + title=draft.title, + rev=revision, + pages=draft.pages, + file_size=txt_size, + document_date=wrapper.get_creation_date(), submission_date=datetime.date.today(), idnits_message='idnits bypassed by manual posting', - temp_id_document_tag=None, - group_acronym_id=draft.group.id, + group_id=draft.group.id, remote_ip=request.META['REMOTE_ADDR'], first_two_pages=''.join(wrapper.pages[:2]), - status_id=-2, + state=DraftSubmissionStateName.objects.get(slug="posted"), abstract=draft.abstract, - file_type=','.join(file_type_list), - man_posted_date=datetime.date.today(), - man_posted_by=request.user.get_profile()) + file_types=','.join(file_type_list), + ) request.session['idsub'] = idsub return (filename,revision,file_type_list) +def post_submission(request): + submission = request.session['idsub'] + submission.save() + + SubmissionEvent.objects.create( + submission=submission, + by=request.user.person, + desc="Submitted and posted manually") + + def promote_files(draft, types): ''' This function takes one argument, a draft object. It then moves the draft files from @@ -307,8 +315,8 @@ def do_revision(draft, request): promote_files(new_draft, request.session['file_type']) # save the submission record - request.session['idsub'].save() - + post_submission(request) + # send announcement if we are in IESG process if new_draft.get_state('draft-iesg'): announcement_from_form(request.session['email'],by=request.user.get_profile()) @@ -355,8 +363,8 @@ def do_update(draft,request): promote_files(new_draft, request.session['file_type']) # save the submission record - request.session['idsub'].save() - + post_submission(request) + # send announcement announcement_from_form(request.session['email'],by=request.user.get_profile()) @@ -580,7 +588,7 @@ def add(request): promote_files(draft, file_type_list) # save the submission record - request.session['idsub'].save() + post_submission(request) request.session['action'] = 'add' diff --git a/ietf/secr/groups/tests.py b/ietf/secr/groups/tests.py index b1f023594..1c9c6e539 100644 --- a/ietf/secr/groups/tests.py +++ b/ietf/secr/groups/tests.py @@ -9,7 +9,7 @@ SECR_USER='secretary' class GroupsTest(TestCase): # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names','persons','groupgroup',] + perma_fixtures = ['persons','groupgroup',] """ perma_fixtures = [ 'acronym.json', 'area.json', diff --git a/ietf/secr/ipradmin/forms.py b/ietf/secr/ipradmin/forms.py index 7f601033b..ef37d1fe8 100644 --- a/ietf/secr/ipradmin/forms.py +++ b/ietf/secr/ipradmin/forms.py @@ -5,7 +5,7 @@ from django.utils.safestring import mark_safe from django.forms.formsets import formset_factory from django.utils import simplejson -from ietf.ipr.models import IprDetail, IprContact, LICENSE_CHOICES, IprRfc, IprDraft, IprUpdate, SELECT_CHOICES, IprDocAlias +from ietf.ipr.models import IprDetail, IprContact, LICENSE_CHOICES, IprUpdate, SELECT_CHOICES, IprDocAlias from ietf.doc.models import DocAlias from ietf.secr.utils.document import get_rfc_num @@ -148,11 +148,11 @@ class IprDetailForm(BetterModelForm): self.fields['updated'].initial = updates[0].updated.ipr_id rfcs = {} - for rfc in self.instance.documents.filter(doc_alias__name__startswith='rfc'): + 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.documents.exclude(doc_alias__name__startswith='rfc'): + 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'] = simplejson.dumps(rfcs) self.initial['id_filename'] = simplejson.dumps(drafts) @@ -246,14 +246,7 @@ class IprDetailForm(BetterModelForm): obj.status_to_be = old_ipr.status obj.processed = 0 obj.save() - ''' - IprRfc.objects.filter(ipr=ipr_detail).delete() - IprDraft.objects.filter(ipr=ipr_detail).delete() - for rfc in self.cleaned_data['rfc_num']: - IprRfc.objects.create(ipr=ipr_detail, document=rfc) - for draft in self.cleaned_data['id_filename']: - IprDraft.objects.create(ipr=ipr_detail, document=draft) - ''' + IprDocAlias.objects.filter(ipr=ipr_detail).delete() for doc in self.cleaned_data['rfc_num']: IprDocAlias.objects.create(ipr=ipr_detail,doc_alias=doc) diff --git a/ietf/secr/ipradmin/models.py b/ietf/secr/ipradmin/models.py index e9c9bed54..137941ffa 100644 --- a/ietf/secr/ipradmin/models.py +++ b/ietf/secr/ipradmin/models.py @@ -1,193 +1 @@ -# Copyright The IETF Trust 2007, All Rights Reserved - from django.db import models -#from django import newforms as forms -#from sec.drafts.models import InternetDraft -#from sec.drafts.models import Rfc - -from ietf.ipr.models import * - -# ------------------------------------------------------------------------ -# Models - -''' -LICENSE_CHOICES = ( - (1, 'a) No License Required for Implementers.'), - (2, 'b) Royalty-Free, Reasonable and Non-Discriminatory License to All Implementers.'), - (3, 'c) Reasonable and Non-Discriminatory License to All Implementers with Possible Royalty/Fee.'), - (4, '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).'), - (5, 'e) Unwilling to Commit to the Provisions of a), b), or c) Above.'), - (6, 'f) See Text Below for Licensing Declaration.'), -) -STDONLY_CHOICES = ( - (0, ""), - (1, "The licensing declaration is limited solely to standards-track IETF documents."), -) -SELECT_CHOICES = ( - (0, 'NO'), - (1, 'YES'), - (2, 'NO'), -) -STATUS_CHOICES = ( - ( 0, "Waiting for approval" ), - ( 1, "Approved and Posted" ), - ( 2, "Rejected by Administrator" ), - ( 3, "Removed by Request" ), -) -# not clear why this has both an ID and selecttype -# Also not clear why a table for "YES" and "NO". -class IprSelecttype(models.Model): - type_id = models.AutoField(primary_key=True) - is_pending = models.IntegerField(unique=True, db_column="selecttype") - type_display = models.CharField(blank=True, max_length=15) - def __str__(self): - return self.type_display - class Meta: - db_table = 'ipr_selecttype' - -class IprLicensing(models.Model): - licensing_option = models.AutoField(primary_key=True) - value = models.CharField(max_length=255, db_column='licensing_option_value') - def __str__(self): - return self.value; - class Meta: - db_table = 'ipr_licensing' - - -class IprDetail(models.Model): - ipr_id = models.AutoField(primary_key=True) - title = models.CharField(blank=True, db_column="document_title", max_length=255) - - # Legacy information fieldset - legacy_url_0 = models.CharField(blank=True, null=True, db_column="old_ipr_url", max_length=255) - legacy_url_1 = models.CharField(blank=True, null=True, db_column="additional_old_url1", max_length=255) - legacy_title_1 = models.CharField(blank=True, null=True, db_column="additional_old_title1", max_length=255) - legacy_url_2 = models.CharField(blank=True, null=True, db_column="additional_old_url2", max_length=255) - legacy_title_2 = models.CharField(blank=True, null=True, db_column="additional_old_title2", max_length=255) - - # Patent holder fieldset - legal_name = models.CharField("Legal Name", db_column="p_h_legal_name", max_length=255) - - # Patent Holder Contact fieldset - # self.contact.filter(contact_type=1) - - # IETF Contact fieldset - # self.contact.filter(contact_type=3) - - # Related IETF Documents fieldset - rfc_number = models.IntegerField(null=True, editable=False, blank=True) # always NULL - id_document_tag = models.IntegerField(null=True, editable=False, blank=True) # always NULL - other_designations = models.CharField(blank=True, max_length=255) - document_sections = models.TextField("Specific document sections covered", blank=True, max_length=255, db_column='disclouser_identify') - - # Patent Information fieldset - patents = models.TextField("Patent Applications", db_column="p_applications", max_length=255) - date_applied = models.CharField(max_length=255) - country = models.CharField(max_length=100) - notes = models.TextField("Additional notes", db_column="p_notes", blank=True) - # AMS Change - #is_pending = models.IntegerField("Unpublished Pending Patent Application", blank=True, choices=SELECT_CHOICES, db_column="selecttype") - #is_pending = models.BooleanField(db_column="selecttype") - is_pending = models.CharField(max_length=3,db_column="selecttype") - applies_to_all = models.IntegerField("Applies to all IPR owned by Submitter", blank=True, choices=SELECT_CHOICES, db_column="selectowned") - - # Licensing Declaration fieldset - #licensing_option = models.ForeignKey(IprLicensing, db_column='licensing_option') - licensing_option = models.IntegerField(null=True, blank=True, choices=LICENSE_CHOICES) - lic_opt_a_sub = models.IntegerField(editable=False, choices=STDONLY_CHOICES) - lic_opt_b_sub = models.IntegerField(editable=False, choices=STDONLY_CHOICES) - lic_opt_c_sub = models.IntegerField(editable=False, choices=STDONLY_CHOICES) - comments = models.TextField("Licensing Comments", blank=True) - lic_checkbox = models.BooleanField("All terms and conditions has been disclosed") - - - # Other notes fieldset - other_notes = models.TextField(blank=True) - - # Generated fields, not part of the submission form - # Hidden fields - third_party = models.BooleanField() - generic = models.BooleanField() - comply = models.BooleanField() - - status = models.IntegerField(null=True, blank=True, choices=STATUS_CHOICES) - submitted_date = models.DateField(blank=True) - update_notified_date = models.DateField(null=True, blank=True) - - def __str__(self): - return self.title - def docs(self): - return list(self.drafts.all()) + list(self.rfcs.all()) - def get_absolute_url(self): - return "/ipr/%d/" % self.ipr_id - def get_submitter(self): - try: - return self.contact.get(contact_type=3) - except IprContact.DoesNotExist: - return None - class Meta: - db_table = 'ipr_detail' - -class IprContact(models.Model): - TYPE_CHOICES = ( - (1, 'Patent Holder Contact'), - (2, 'IETF Participant Contact'), - (3, 'Submitter Contact'), - ) - contact_id = models.AutoField(primary_key=True) - ipr = models.ForeignKey(IprDetail, related_name="contact") - contact_type = models.IntegerField(choices=TYPE_CHOICES) - name = models.CharField(max_length=255) - title = models.CharField(blank=True, max_length=255) - department = models.CharField(blank=True, max_length=255) - address1 = models.CharField(blank=True, max_length=255) - address2 = models.CharField(blank=True, max_length=255) - telephone = models.CharField(max_length=25) - fax = models.CharField(blank=True, max_length=25) - email = models.EmailField(max_length=255) - def __str__(self): - return self.name or '' - class Meta: - db_table = 'ipr_contacts' - - -class IprDraft(models.Model): - ipr = models.ForeignKey(IprDetail, related_name='drafts') - document = models.ForeignKey(InternetDraft, db_column='id_document_tag', related_name="ipr") - revision = models.CharField(max_length=2) - def __str__(self): - return "%s which applies to %s-%s" % ( self.ipr, self.document, self.revision ) - class Meta: - db_table = 'ipr_ids' - -class IprNotification(models.Model): - ipr = models.ForeignKey(IprDetail) - notification = models.TextField(blank=True) - date_sent = models.DateField(null=True, blank=True) - time_sent = models.CharField(blank=True, max_length=25) - def __str__(self): - return "IPR notification for %s sent %s %s" % (self.ipr, self.date_sent, self.time_sent) - class Meta: - db_table = 'ipr_notifications' - -class IprRfc(models.Model): - ipr = models.ForeignKey(IprDetail, related_name='rfcs') - document = models.ForeignKey(Rfc, db_column='rfc_number', related_name="ipr") - def __str__(self): - return "%s applies to RFC%04d" % ( self.ipr, self.document_id ) - class Meta: - db_table = 'ipr_rfcs' - -class IprUpdate(models.Model): - id = models.IntegerField(primary_key=True) - ipr = models.ForeignKey(IprDetail, related_name='updates') - updated = models.ForeignKey(IprDetail, db_column='updated', related_name='updated_by') - status_to_be = models.IntegerField(null=True, blank=True) - processed = models.IntegerField(null=True, blank=True) - class Meta: - db_table = 'ipr_updates' - -''' diff --git a/ietf/secr/ipradmin/tests.py b/ietf/secr/ipradmin/tests.py index c64a50654..36e33c677 100644 --- a/ietf/secr/ipradmin/tests.py +++ b/ietf/secr/ipradmin/tests.py @@ -9,9 +9,6 @@ from pyquery import PyQuery SECR_USER='secretary' class MainTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] - def test_main(self): "Main Test" draft = make_test_data() @@ -26,4 +23,4 @@ class MainTestCase(TestCase): url = reverse('drafts_view', kwargs={'id':drafts[0].name}) response = self.client.get(url, REMOTE_USER=SECR_USER) self.assertEquals(response.status_code, 200) -""" \ No newline at end of file +""" diff --git a/ietf/secr/ipradmin/views.py b/ietf/secr/ipradmin/views.py index 64c253442..1f6334309 100644 --- a/ietf/secr/ipradmin/views.py +++ b/ietf/secr/ipradmin/views.py @@ -15,7 +15,7 @@ from ietf.secr.ipradmin.forms import IprDetailForm, IPRContactFormset from ietf.secr.utils.document import get_rfc_num, is_draft import ietf.settings as settings -from ietf.ipr.models import IprDetail, IprUpdate, IprRfc, IprDraft, IprContact, LICENSE_CHOICES, STDONLY_CHOICES, IprNotification +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 @@ -145,15 +145,7 @@ def admin_notify(request, ipr_id): submitter_text = get_submitter_text(ipr_id, updated_ipr_id, from_page) document_relatives = '' - #drafts = IprDraft.objects.filter(ipr__ipr_id=ipr_id) - #for draft in drafts: - # document_relatives += get_document_relatives(ipr_id, draft, is_draft=1) - - #rfcs = IprRfc.objects.filter(ipr__ipr_id=ipr_id) - #for rfc in rfcs: - # document_relatives += get_document_relatives(ipr_id, rfc, is_draft=0) - # REDESIGN - for iprdocalias in ipr_dtl.documents.all(): + for iprdocalias in ipr_dtl.docs(): document_relatives += get_document_relatives(ipr_dtl, iprdocalias.doc_alias) return dict( @@ -528,8 +520,8 @@ def admin_detail(request, ipr_id): # conversion #rfcs = ipr_dtl.rfcs.all() #drafts = ipr_dtl.drafts.all() - rfcs = ipr_dtl.documents.filter(doc_alias__name__startswith='rfc') - drafts = ipr_dtl.documents.exclude(doc_alias__name__startswith='rfc') + 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: diff --git a/ietf/secr/meetings/tests.py b/ietf/secr/meetings/tests.py index e0995c318..af7dfd095 100644 --- a/ietf/secr/meetings/tests.py +++ b/ietf/secr/meetings/tests.py @@ -9,9 +9,6 @@ from pyquery import PyQuery SECR_USER='secretary' class MainTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] - def test_main(self): "Main Test" url = reverse('meetings') diff --git a/ietf/secr/middleware/secauth.py b/ietf/secr/middleware/secauth.py index 327080284..99c3ca836 100644 --- a/ietf/secr/middleware/secauth.py +++ b/ietf/secr/middleware/secauth.py @@ -2,7 +2,7 @@ from django.conf import settings from django.http import HttpResponseForbidden from django.shortcuts import render_to_response -from ietf.ietfauth.decorators import has_role +from ietf.ietfauth.utils import has_role import re diff --git a/ietf/secr/proceedings/proc_utils.py b/ietf/secr/proceedings/proc_utils.py index ea2e69e2c..cd47e52bc 100644 --- a/ietf/secr/proceedings/proc_utils.py +++ b/ietf/secr/proceedings/proc_utils.py @@ -8,7 +8,6 @@ from django.shortcuts import render_to_response from ietf.group.models import Group, Role from ietf.group.utils import get_charter_text from ietf.meeting.models import Session, TimeSlot, Meeting -from ietf.meeting.views import agenda_info from ietf.doc.models import Document, RelatedDocument, DocEvent from itertools import chain from ietf.secr.proceedings.models import Registration @@ -374,7 +373,6 @@ def gen_acknowledgement(context): def gen_agenda(context): meeting = context['meeting'] - #timeslots, update, meeting, venue, ads, plenaryw_agenda, plenaryt_agenda = agenda_info(meeting.number) timeslots = TimeSlot.objects.filter(meeting=meeting) # sort by area:group then time diff --git a/ietf/secr/proceedings/tests.py b/ietf/secr/proceedings/tests.py index 2b50c9c64..f62f6daef 100644 --- a/ietf/secr/proceedings/tests.py +++ b/ietf/secr/proceedings/tests.py @@ -10,9 +10,6 @@ import debug SECR_USER='secretary' class MainTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] - def test_main(self): "Main Test" make_test_data() diff --git a/ietf/secr/proceedings/views.py b/ietf/secr/proceedings/views.py index b927de710..3bb04c945 100644 --- a/ietf/secr/proceedings/views.py +++ b/ietf/secr/proceedings/views.py @@ -24,9 +24,8 @@ from ietf.secr.utils.meeting import get_upload_root, get_proceedings_path, get_m from ietf.doc.models import Document, DocAlias, DocEvent, State, NewRevisionDocEvent, RelatedDocument from ietf.group.models import Group -from ietf.group.proxy import IETFWG from ietf.group.utils import get_charter_text -from ietf.ietfauth.decorators import has_role +from ietf.ietfauth.utils import has_role from ietf.meeting.models import Meeting, Session, TimeSlot, ScheduledSession from ietf.name.models import MeetingTypeName, SessionStatusName from ietf.person.models import Person diff --git a/ietf/secr/roles/tests.py b/ietf/secr/roles/tests.py index 8e49494a2..bb2272212 100644 --- a/ietf/secr/roles/tests.py +++ b/ietf/secr/roles/tests.py @@ -11,13 +11,13 @@ import debug SECR_USER='secretary' def augment_data(): - # need this for the RoleForm intialization - Group.objects.create(acronym='dummy',name='Dummy Group',type_id='sdo') + # need this for the RoleForm intialization + Group.objects.create(acronym='dummy',name='Dummy Group',type_id='sdo') class MainTestCase(TestCase): # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names', 'persons', 'groupgroup'] - + perma_fixtures = ['persons', 'groupgroup'] + def test_main(self): "Main Test" augment_data() diff --git a/ietf/secr/rolodex/tests.py b/ietf/secr/rolodex/tests.py index fa6298bfc..61a632c82 100644 --- a/ietf/secr/rolodex/tests.py +++ b/ietf/secr/rolodex/tests.py @@ -9,9 +9,6 @@ from pyquery import PyQuery SECR_USER='secretary' class MainTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] - def test_main(self): "Main Test" url = reverse('rolodex') diff --git a/ietf/secr/sreq/tests.py b/ietf/secr/sreq/tests.py index 0854ee55a..9dc6b4a46 100644 --- a/ietf/secr/sreq/tests.py +++ b/ietf/secr/sreq/tests.py @@ -1,28 +1,30 @@ -import unittest from django.conf import settings from django.contrib.auth.models import User from django.core.urlresolvers import reverse -from ietf.utils import TestCase -from django.test.client import Client -from ietf.group.models import Group -from ietf.ietfauth.decorators import has_role -from ietf.utils.test_data import make_test_data -from ietf.utils.test_utils import SimpleUrlTestCase, RealDatabaseTest -from ietf.idtracker.models import Role -from urlparse import urlsplit +from ietf.utils import TestCase +from ietf.group.models import Group +from ietf.ietfauth.utils import has_role +from ietf.utils.test_data import make_test_data + #from pyquery import PyQuery SECR_USER='secretary' -class SreqUrlTestCase(SimpleUrlTestCase): - def testUrls(self): - self.doTestUrls(__file__) +class SreqUrlTests(TestCase): + def test_urls(self): + draft = make_test_data() + + r = self.client.get("/secr/") + self.assertEqual(r.status_code, 200) + + r = self.client.get("/secr/sreq/") + self.assertEqual(r.status_code, 200) + + r = self.client.get("/secr/sreq/%s/new/" % draft.group.acronym) + self.assertEqual(r.status_code, 200) class MainTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] - def test_main(self): draft = make_test_data() url = reverse('sessions') @@ -34,8 +36,6 @@ class MainTestCase(TestCase): self.failUnless(len(unsched) > 0) class SubmitRequestCase(TestCase): - perma_fixtures = ['names'] - def test_submit_request(self): draft = make_test_data() acronym = Group.objects.all()[0].acronym @@ -71,4 +71,4 @@ class RetrievePreviousCase(TestCase): # test error if already scheduled # test get previous exists/doesn't exist # test that groups scheduled and unscheduled add up to total groups - # test locking function, access by unauthorized \ No newline at end of file + # test locking function, access by unauthorized diff --git a/ietf/secr/sreq/testurl.list b/ietf/secr/sreq/testurl.list deleted file mode 100644 index 5ae678bdd..000000000 --- a/ietf/secr/sreq/testurl.list +++ /dev/null @@ -1,3 +0,0 @@ -200 /secr/ -200 /secr/sreq/ -200 /secr/sreq/6lowpan/new/ diff --git a/ietf/secr/sreq/views.py b/ietf/secr/sreq/views.py index 7deb6daee..9e2369fba 100644 --- a/ietf/secr/sreq/views.py +++ b/ietf/secr/sreq/views.py @@ -11,7 +11,7 @@ from ietf.secr.utils.mail import get_ad_email_list, get_chair_email_list, get_cc from ietf.secr.utils.decorators import check_permissions, sec_only from ietf.secr.utils.group import get_my_groups, groups_by_session -from ietf.ietfauth.decorators import has_role +from ietf.ietfauth.utils import has_role from ietf.utils.mail import send_mail from ietf.meeting.models import Meeting, Session, Constraint diff --git a/ietf/secr/telechat/tests.py b/ietf/secr/telechat/tests.py index c2a0b03c4..887e4f16f 100644 --- a/ietf/secr/telechat/tests.py +++ b/ietf/secr/telechat/tests.py @@ -1,7 +1,7 @@ from django.core.urlresolvers import reverse from ietf.utils import TestCase -from ietf.iesg.models import TelechatDate, TelechatAgendaItem, WGAction +from ietf.iesg.models import TelechatDate, TelechatAgendaItem from ietf.person.models import Person from ietf.utils.test_data import make_test_data @@ -15,9 +15,6 @@ def augment_data(): TelechatDate.objects.create(date=datetime.datetime.today()) class MainTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] - def test_main(self): "Main Test" augment_data() diff --git a/ietf/secr/telechat/views.py b/ietf/secr/telechat/views.py index 05d4e79bc..f76dd1c6c 100644 --- a/ietf/secr/telechat/views.py +++ b/ietf/secr/telechat/views.py @@ -8,15 +8,14 @@ from django.shortcuts import render_to_response, get_object_or_404 from django.template import RequestContext from ietf.doc.models import DocEvent, Document, BallotDocEvent, BallotPositionDocEvent, TelechatDocEvent, WriteupDocEvent, save_document_in_history -from ietf.doc.proxy import InternetDraft from ietf.doc.utils import get_document_content, log_state_changed from ietf.group.models import Group from ietf.name.models import BallotPositionName from ietf.person.models import Person from ietf.doc.lastcall import request_last_call from ietf.doc.mails import email_ad, email_state_changed -from ietf.iesg.models import TelechatDate, TelechatAgendaItem, WGAction -from ietf.iesg.views import _agenda_data +from ietf.iesg.models import TelechatDate, TelechatAgendaItem +from ietf.iesg.agenda import agenda_data, get_doc_section from forms import * import os @@ -25,8 +24,6 @@ import datetime ''' EXPECTED CHANGES: x group pages will be just another doc, charter doc -x charter docs to discuss will be passed in the 'docs' section of agenda -x expand get_section_header to include section 4 x consolidate views (get rid of get_group_header,group,group_navigate) ''' @@ -38,9 +35,7 @@ active_ballot_positions: takes one argument, doc. returns a dictionary with a k NOTE: this function has been deprecated as of Datatracker 4.34. Should now use methods on the Document. For example: doc.active_ballot().active_ad_positions() -_agenda_data: takes a request object and a date string in the format YYYY-MM-DD. - - 2012-07-28 this function was changed to return Document objects instead - of old InternetDraft wrappers +agenda_data: takes a date string in the format YYYY-MM-DD. ''' # ------------------------------------------------- @@ -52,10 +47,11 @@ def get_doc_list(agenda): Document objects in the order they appear in the agenda sections 1-3. ''' docs = [] - for key in sorted(agenda['docs']): - docs.extend(agenda['docs'][key]) + for num, section in sorted(agenda['sections'].iteritems()): + if "docs" in section: + docs.extend(section["docs"]) - return [x['obj'] for x in docs] + return docs def get_doc_writeup(doc): ''' @@ -87,44 +83,29 @@ def get_next_telechat_date(): ''' return TelechatDate.objects.filter(date__gte=datetime.date.today()).order_by('date')[0].date -def get_section_header(file,agenda): +def get_section_header(doc, agenda): ''' This function takes a filename and an agenda dictionary and returns the - agenda section header as a string for use in the doc template + agenda section header as a list for use in the doc template ''' - h1 = {'2':'Protocol Actions','3':'Document Actions','4':'Working Group Actions'} - h2a = {'1':'WG Submissions','2':'Individual Submissions','3':'Status Changes'} - h2b = {'1':'WG Submissions','2':'Individual Submissions via AD','3':'Status Changes','4':'IRTF and Independent Submission Stream Documents'} - h2c = {'1':'WG Creation','2':'WG Chartering'} - h3a = {'1':'New Item','2':'Returning Item','3':'For Action'} - h3b = {'1':'Proposed for IETF Review','2':'Proposed for Approval'} - h3c = {'1':'Under Evaluation for IETF Review','2':'Proposed for Approval'} + num = get_doc_section(doc) - # Robert updated _agenda_data to return Document objects instead of the ID wrapper - #doc = InternetDraft.objects.get(filename=file) - doc = Document.objects.get(name=file) + header = [] - test = {'obj':doc} - for k,v in agenda['docs'].iteritems(): - if test in v: - section = k - count = '%s of %s' % (v.index(test) + 1, len(v)) - break + split = num.split(".") - header = [ '%s %s' % (section[1], h1[section[1]]) ] - if section[1] == '2': - header.append('%s.%s %s' % (section[1], section[2], h2a[section[2]])) - elif section[1] == '4': - header.append('%s.%s %s' % (section[1], section[2], h2c[section[2]])) - else: - header.append('%s.%s %s' % (section[1], section[2], h2b[section[2]])) - if section[1] == '4': - if section[2] == '1': - header.append('%s.%s.%s %s' % (section[1], section[2], section[3], h3b[section[3]])) - elif section[2] == '2': - header.append('%s.%s.%s %s' % (section[1], section[2], section[3], h3c[section[3]])) - else: - header.append('%s.%s.%s %s' % (section[1], section[2], section[3], h3a[section[3]])) + for i in xrange(num.count(".")): + parent_num = ".".join(split[:i + 1]) + parent = agenda["sections"].get(parent_num) + if parent: + if "." not in parent_num: + parent_num += "." + header.append(u"%s %s" % (parent_num, parent["title"])) + + section = agenda["sections"][num] + header.append(u"%s %s" % (num, section["title"])) + + count = '%s of %s' % (section["docs"].index(doc) + 1, len(section["docs"])) header.append(count) return header @@ -133,9 +114,9 @@ def get_first_doc(agenda): ''' This function takes an agenda dictionary and returns the first document in the agenda ''' - for k,v in sorted(agenda['docs'].iteritems()): - if v: - return v[0]['obj'] + for num, section in sorted(agenda['sections'].iteritems()): + if "docs" in section and section["docs"]: + return section["docs"][0] return None @@ -144,7 +125,7 @@ def get_first_doc(agenda): # ------------------------------------------------- def bash(request, date): - agenda = _agenda_data(request, date=date) + agenda = agenda_data(date=date) return render_to_response('telechat/bash.html', { 'agenda': agenda, @@ -158,7 +139,7 @@ def doc(request, date): displays the message "No Documents" ''' - agenda = _agenda_data(request, date=date) + agenda = agenda_data(date=date) doc = get_first_doc(agenda) if doc: url = reverse('telechat_doc_detail', kwargs={'date':date,'name':doc.name}) @@ -212,8 +193,8 @@ def doc_detail(request, date, name): 'substate':tag} BallotFormset = formset_factory(BallotForm, extra=0) - agenda = _agenda_data(request, date=date) - header = get_section_header(name,agenda) if name else '' + agenda = agenda_data(date=date) + header = get_section_header(doc, agenda) # nav button logic doc_list = get_doc_list(agenda) @@ -226,7 +207,7 @@ def doc_detail(request, date, name): if request.method == 'POST': button_text = request.POST.get('submit', '') - # logic from doc/views_ballot.py EditPositionRedesign + # logic from doc/views_ballot.py EditPosition if button_text == 'update_ballot': formset = BallotFormset(request.POST, initial=initial_ballot) state_form = ChangeStateForm(initial=initial_state) @@ -329,7 +310,7 @@ def doc_navigate(request, date, name, nav): The view retrieves the appropriate document and redirects to the doc view. ''' doc = get_object_or_404(Document, docalias__name=name) - agenda = _agenda_data(request, date=date) + agenda = agenda_data(date=date) target = name docs = get_doc_list(agenda) @@ -346,10 +327,6 @@ def doc_navigate(request, date, name, nav): def main(request): ''' The is the main view where the user selects an existing telechat or creates a new one. - - NOTES ON EXTERNAL HELPER FUNCTIONS: - _agenda_data(): returns dictionary of agenda sections - get_ballot(name): returns a BallotWrapper and RfcWrapper or IdWrapper ''' if request.method == 'POST': date=request.POST['date'] @@ -371,7 +348,7 @@ def management(request, date): This view displays management issues and lets the user update the status ''' - agenda = _agenda_data(request, date=date) + agenda = agenda_data(date=date) issues = TelechatAgendaItem.objects.filter(type=3).order_by('id') return render_to_response('telechat/management.html', { @@ -386,17 +363,18 @@ def minutes(request, date): This view shows a list of documents that were approved since the last telechat ''' # get the telechat previous to selected one - dates = [ t.date for t in TelechatDate.objects.all() ] y,m,d = date.split('-') current = datetime.date(int(y),int(m),int(d)) - index = dates.index(current) - previous = dates[index + 1] + + previous = TelechatDate.objects.filter(date__lt=current).order_by("-date")[0].date events = DocEvent.objects.filter(type='iesg_approved',time__gte=previous,time__lt=current,doc__type='draft') docs = [ e.doc for e in events ] pa_docs = [ d for d in docs if d.intended_std_level.slug not in ('inf','exp','hist') ] da_docs = [ d for d in docs if d.intended_std_level.slug in ('inf','exp','hist') ] - agenda = _agenda_data(request, date=date) + agenda = agenda_data(date=date) + + # FIXME: this doesn't show other documents return render_to_response('telechat/minutes.html', { 'agenda': agenda, @@ -422,8 +400,8 @@ def new(request): def roll_call(request, date): - agenda = _agenda_data(request, date=date) - ads = Person.objects.filter(role__name='ad') + agenda = agenda_data(date=date) + ads = Person.objects.filter(role__name='ad', role__group__state="active") sorted_ads = sorted(ads, key = lambda a: a.name_parts()[3]) return render_to_response('telechat/roll_call.html', { diff --git a/ietf/secr/templates/telechat/agenda_outline_23.html b/ietf/secr/templates/telechat/agenda_outline_23.html deleted file mode 100644 index a3fc9c8d0..000000000 --- a/ietf/secr/templates/telechat/agenda_outline_23.html +++ /dev/null @@ -1,142 +0,0 @@ -{% comment %} -Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). -All rights reserved. Contact: Pasi Eronen - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * Neither the name of the Nokia Corporation and/or its - subsidiary(-ies) nor the names of its contributors may be used - to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -{% endcomment %} -{% with "2. Protocol Actions" as title1 %}{% with 1 as title1_first %} -{% with "2.1 WG Submissions" as title2 %} -{% with 1 as title2_first %} - -{% with "2.1.1 New Items" as title3 %} -{% with docs.s211 as section_docs %}{% include doc_template %}{% endwith %} -{% endwith %} -{% endwith %}{# title2_first #} - -{% with "2.1.2 Returning Items" as title3 %} -{% with docs.s212 as section_docs %}{% include doc_template %}{% endwith %} -{% endwith %} - -{% if docs.s213 %} -{% with "2.1.3 For Action" as title3 %} -{% with docs.s213 as section_docs %}{% include doc_template %}{% endwith %} -{% endwith %} -{% endif %} - -{% endwith %}{# title2 #} -{% endwith %}{# title1_first #} - -{% with "2.2 Individual Submissions" as title2 %} -{% with 1 as title2_first %} - -{% with "2.2.1 New Items" as title3 %} -{% with docs.s221 as section_docs %}{% include doc_template %}{% endwith %} -{% endwith %} -{% endwith %}{# title2_first #} - -{% with "2.2.2 Returning Items" as title3 %} -{% with docs.s222 as section_docs %}{% include doc_template %}{% endwith %} -{% endwith %} - -{% if docs.s223 %} -{% with "2.2.3 For Action" as title3 %} -{% with docs.s223 as section_docs %}{% include doc_template %}{% endwith %} -{% endwith %} -{% endif %} - -{% endwith %}{# title2 #} - -{% endwith %}{# title1 #} - -{% with "3. Document Actions" as title1 %}{% with 1 as title1_first %} - -{% with "3.1 WG Submissions" as title2 %} -{% with 1 as title2_first %} - -{% with "3.1.1 New Items" as title3 %} -{% with docs.s311 as section_docs %}{% include doc_template %}{% endwith %} -{% endwith %} -{% endwith %}{# title2_first #} - -{% with "3.1.2 Returning Items" as title3 %} -{% with docs.s312 as section_docs %}{% include doc_template %}{% endwith %} -{% endwith %} - -{% if docs.s313 %} -{% with "3.1.3 For Action" as title3 %} -{% with docs.s313 as section_docs %}{% include doc_template %}{% endwith %} -{% endwith %} -{% endif %} - -{% endwith %}{# title2 #} - -{% endwith %}{# title1_first #} - -{% with "3.2 Individual Submissions Via AD" as title2 %} -{% with 1 as title2_first %} - -{% with "3.2.1 New Items" as title3 %} -{% with docs.s321 as section_docs %}{% include doc_template %}{% endwith %} -{% endwith %} -{% endwith %}{# title2_first #} - -{% with "3.2.2 Returning Items" as title3 %} -{% with docs.s322 as section_docs %}{% include doc_template %}{% endwith %} -{% endwith %} - -{% if docs.s323 %} -{% with "3.2.3 For Action" as title3 %} -{% with docs.s323 as section_docs %}{% include doc_template %}{% endwith %} -{% endwith %} -{% endif %} - -{% endwith %}{# title2 #} - -{% with "3.3 IRTF and Independent Submission Stream Documents" as title2 %} -{% with 1 as title2_first %} - -{% with "3.3.1 New Items" as title3 %} -{% with docs.s331 as section_docs %}{% include doc_template %}{% endwith %} -{% endwith %} -{% endwith %}{# title2_first #} - -{% with "3.3.2 Returning Items" as title3 %} -{% with docs.s332 as section_docs %}{% include doc_template %}{% endwith %} -{% endwith %} - -{% if docs.s333 %} -{% with "3.3.3 For Action" as title3 %} -{% with docs.s333 as section_docs %}{% include doc_template %}{% endwith %} -{% endwith %} -{% endif %} - -{% endwith %}{# title2 #} - -{% endwith %} diff --git a/ietf/secr/templates/telechat/base_telechat.html b/ietf/secr/templates/telechat/base_telechat.html index cecad39b8..a972b3e5f 100644 --- a/ietf/secr/templates/telechat/base_telechat.html +++ b/ietf/secr/templates/telechat/base_telechat.html @@ -12,77 +12,30 @@ {% endblock %} {% block content %} - +{% load ietf_filters %}

      Agenda {{ date }}

      {% if agenda %}
        -
      • 2 Protocol Actions
      • -
      • 2.1 WG Submissions
      • -
      • 2.1.1 New Item
      • - {% with agenda.docs.s211 as section_docs %}{% include "telechat/doc_template.html" %}{% endwith %} -
      • 2.1.2 Returning Item
      • - {% with agenda.docs.s212 as section_docs %}{% include "telechat/doc_template.html" %}{% endwith %} -
      • 2.1.3 For Action
      • - {% with agenda.docs.s213 as section_docs %}{% include "telechat/doc_template.html" %}{% endwith %} -
      • -
      • 2.2 Individual Submissions
      • -
      • 2.2.1 New Item
      • - {% with agenda.docs.s221 as section_docs %}{% include "telechat/doc_template.html" %}{% endwith %} -
      • 2.2.2 Returning Item
      • - {% with agenda.docs.s222 as section_docs %}{% include "telechat/doc_template.html" %}{% endwith %} -
      • 2.2.3 For Action
      • - {% with agenda.docs.s223 as section_docs %}{% include "telechat/doc_template.html" %}{% endwith %} -
      • -
      • 2.3 Status Changes
      • -
      • 2.3.1 New Item
      • - {% with agenda.docs.s231 as section_docs %}{% include "telechat/doc_template.html" %}{% endwith %} -
      • 2.3.2 Returning Item
      • - {% with agenda.docs.232 as section_docs %}{% include "telechat/doc_template.html" %}{% endwith %} -
      • -
      • 3 Document Actions
      • -
      • 3.1 WG Submissions
      • -
      • 3.1.1 New Item
      • - {% with agenda.docs.s311 as section_docs %}{% include "telechat/doc_template.html" %}{% endwith %} -
      • 3.1.2 Returning Item
      • - {% with agenda.docs.s312 as section_docs %}{% include "telechat/doc_template.html" %}{% endwith %} -
      • 3.1.3 For Action
      • - {% with agenda.docs.s313 as section_docs %}{% include "telechat/doc_template.html" %}{% endwith %} -
      • -
      • 3.2 Individual Submissions via AD
      • -
      • 3.2.1 New Item
      • - {% with agenda.docs.s321 as section_docs %}{% include "telechat/doc_template.html" %}{% endwith %} -
      • 3.2.2 Returning Item
      • - {% with agenda.docs.s322 as section_docs %}{% include "telechat/doc_template.html" %}{% endwith %} -
      • 3.2.3 For Action
      • - {% with agenda.docs.s323 as section_docs %}{% include "telechat/doc_template.html" %}{% endwith %} -
      • -
      • 3.3 Status Changes
      • -
      • 3.3.1 New Item
      • - {% with agenda.docs.s331 as section_docs %}{% include "telechat/doc_template.html" %}{% endwith %} -
      • 3.3.2 Returning Item
      • - {% with agenda.docs.s332 as section_docs %}{% include "telechat/doc_template.html" %}{% endwith %} -
      • -
      • 3.4 Independent Submissions via RFC Editor
      • -
      • 3.4.1 New Item
      • - {% with agenda.docs.s341 as section_docs %}{% include "telechat/doc_template.html" %}{% endwith %} -
      • 3.4.2 Returning Item
      • - {% with agenda.docs.s342 as section_docs %}{% include "telechat/doc_template.html" %}{% endwith %} -
      • 3.4.3 For Action
      • - {% with agenda.docs.s343 as section_docs %}{% include "telechat/doc_template.html" %}{% endwith %} -
      • -
      • 4 Working Group Actions
      • -
      • 4.1 WG Creation
      • -
      • 4.1.1 Proposed for IETF Review
      • - {% with agenda.docs.s411 as section_docs %}{% include "telechat/doc_template.html" %}{% endwith %} -
      • 4.1.2 Proposed for Approval
      • - {% with agenda.docs.s412 as section_docs %}{% include "telechat/doc_template.html" %}{% endwith %} -
      • -
      • 4.2 WG Rechartering
      • -
      • 4.2.1 Under evaluation for IETF Review
      • - {% with agenda.docs.s421 as section_docs %}{% include "telechat/doc_template.html" %}{% endwith %} -
      • 4.2.2 Proposed for Approval
      • - {% with agenda.docs.s422 as section_docs %}{% include "telechat/doc_template.html" %}{% endwith %} + {% for num, section in agenda.sections.iteritems %} + {% if num >= "2" and num < "5" %} +
      • {{ num }} {{ section.title }} + + {% if "docs" in section %} + {% if section.docs %} + + {% else %} +
        None
        + {% endif %} +
      • + {% endif %} + + {% endif %} + {% endfor %}
      {% else %} Please select a telechat to display the agenda. diff --git a/ietf/secr/templates/telechat/doc.html b/ietf/secr/templates/telechat/doc.html index a26d39fd7..793bf308f 100644 --- a/ietf/secr/templates/telechat/doc.html +++ b/ietf/secr/templates/telechat/doc.html @@ -7,8 +7,8 @@ {% block subsection %}
      {% if document %} - {% if not nav_start %}<< Previous{% endif %} - {% if not nav_end %}Next >>{% endif %} + {% if not nav_start %}« Previous{% endif %} + {% if not nav_end %}Next »{% endif %}

      {% for line in header %} @@ -64,7 +64,7 @@

      Ballot Writeup

      -    {{ writeup }}
      +{{ writeup }}
           
      diff --git a/ietf/secr/templates/telechat/doc_template.html b/ietf/secr/templates/telechat/doc_template.html index 700a717c1..acb165d5a 100644 --- a/ietf/secr/templates/telechat/doc_template.html +++ b/ietf/secr/templates/telechat/doc_template.html @@ -1,7 +1,7 @@ {% if section_docs %} {% else %} diff --git a/ietf/secr/utils/decorators.py b/ietf/secr/utils/decorators.py index 168af6efe..0cd7214ef 100644 --- a/ietf/secr/utils/decorators.py +++ b/ietf/secr/utils/decorators.py @@ -3,7 +3,7 @@ from django.http import HttpResponseRedirect from django.shortcuts import render_to_response, get_object_or_404 from functools import wraps -from ietf.ietfauth.decorators import has_role +from ietf.ietfauth.utils import has_role from ietf.doc.models import Document from ietf.group.models import Group from ietf.meeting.models import Session diff --git a/ietf/secr/utils/document.py b/ietf/secr/utils/document.py index 1f61d182b..b1a8e32ca 100644 --- a/ietf/secr/utils/document.py +++ b/ietf/secr/utils/document.py @@ -24,6 +24,6 @@ def get_start_date(doc): This function takes a document object and returns the date of the first new revision doc event ''' - # based on ietf.doc.proxy + # originally based on doc shim layer event = doc.docevent_set.filter(type='new_revision').order_by('time') - return event[0].time.date() if event else None \ No newline at end of file + return event[0].time.date() if event else None diff --git a/ietf/secr/utils/group.py b/ietf/secr/utils/group.py index 0dcf57d2a..ed2771b17 100644 --- a/ietf/secr/utils/group.py +++ b/ietf/secr/utils/group.py @@ -2,7 +2,7 @@ from django.conf import settings from ietf.group.models import Group from ietf.meeting.models import Session -from ietf.ietfauth.decorators import has_role +from ietf.ietfauth.utils import has_role import itertools import os diff --git a/ietf/settings.py b/ietf/settings.py index a5c6bc8ca..41a540a73 100644 --- a/ietf/settings.py +++ b/ietf/settings.py @@ -18,7 +18,6 @@ LOG_DIR = '/var/log/datatracker' import sys sys.path.append(os.path.abspath(BASE_DIR + "/..")) -sys.path.append(os.path.abspath(BASE_DIR + "/../redesign")) DEBUG = True TEMPLATE_DEBUG = DEBUG @@ -161,16 +160,12 @@ INSTALLED_APPS = ( 'django.contrib.humanize', 'django.contrib.messages', 'south', - 'workflows', - 'permissions', 'ietf.person', 'ietf.name', 'ietf.group', 'ietf.doc', 'ietf.message', - 'ietf.announcements', 'ietf.idindex', - 'ietf.idtracker', 'ietf.ietfauth', 'ietf.iesg', 'ietf.ipr', @@ -178,13 +173,9 @@ INSTALLED_APPS = ( 'ietf.mailinglists', 'ietf.meeting', 'ietf.utils', - #'ietf.proceedings', 'ietf.redirects', - 'ietf.idrfc', 'ietf.wginfo', 'ietf.submit', - 'ietf.ietfworkflows', - 'ietf.wgchairs', 'ietf.wgcharter', 'ietf.sync', 'ietf.community', @@ -314,12 +305,6 @@ LIAISON_UNIVERSAL_FROM = 'Liaison Statement Management Tool %s' % (url, instance.status) + url = urlreverse('submit_submission_status_by_hash', + kwargs=dict(submission_id=instance.pk, + access_token=instance.access_token())) + return '%s' % (url, instance.state) status_link.allow_tags = True -admin.site.register(IdSubmissionDetail, IdSubmissionDetailAdmin) + def draft_link(self, instance): + if instance.state_id == "posted": + return '%s' % (instance.name, instance.rev, instance.name) + else: + return instance.name + draft_link.allow_tags = True + +admin.site.register(Submission, SubmissionAdmin) class PreapprovalAdmin(admin.ModelAdmin): pass admin.site.register(Preapproval, PreapprovalAdmin) -class TempIdAuthorsAdmin(admin.ModelAdmin): - ordering = ["-id"] -admin.site.register(TempIdAuthors, TempIdAuthorsAdmin) - diff --git a/ietf/submit/error_manager.py b/ietf/submit/error_manager.py deleted file mode 100644 index b4dcefd8f..000000000 --- a/ietf/submit/error_manager.py +++ /dev/null @@ -1,19 +0,0 @@ -from ietf.submit.models import IdSubmissionStatus - -class ErrorManager(object): - ERROR_CODES = { - 'DEFAULT': 'Unknow error', - 'INVALID_FILENAME': 111, - 'EXCEEDED_SIZE': 102, - } - - def get_error_str(self, key): - error_code = self.ERROR_CODES.get(key, self.ERROR_CODES['DEFAULT']) - if isinstance(error_code, basestring): - return '%s (%s)' % (key, error_code) - try: - return IdSubmissionStatus.objects.get(status_id=error_code).status_value - except IdSubmissionStatus.DoesNotExist: - return '%s (%s)' % (self.ERROR_CODES['DEFAULT'], key) - -MainErrorManager=ErrorManager() diff --git a/ietf/submit/fixtures/idsubmissionstatus.xml b/ietf/submit/fixtures/idsubmissionstatus.xml deleted file mode 100644 index 280d52693..000000000 --- a/ietf/submit/fixtures/idsubmissionstatus.xml +++ /dev/null @@ -1,102 +0,0 @@ - - - - Cancelled - - - Dead - - - Posted by the Secretariat - - - Posted - - - Ready To Post - - - Uploaded - - - ID NITS Passed - - - Initial Version Approval Required - - - Submitter Authentication Required - - - Manual Post Requested - - - External Meta-Data Required - - - Internal Database Has Been Updated - - - ID Announcement Scheduled - - - ID Tracker Notification Scheduled - - - Initial Version Approval Requested - - - Error - Plain text version does not exist - - - File size is larger than 20 MB - - - Duplicate Internet-Draft submission is currently in process. - - - Error - Simultaneous submission from the same IP address - - - Error - Auth key does not match - - - Error - No such Internet-Draft is currently in process - - - Error - Draft is not in an appropriate status for the requested page - - - Error - Unknown Request - - - Error - Invalid Email Address - - - Error - Direct Access is prohibited - - - Error - Invalid version number - - - Error - Invalid filename - - - Error - The document failed idnits verification - - - Creation Date must be within 3 days of the submission date. - - - Error – Not a valid submitter - - - Incorrect Meta-Data - - - The document does not contain a legitimate filename that start with draft-*. - - - Initial Version Approved - - \ No newline at end of file diff --git a/ietf/submit/forms.py b/ietf/submit/forms.py index 1aecf5d35..5aaff363e 100644 --- a/ietf/submit/forms.py +++ b/ietf/submit/forms.py @@ -1,60 +1,47 @@ -import hashlib -import random import os -import subprocess import datetime from django import forms -from django.core.validators import email_re +from django.forms.formsets import formset_factory from django.conf import settings -from django.contrib.sites.models import Site -from django.template.loader import render_to_string from django.utils.html import mark_safe from django.core.urlresolvers import reverse as urlreverse import debug -from ietf.group.models import Group -from ietf.idtracker.models import InternetDraft, IETFWG -from ietf.proceedings.models import Meeting -from ietf.submit.models import IdSubmissionDetail, TempIdAuthors, Preapproval -from ietf.submit.utils import MANUAL_POST_REQUESTED, NONE_WG, UPLOADED, AWAITING_AUTHENTICATION, POSTED, POSTED_BY_SECRETARIAT +from ietf.group.models import Group, Role +from ietf.doc.models import Document +from ietf.meeting.models import Meeting +from ietf.submit.models import Submission, Preapproval, DraftSubmissionStateName +from ietf.submit.utils import validate_submission_rev, validate_submission_document_date from ietf.submit.parsers.pdf_parser import PDFParser from ietf.submit.parsers.plain_parser import PlainParser from ietf.submit.parsers.ps_parser import PSParser from ietf.submit.parsers.xml_parser import XMLParser from ietf.utils.mail import send_mail from ietf.utils.draft import Draft -from ietf.utils.pipe import pipe -from ietf.utils.log import log class UploadForm(forms.Form): - txt = forms.FileField(label=u'.txt format', required=True) xml = forms.FileField(label=u'.xml format', required=False) pdf = forms.FileField(label=u'.pdf format', required=False) ps = forms.FileField(label=u'.ps format', required=False) - fieldsets = [('Upload a draft', ('txt', 'xml', 'pdf', 'ps'))] - - class Media: - css = {'all': ("/css/liaisons.css", )} - - def __init__(self, *args, **kwargs): - self.request=kwargs.pop('request', None) - self.remote_ip=self.request.META.get('REMOTE_ADDR', None) + def __init__(self, request, *args, **kwargs): super(UploadForm, self).__init__(*args, **kwargs) - self.in_first_cut_off = False - self.idnits_message = None - self.shutdown = False - self.draft = None - self.filesize = None - self.group = None - self.file_type = [] - self.read_dates() - def read_dates(self): + self.remote_ip = request.META.get('REMOTE_ADDR', None) + + self.in_first_cut_off = False + self.cutoff_warning = "" + self.shutdown = False + self.set_cutoff_warnings() + + self.group = None + self.parsed_draft = None + + def set_cutoff_warnings(self): now = datetime.datetime.utcnow() first_cut_off = Meeting.get_first_cut_off() second_cut_off = Meeting.get_second_cut_off() @@ -74,170 +61,104 @@ class UploadForm(forms.Form): self.cutoff_warning = 'The cut-off time for the I-D submission was %02dh UTC, %s.
      The I-D submission tool will be reopened at %02dh local time at the IETF meeting location, %s.' % (settings.CUTOFF_HOUR, second_cut_off, settings.CUTOFF_HOUR, ietf_monday) self.shutdown = True - def __unicode__(self): - return self.as_div() + def clean_file(self, field_name, parser_class): + f = self.cleaned_data[field_name] + if not f: + return f - def as_div(self): - return render_to_string('submit/submitform.html', {'form': self}) + parsed_info = parser_class(f).critical_parse() + if parsed_info.errors: + raise forms.ValidationError(parsed_info.errors) + + return f - def get_fieldsets(self): - if not self.fieldsets: - yield dict(name=None, fields=self) - else: - for fieldset, fields in self.fieldsets: - fieldset_dict = dict(name=fieldset, fields=[]) - for field_name in fields: - if field_name in self.fields.keyOrder: - fieldset_dict['fields'].append(self[field_name]) - if not fieldset_dict['fields']: - # if there is no fields in this fieldset, we continue to next fieldset - continue - yield fieldset_dict def clean_txt(self): - txt_file = self.cleaned_data['txt'] - if not txt_file: - return txt_file - parsed_info = PlainParser(txt_file).critical_parse() - if parsed_info.errors: - raise forms.ValidationError(parsed_info.errors) - self.filesize=txt_file.size - return txt_file + return self.clean_file("txt", PlainParser) def clean_pdf(self): - pdf_file = self.cleaned_data['pdf'] - if not pdf_file: - return pdf_file - parsed_info = PDFParser(pdf_file).critical_parse() - if parsed_info.errors: - raise forms.ValidationError(parsed_info.errors) - return pdf_file + return self.clean_file("pdf", PDFParser) def clean_ps(self): - ps_file = self.cleaned_data['ps'] - if not ps_file: - return ps_file - parsed_info = PSParser(ps_file).critical_parse() - if parsed_info.errors: - raise forms.ValidationError(parsed_info.errors) - return ps_file + return self.clean_file("ps", PSParser) def clean_xml(self): - xml_file = self.cleaned_data['xml'] - if not xml_file: - return xml_file - parsed_info = XMLParser(xml_file).critical_parse() - if parsed_info.errors: - raise forms.ValidationError(parsed_info.errors) - return xml_file + return self.clean_file("xml", XMLParser) def clean(self): if self.shutdown: raise forms.ValidationError('The tool is shut down') - self.check_paths() - if self.cleaned_data.get('txt', None): - self.get_draft() - self.group=self.get_working_group() - self.check_previous_submission() - if self.draft.revision == '00' and self.in_first_cut_off: + + # sanity check that paths exist (for development servers) + for s in ("IDSUBMIT_STAGING_PATH", "IDSUBMIT_IDNITS_BINARY", + "IDSUBMIT_REPOSITORY_PATH", "INTERNET_DRAFT_ARCHIVE_DIR"): + if not os.path.exists(getattr(settings, s)): + raise forms.ValidationError('%s defined in settings.py does not exist' % s) + + if self.cleaned_data.get('txt'): + # try to parse it + txt_file = self.cleaned_data['txt'] + txt_file.seek(0) + self.parsed_draft = Draft(txt_file.read(), txt_file.name) + txt_file.seek(0) + + if not self.parsed_draft.filename: + raise forms.ValidationError("Draft parser could not extract a valid draft name from the .txt file") + + # check group + self.group = self.deduce_group() + + # check existing + existing = Submission.objects.filter(name=self.parsed_draft.filename, rev=self.parsed_draft.revision).exclude(state__in=("posted", "cancel")) + if existing: + raise forms.ValidationError(mark_safe('Submission with same name and revision is currently being processed. Check the status here' % urlreverse("submit_submission_status", kwargs={ 'submission_id': existing[0].pk }))) + + # cut-off + if self.parsed_draft.revision == '00' and self.in_first_cut_off: raise forms.ValidationError(mark_safe(self.cutoff_warning)) - self.check_tresholds() + + # check thresholds + today = datetime.date.today() + + self.check_submissions_tresholds( + "for the draft %s" % self.parsed_draft.filename, + dict(name=self.parsed_draft.filename, rev=self.parsed_draft.revision, submission_date=today), + settings.IDSUBMIT_MAX_DAILY_SAME_DRAFT_NAME, settings.IDSUBMIT_MAX_DAILY_SAME_DRAFT_NAME_SIZE, + ) + self.check_submissions_tresholds( + "for the same submitter", + dict(remote_ip=self.remote_ip, submission_date=today), + settings.IDSUBMIT_MAX_DAILY_SAME_SUBMITTER, settings.IDSUBMIT_MAX_DAILY_SAME_SUBMITTER_SIZE, + ) + if self.group: + self.check_submissions_tresholds( + "for the group \"%s\"" % (self.group.acronym), + dict(group=self.group, submission_date=today), + settings.IDSUBMIT_MAX_DAILY_SAME_GROUP, settings.IDSUBMIT_MAX_DAILY_SAME_GROUP_SIZE, + ) + self.check_submissions_tresholds( + "across all submitters", + dict(submission_date=today), + settings.IDSUBMIT_MAX_DAILY_SUBMISSIONS, settings.IDSUBMIT_MAX_DAILY_SUBMISSIONS_SIZE, + ) + return super(UploadForm, self).clean() - def check_tresholds(self): - filename = self.draft.filename - revision = self.draft.revision - remote_ip = self.remote_ip - today = datetime.date.today() + def check_submissions_tresholds(self, which, filter_kwargs, max_amount, max_size): + submissions = Submission.objects.filter(**filter_kwargs) - # Same draft by name - same_name = IdSubmissionDetail.objects.filter(filename=filename, revision=revision, submission_date=today) - if same_name.count() > settings.MAX_SAME_DRAFT_NAME: - raise forms.ValidationError('The same I-D cannot be submitted more than %s times a day' % settings.MAX_SAME_DRAFT_NAME) - if sum([i.filesize for i in same_name]) > (settings.MAX_SAME_DRAFT_NAME_SIZE * 1048576): - raise forms.ValidationError('The same I-D submission cannot exceed more than %s MByte a day' % settings.MAX_SAME_DRAFT_NAME_SIZE) + if len(submissions) > max_amount: + raise forms.ValidationError("Max submissions %s has been reached for today (maximum is %s submissions)." % (which, max_amount)) + if sum(s.file_size for s in submissions) > max_size * 1024 * 1024: + raise forms.ValidationError("Max uploaded amount %s has been reached for today (maximum is %s MB)." % (which, max_size)) - # Total from same ip - same_ip = IdSubmissionDetail.objects.filter(remote_ip=remote_ip, submission_date=today) - if same_ip.count() > settings.MAX_SAME_SUBMITTER: - raise forms.ValidationError('The same submitter cannot submit more than %s I-Ds a day' % settings.MAX_SAME_SUBMITTER) - if sum([i.filesize for i in same_ip]) > (settings.MAX_SAME_SUBMITTER_SIZE * 1048576): - raise forms.ValidationError('The same submitter cannot exceed more than %s MByte a day' % settings.MAX_SAME_SUBMITTER_SIZE) - - # Total in same group - if self.group: - same_group = IdSubmissionDetail.objects.filter(group_acronym=self.group, submission_date=today) - if same_group.count() > settings.MAX_SAME_WG_DRAFT: - raise forms.ValidationError('The same working group I-Ds cannot be submitted more than %s times a day' % settings.MAX_SAME_WG_DRAFT) - if sum([i.filesize for i in same_group]) > (settings.MAX_SAME_WG_DRAFT_SIZE * 1048576): - raise forms.ValidationError('Total size of same working group I-Ds cannot exceed %s MByte a day' % settings.MAX_SAME_WG_DRAFT_SIZE) - - - # Total drafts for today - total_today = IdSubmissionDetail.objects.filter(submission_date=today) - if total_today.count() > settings.MAX_DAILY_SUBMISSION: - raise forms.ValidationError('The total number of today\'s submission has reached the maximum number of submission per day') - if sum([i.filesize for i in total_today]) > (settings.MAX_DAILY_SUBMISSION_SIZE * 1048576): - raise forms.ValidationError('The total size of today\'s submission has reached the maximum size of submission per day') - - def check_paths(self): - self.staging_path = getattr(settings, 'IDSUBMIT_STAGING_PATH', None) - self.idnits = getattr(settings, 'IDSUBMIT_IDNITS_BINARY', None) - if not self.staging_path: - raise forms.ValidationError('IDSUBMIT_STAGING_PATH not defined in settings.py') - if not os.path.exists(self.staging_path): - raise forms.ValidationError('IDSUBMIT_STAGING_PATH defined in settings.py does not exist') - if not self.idnits: - raise forms.ValidationError('IDSUBMIT_IDNITS_BINARY not defined in settings.py') - if not os.path.exists(self.idnits): - raise forms.ValidationError('IDSUBMIT_IDNITS_BINARY defined in settings.py does not exist') - - def check_previous_submission(self): - filename = self.draft.filename - revision = self.draft.revision - existing = IdSubmissionDetail.objects.filter(filename=filename, revision=revision, - status__pk__gte=0, status__pk__lt=100) - if existing: - raise forms.ValidationError(mark_safe('Duplicate Internet-Draft submission is currently in process. Check it here' % existing[0].pk)) - - def get_draft(self): - if self.draft: - return self.draft - txt_file = self.cleaned_data['txt'] - txt_file.seek(0) - self.draft = Draft(txt_file.read(), txt_file.name) - txt_file.seek(0) - return self.draft - - def save(self): - for ext in ['txt', 'pdf', 'xml', 'ps']: - fd = self.cleaned_data[ext] - if not fd: - continue - self.file_type.append('.%s' % ext) - filename = os.path.join(self.staging_path, '%s-%s.%s' % (self.draft.filename, self.draft.revision, ext)) - destination = open(filename, 'wb+') - for chunk in fd.chunks(): - destination.write(chunk) - destination.close() - self.check_idnits() - return self.save_draft_info(self.draft) - - def check_idnits(self): - filepath = os.path.join(self.staging_path, '%s-%s.txt' % (self.draft.filename, self.draft.revision)) - #p = subprocess.Popen([self.idnits, '--submitcheck', '--nitcount', filepath], stdout=subprocess.PIPE) - cmd = "%s --submitcheck --nitcount %s" % (self.idnits, filepath) - code, out, err = pipe(cmd) - if code != 0: - log("idnits error: %s:\n Error %s: %s" %(cmd, code, err)) - self.idnits_message = out - - def get_working_group(self): - name = self.draft.filename - existing_draft = InternetDraft.objects.filter(filename=name) + def deduce_group(self): + """Figure out group from name or previously submitted draft, returns None if individual.""" + name = self.parsed_draft.filename + existing_draft = Document.objects.filter(name=name, type="draft") if existing_draft: - group = existing_draft[0].group and existing_draft[0].group.ietfwg or None - if group and group.pk != NONE_WG and group.type_id != "area": + group = existing_draft[0].group + if group and group.type_id not in ("individ", "area"): return group else: return None @@ -245,328 +166,109 @@ class UploadForm(forms.Form): if name.startswith('draft-ietf-') or name.startswith("draft-irtf-"): components = name.split("-") if len(components) < 3: - raise forms.ValidationError("The draft name \"%s\" is missing a third part, please rename it") + raise forms.ValidationError(u"The draft name \"%s\" is missing a third part, please rename it" % name) if components[1] == "ietf": group_type = "wg" - else: + elif components[1] == "irtf": group_type = "rg" # first check groups with dashes for g in Group.objects.filter(acronym__contains="-", type=group_type): if name.startswith('draft-%s-%s-' % (components[1], g.acronym)): - return IETFWG().from_object(g) + return g try: - return IETFWG().from_object(Group.objects.get(acronym=components[2], type=group_type)) + return Group.objects.get(acronym=components[2], type=group_type) except Group.DoesNotExist: raise forms.ValidationError('There is no active group with acronym \'%s\', please rename your draft' % components[2]) + elif name.startswith("draft-iab-"): - return IETFWG().from_object(Group.objects.get(acronym="iab")) + return Group.objects.get(acronym="iab") + else: return None - def save_draft_info(self, draft): - document_id = 0 - existing_draft = InternetDraft.objects.filter(filename=draft.filename) - if existing_draft: - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - document_id = -1 - else: - document_id = existing_draft[0].id_document_tag - detail = IdSubmissionDetail.objects.create( - id_document_name=draft.get_title(), - filename=draft.filename, - revision=draft.revision, - txt_page_count=draft.get_pagecount(), - filesize=self.filesize, - creation_date=draft.get_creation_date(), - submission_date=datetime.date.today(), - idnits_message=self.idnits_message, - temp_id_document_tag=document_id, - group_acronym=self.group, - remote_ip=self.remote_ip, - first_two_pages=''.join(draft.pages[:2]), - status_id=UPLOADED, - abstract=draft.get_abstract(), - file_type=','.join(self.file_type), - ) - order = 0 - for author in draft.get_author_list(): - full_name, first_name, middle_initial, last_name, name_suffix, email, company = author - order += 1 - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - # save full name - TempIdAuthors.objects.create( - id_document_tag=document_id, - first_name=full_name.strip(), - email_address=(email or "").strip(), - author_order=order, - submission=detail) - else: - TempIdAuthors.objects.create( - id_document_tag=document_id, - first_name=first_name, - middle_initial=middle_initial, - last_name=last_name, - name_suffix=name_suffix, - email_address=email, - author_order=order, - submission=detail) - return detail - - -class AutoPostForm(forms.Form): - - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - name = forms.CharField(required=True) - else: - first_name = forms.CharField(label=u'Given name', required=True) - last_name = forms.CharField(label=u'Last name', required=True) - email = forms.EmailField(label=u'Email address', required=True) +class NameEmailForm(forms.Form): + """For validating supplied submitter and author information.""" + name = forms.CharField(required=True) + email = forms.EmailField(label=u'Email address') def __init__(self, *args, **kwargs): - self.draft = kwargs.pop('draft', None) - self.validation = kwargs.pop('validation', None) - self.replaces = kwargs.pop('replaces', None) - super(AutoPostForm, self).__init__(*args, **kwargs) + email_required = kwargs.pop("email_required", True) + super(NameEmailForm, self).__init__(*args, **kwargs) - def get_author_buttons(self): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - buttons = [] - for i in self.validation.authors: - buttons.append('' - % dict(name=i.get_full_name(), - email=i.email()[1] or '')) - return "".join(buttons) + self.fields["email"].required = email_required + self.fields["name"].widget.attrs["class"] = "name" + self.fields["email"].widget.attrs["class"] = "email" + def clean_name(self): + return self.cleaned_data["name"].replace("\n", "").replace("\r", "").replace("<", "").replace(">", "").strip() - # this should be moved to a Javascript file and attributes like data-first-name ... - button_template = '' + def clean_email(self): + return self.cleaned_data["email"].replace("\n", "").replace("\r", "").replace("<", "").replace(">", "").strip() - buttons = [] - for i in self.validation.authors: - full_name = u'%s. %s' % (i.first_name[0], i.last_name) - buttons.append(button_template % {'first_name': i.first_name, - 'last_name': i.last_name, - 'email': i.email()[1] or '', - 'full_name': full_name}) - return ''.join(buttons) + def cleaned_line(self): + line = self.cleaned_data["name"] + email = self.cleaned_data.get("email") + if email: + line += u" <%s>" % email + return line - def save(self, request): - self.save_submitter_info() - self.save_new_draft_info() - self.send_confirmation_mail(request) +class EditSubmissionForm(forms.ModelForm): + title = forms.CharField(required=True, max_length=255) + rev = forms.CharField(label=u'Revision', max_length=2, required=True) + document_date = forms.DateField(required=True) + pages = forms.IntegerField(required=True) + abstract = forms.CharField(widget=forms.Textarea, required=True) - def send_confirmation_mail(self, request): - subject = 'Confirmation for Auto-Post of I-D %s' % self.draft.filename - from_email = settings.IDSUBMIT_FROM_EMAIL - to_email = self.draft.confirmation_email_list() + note = forms.CharField(label=mark_safe(u'Comment to
      the Secretariat'), widget=forms.Textarea, required=False) - confirm_url = settings.IDTRACKER_BASE_URL + urlreverse('draft_confirm', kwargs=dict(submission_id=self.draft.submission_id, auth_key=self.draft.auth_key)) - status_url = settings.IDTRACKER_BASE_URL + urlreverse('draft_status_by_hash', kwargs=dict(submission_id=self.draft.submission_id, submission_hash=self.draft.get_hash())) - - send_mail(request, to_email, from_email, subject, 'submit/confirm_autopost.txt', - { 'draft': self.draft, 'confirm_url': confirm_url, 'status_url': status_url }) - - def save_submitter_info(self): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - return TempIdAuthors.objects.create( - id_document_tag=self.draft.temp_id_document_tag, - first_name=self.cleaned_data['name'], - email_address=self.cleaned_data['email'], - author_order=0, - submission=self.draft) - - return TempIdAuthors.objects.create( - id_document_tag=self.draft.temp_id_document_tag, - first_name=self.cleaned_data['first_name'], - last_name=self.cleaned_data['last_name'], - email_address=self.cleaned_data['email'], - author_order=0, - submission=self.draft) - - def save_new_draft_info(self): - salt = hashlib.sha1(str(random.random())).hexdigest()[:5] - self.draft.auth_key = hashlib.sha1(salt+self.cleaned_data['email']).hexdigest() - self.draft.status_id = AWAITING_AUTHENTICATION - self.draft.save() - - -class MetaDataForm(AutoPostForm): - - title = forms.CharField(label=u'Title', required=True) - version = forms.CharField(label=u'Version', required=True) - creation_date = forms.DateField(label=u'Creation date', required=True) - pages = forms.IntegerField(label=u'Pages', required=True) - abstract = forms.CharField(label=u'Abstract', widget=forms.Textarea, required=True) - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - name = forms.CharField(required=True) - else: - first_name = forms.CharField(label=u'Given name', required=True) - last_name = forms.CharField(label=u'Last name', required=True) - email = forms.EmailField(label=u'Email address', required=True) - comments = forms.CharField(label=u'Comments to the secretariat', widget=forms.Textarea, required=False) - - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - fields = ['title', 'version', 'creation_date', 'pages', 'abstract', 'name', 'email', 'comments'] - else: - fields = ['title', 'version', 'creation_date', 'pages', 'abstract', 'first_name', 'last_name', 'email', 'comments'] - - def __init__(self, *args, **kwargs): - super(MetaDataForm, self).__init__(*args, **kwargs) - self.set_initials() - self.authors = self.get_initial_authors() + class Meta: + model = Submission + fields = ['title', 'rev', 'document_date', 'pages', 'abstract', 'note'] def get_initial_authors(self): authors=[] if self.is_bound: for key, value in self.data.items(): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - if key.startswith('name_'): - author = {'errors': {}} - index = key.replace('name_', '') - name = value.strip() - if not name: - author['errors']['name'] = 'This field is required' - email = self.data.get('email_%s' % index, '').strip() - if email and not email_re.search(email): - author['errors']['email'] = 'Enter a valid e-mail address' - if name or email: - author.update({'get_full_name': name, - 'email': (name, email), - 'index': index, - }) - authors.append(author) - - else: - if key.startswith('first_name_'): - author = {'errors': {}} - index = key.replace('first_name_', '') - first_name = value.strip() - if not first_name: - author['errors']['first_name'] = 'This field is required' - last_name = self.data.get('last_name_%s' % index, '').strip() - if not last_name: - author['errors']['last_name'] = 'This field is required' - email = self.data.get('email_%s' % index, '').strip() - if email and not email_re.search(email): - author['errors']['email'] = 'Enter a valid e-mail address' - if first_name or last_name or email: - author.update({'first_name': first_name, - 'last_name': last_name, - 'email': ('%s %s' % (first_name, last_name), email), - 'index': index, - }) - authors.append(author) + if key.startswith('name_'): + author = {'errors': {}} + index = key.replace('name_', '') + name = value.strip() + if not name: + author['errors']['name'] = 'This field is required' + email = self.data.get('email_%s' % index, '').strip() + if email and not email_re.search(email): + author['errors']['email'] = 'Enter a valid e-mail address' + if name or email: + author.update({'name': name, + 'email': email, + 'index': index, + }) + authors.append(author) authors.sort(key=lambda x: x['index']) return authors - def set_initials(self): - self.fields['pages'].initial=self.draft.txt_page_count - self.fields['creation_date'].initial=self.draft.creation_date - self.fields['version'].initial=self.draft.revision - self.fields['abstract'].initial=self.draft.abstract - self.fields['title'].initial=self.draft.id_document_name + def clean_rev(self): + rev = self.cleaned_data["rev"] - def clean_creation_date(self): - creation_date = self.cleaned_data.get('creation_date', None) - if not creation_date: - return None - submit_date = self.draft.submission_date - if (creation_date + datetime.timedelta(days=3) < submit_date or - creation_date - datetime.timedelta(days=3) > submit_date): - raise forms.ValidationError('Creation Date must be within 3 days of submission date') - return creation_date + if len(rev) == 1: + rev = "0" + rev - def clean_version(self): - version = self.cleaned_data.get('version', None) - if not version: - return None - if len(version) > 2: - raise forms.ValidationError('Version field is not in NN format') - try: - version_int = int(version) - except ValueError: - raise forms.ValidationError('Version field is not in NN format') - if version_int > 99 or version_int < 0: - raise forms.ValidationError('Version must be set between 00 and 99') - existing_revisions = [int(i.revision_display()) for i in InternetDraft.objects.filter(filename=self.draft.filename)] - expected = 0 - if existing_revisions: - expected = max(existing_revisions) + 1 - if version_int != expected: - raise forms.ValidationError('Invalid Version Number (Version %02d is expected)' % expected) - return version + error = validate_submission_rev(self.instance.name, rev) + if error: + raise forms.ValidationError(error) - def clean(self): - if bool([i for i in self.authors if i['errors']]): - raise forms.ValidationError('Please fix errors in author list') - return super(MetaDataForm, self).clean() + return rev - def get_authors(self): - if not self.is_bound: - return self.validation.get_authors() - else: - return self.authors - - def move_docs(self, draft, revision): - old_revision = draft.revision - for ext in draft.file_type.split(','): - source = os.path.join(settings.IDSUBMIT_STAGING_PATH, '%s-%s%s' % (draft.filename, old_revision, ext)) - dest = os.path.join(settings.IDSUBMIT_STAGING_PATH, '%s-%s%s' % (draft.filename, revision, ext)) - os.rename(source, dest) - - def save_new_draft_info(self): - draft = self.draft - draft.id_document_name = self.cleaned_data['title'] - if draft.revision != self.cleaned_data['version']: - self.move_docs(draft, self.cleaned_data['version']) - draft.revision = self.cleaned_data['version'] - draft.creation_date = self.cleaned_data['creation_date'] - draft.txt_page_count = self.cleaned_data['pages'] - draft.abstract = self.cleaned_data['abstract'] - draft.comment_to_sec = self.cleaned_data['comments'] - draft.status_id = MANUAL_POST_REQUESTED - draft.save() - - # sync authors - draft.tempidauthors_set.all().delete() - - self.save_submitter_info() # submitter is author 0 - - for i, author in enumerate(self.authors): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - # save full name - TempIdAuthors.objects.create( - id_document_tag=draft.temp_id_document_tag, - first_name=author["get_full_name"], - email_address=author["email"][1], - author_order=i + 1, - submission=draft) - - def save(self, request): - self.save_new_draft_info() - self.send_mail_to_secretariat(request) - - def send_mail_to_secretariat(self, request): - subject = 'Manual Post Requested for %s' % self.draft.filename - from_email = settings.IDSUBMIT_FROM_EMAIL - to_email = settings.IDSUBMIT_TO_EMAIL - cc = [self.cleaned_data['email']] - cc += [i['email'][1] for i in self.authors] - if self.draft.group_acronym: - cc += [i.person.email()[1] for i in self.draft.group_acronym.wgchair_set.all()] - cc = list(set(cc)) - submitter = self.draft.tempidauthors_set.get(author_order=0) - send_mail(request, to_email, from_email, subject, 'submit/manual_post_mail.txt', { - 'form': self, - 'draft': self.draft, - 'url': settings.IDTRACKER_BASE_URL + urlreverse('draft_status', kwargs=dict(submission_id=self.draft.submission_id)), - 'submitter': submitter - }, - cc=cc) + def clean_document_date(self): + document_date = self.cleaned_data['document_date'] + error = validate_submission_document_date(self.instance.submission_date, document_date) + if error: + raise forms.ValidationError(error) + return document_date class PreapprovalForm(forms.Form): name = forms.CharField(max_length=255, required=True, label="Pre-approved name", initial="draft-ietf-") @@ -588,11 +290,11 @@ class PreapprovalForm(forms.Form): raise forms.ValidationError("Name ends with a dash.") acronym = components[2] if acronym not in self.groups.values_list('acronym', flat=True): - raise forms.ValidationError("WG acronym not recognized as one you can approve drafts for.") + raise forms.ValidationError("Group acronym not recognized as one you can approve drafts for.") if Preapproval.objects.filter(name=n): raise forms.ValidationError("Pre-approval for this name already exists.") - if IdSubmissionDetail.objects.filter(status__in=[POSTED, POSTED_BY_SECRETARIAT ], filename=n): + if Submission.objects.filter(state="posted", name=n): raise forms.ValidationError("A draft with this name has already been submitted and accepted. A pre-approval would not make any difference.") return n diff --git a/ietf/submit/generate_fixtures.py b/ietf/submit/generate_fixtures.py deleted file mode 100755 index cbda2392d..000000000 --- a/ietf/submit/generate_fixtures.py +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/python - -# boiler plate -import os, sys - -ietf_path = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../ietf')) - -sys.path.insert(0, ietf_path) - -from django.core.management import setup_environ -import settings -setup_environ(settings) - -# script -from django.core.serializers import serialize -from django.db.models import Q - -def output(name, qs): - try: - f = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "fixtures/%s.xml" % name), 'w') - f.write(serialize("xml", qs, indent=4)) - f.close() - except: - from django.db import connection - from pprint import pprint - pprint(connection.queries) - raise - -# pick all name models directly out of the module -names = [] - -from ietf.submit.models import IdSubmissionStatus - -output("idsubmissionstatus", IdSubmissionStatus.objects.all()) diff --git a/ietf/submit/mail.py b/ietf/submit/mail.py new file mode 100644 index 000000000..42ddeff3f --- /dev/null +++ b/ietf/submit/mail.py @@ -0,0 +1,152 @@ +from django.conf import settings +from django.core.urlresolvers import reverse as urlreverse +from django.contrib.sites.models import Site +from django.template.loader import render_to_string + +from ietf.utils.mail import send_mail, send_mail_message +from ietf.doc.models import Document +from ietf.person.models import Person +from ietf.group.models import Role +from ietf.message.models import Message +from ietf.utils.accesstoken import generate_access_token + +def submission_confirmation_email_list(submission): + try: + doc = Document.objects.get(name=submission.name) + email_list = [i.author.formatted_email() for i in doc.documentauthor_set.all()] + except Document.DoesNotExist: + email_list = [u"%s <%s>" % (author["name"], author["email"]) + for author in submission.authors_parsed() if author["email"]] + if submission.submitter_parsed()["email"] and submission.submitter not in email_list: + email_list.append(submission.submitter) + return email_list + +def send_submission_confirmation(request, submission): + subject = 'Confirm submission of I-D %s' % submission.name + from_email = settings.IDSUBMIT_FROM_EMAIL + to_email = submission_confirmation_email_list(submission) + + confirm_url = settings.IDTRACKER_BASE_URL + urlreverse('submit_confirm_submission', kwargs=dict(submission_id=submission.pk, auth_token=generate_access_token(submission.auth_key))) + status_url = settings.IDTRACKER_BASE_URL + urlreverse('submit_submission_status_by_hash', kwargs=dict(submission_id=submission.pk, access_token=submission.access_token())) + + send_mail(request, to_email, from_email, subject, 'submit/confirm_submission.txt', { + 'submission': submission, + 'confirm_url': confirm_url, + 'status_url': status_url, + }) + + return to_email + +def send_full_url(request, submission): + subject = 'Full URL for managing submission of draft %s' % submission.name + from_email = settings.IDSUBMIT_FROM_EMAIL + to_email = submission_confirmation_email_list(submission) + url = settings.IDTRACKER_BASE_URL + urlreverse('submit_submission_status_by_hash', kwargs=dict(submission_id=submission.pk, access_token=submission.access_token())) + + send_mail(request, to_email, from_email, subject, 'submit/full_url.txt', { + 'submission': submission, + 'url': url, + }) + + return to_email + +def send_approval_request_to_group(request, submission): + subject = 'New draft waiting for approval: %s' % submission.name + from_email = settings.IDSUBMIT_FROM_EMAIL + to_email = [r.formatted_email() for r in Role.objects.filter(group=submission.group, name="chair").select_related("email", "person")] + if not to_email: + return to_email + + send_mail(request, to_email, from_email, subject, 'submit/approval_request.txt', { + 'submission': submission, + 'domain': Site.objects.get_current().domain, + }) + + return to_email + +def send_manual_post_request(request, submission, errors): + subject = u'Manual Post Requested for %s' % submission.name + from_email = settings.IDSUBMIT_FROM_EMAIL + to_email = settings.IDSUBMIT_TO_EMAIL + + cc = [submission.submitter] + cc += [u"%s <%s>" % (author["name"], author["email"]) + for author in submission.authors_parsed() if author["email"]] + if submission.group: + cc += [r.formatted_email() for r in Role.objects.filter(group=submission.group, name="chair").select_related("email", "person")] + cc = list(set(cc)) + + send_mail(request, to_email, from_email, subject, 'submit/manual_post_request.txt', { + 'submission': submission, + 'url': settings.IDTRACKER_BASE_URL + urlreverse('submit_submission_status', kwargs=dict(submission_id=submission.pk)), + 'errors': errors, + }, cc=cc) + + +def announce_to_lists(request, submission): + m = Message() + m.by = Person.objects.get(name="(System)") + if request.user.is_authenticated(): + try: + m.by = request.user.get_profile() + except Person.DoesNotExist: + pass + m.subject = 'I-D Action: %s-%s.txt' % (submission.name, submission.rev) + m.frm = settings.IDSUBMIT_ANNOUNCE_FROM_EMAIL + m.to = settings.IDSUBMIT_ANNOUNCE_LIST_EMAIL + if submission.group and submission.group.list_email: + m.cc = submission.group.list_email + m.body = render_to_string('submit/announce_to_lists.txt', + dict(submission=submission, + settings=settings)) + m.save() + m.related_docs.add(Document.objects.get(name=submission.name)) + + send_mail_message(request, m) + + +def announce_new_version(request, submission, draft, state_change_msg): + to_email = [] + if draft.notify: + to_email.append(draft.notify) + if draft.ad: + to_email.append(draft.ad.role_email("ad").address) + + if draft.stream_id == "iab": + to_email.append("IAB Stream ") + elif draft.stream_id == "ise": + to_email.append("Independent Submission Editor ") + elif draft.stream_id == "irtf": + to_email.append("IRSG ") + + # if it has been sent to the RFC Editor, keep them in the loop + if draft.get_state_slug("draft-iesg") in ("ann", "rfcqueue"): + to_email.append("RFC Editor ") + + active_ballot = draft.active_ballot() + if active_ballot: + for ad, pos in active_ballot.active_ad_positions().iteritems(): + if pos and pos.pos_id == "discuss": + to_email.append(ad.role_email("ad").address) + + if to_email: + subject = 'New Version Notification - %s-%s.txt' % (submission.name, submission.rev) + from_email = settings.IDSUBMIT_ANNOUNCE_FROM_EMAIL + send_mail(request, to_email, from_email, subject, 'submit/announce_new_version.txt', + {'submission': submission, + 'msg': state_change_msg}) + +def announce_to_authors(request, submission): + authors = [u"%s <%s>" % (author["name"], author["email"]) for author in submission.authors_parsed() if author["email"]] + to_email = list(set(submission_confirmation_email_list(submission) + authors)) + from_email = settings.IDSUBMIT_ANNOUNCE_FROM_EMAIL + subject = 'New Version Notification for %s-%s.txt' % (submission.name, submission.rev) + if submission.group: + group = submission.group.acronym + elif submission.name.startswith('draft-iesg'): + group = 'IESG' + else: + group = 'Individual Submission' + send_mail(request, to_email, from_email, subject, 'submit/announce_to_authors.txt', + {'submission': submission, + 'group': group}) diff --git a/ietf/submit/migrations/0003_turn_nulls_into_empty_strings.py b/ietf/submit/migrations/0003_turn_nulls_into_empty_strings.py new file mode 100644 index 000000000..4030ab46b --- /dev/null +++ b/ietf/submit/migrations/0003_turn_nulls_into_empty_strings.py @@ -0,0 +1,297 @@ +# encoding: utf-8 +import datetime +from south.db import db +from south.v2 import DataMigration +from django.db import models + +class Migration(DataMigration): + + def forwards(self, orm): + nullable_string_fields = [ + "id_document_name", + "comment_to_sec", + "filename", + "revision", + "replaces", + "file_type", + "abstract", + "idnits_message", + "first_two_pages", + "remote_ip", + "auth_key", + "submission_hash", + ] + + for f in nullable_string_fields: + orm.IdSubmissionDetail.objects.filter(**{ f: None}).update(**{ f: ""}) + + def backwards(self, orm): + pass + + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + '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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + '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', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + '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', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}) + }, + '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'}), + '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'}) + }, + 'doc.docalias': { + 'Meta': {'object_name': 'DocAlias'}, + 'document': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.Document']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}) + }, + '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': "orm['person.Person']"}), + 'authors': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['person.Email']", 'symmetrical': 'False', 'through': "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': "orm['group.Group']", 'null': 'True', 'blank': 'True'}), + 'intended_std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': "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'}), + 'related': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'reversely_related_document_set'", 'blank': 'True', 'through': "orm['doc.RelatedDocument']", 'to': "orm['doc.DocAlias']"}), + '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': "orm['person.Person']"}), + 'states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}), + 'std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.StdLevelName']", 'null': 'True', 'blank': 'True'}), + 'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.StreamName']", 'null': 'True', 'blank': 'True'}), + 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "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': "orm['name.DocTypeName']", 'null': 'True', 'blank': 'True'}) + }, + 'doc.documentauthor': { + 'Meta': {'ordering': "['document', 'order']", 'object_name': 'DocumentAuthor'}, + 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Email']"}), + 'document': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.Document']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '1'}) + }, + 'doc.relateddocument': { + 'Meta': {'object_name': 'RelatedDocument'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'relationship': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.DocRelationshipName']"}), + 'source': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.Document']"}), + 'target': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.DocAlias']"}) + }, + 'doc.state': { + 'Meta': {'ordering': "['type', 'order']", 'object_name': 'State'}, + 'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + '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': "orm['doc.State']"}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'db_index': 'True'}), + 'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.StateType']"}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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'}) + }, + 'group.group': { + 'Meta': {'object_name': 'Group'}, + 'acronym': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '40', 'db_index': 'True'}), + 'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "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': "orm['doc.Document']"}), + 'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + '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': "orm['group.Group']", 'null': 'True', 'blank': 'True'}), + 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupStateName']", 'null': 'True'}), + 'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupTypeName']", 'null': 'True'}), + 'unused_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}), + 'unused_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['name.DocTagName']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'group.ietfwg': { + 'Meta': {'object_name': 'IETFWG', 'db_table': "'group_group'", '_ormbases': ['group.Group'], 'proxy': 'True'} + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': "orm['person.Person']", 'null': 'True'}), + 'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}) + }, + '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'}), + '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': "orm['auth.User']", 'unique': 'True', 'null': 'True', 'blank': 'True'}) + }, + 'submit.idsubmissiondetail': { + 'Meta': {'object_name': 'IdSubmissionDetail'}, + 'abstract': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'auth_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'comment_to_sec': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'creation_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'error_message': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'file_type': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), + 'filename': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'filesize': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'first_two_pages': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'group_acronym': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']", 'null': 'True', 'blank': 'True'}), + 'id_document_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'idnits_failed': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'idnits_message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'invalid_version': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'last_updated_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'last_updated_time': ('django.db.models.fields.CharField', [], {'max_length': '25', 'null': 'True', 'blank': 'True'}), + 'man_posted_by': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'man_posted_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'remote_ip': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'replaces': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'revision': ('django.db.models.fields.CharField', [], {'max_length': '3', 'null': 'True', 'blank': 'True'}), + 'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['submit.IdSubmissionStatus']", 'null': 'True', 'db_column': "'status_id'", 'blank': 'True'}), + 'sub_email_priority': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'submission_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'submission_hash': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'submission_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'submitter_tag': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'temp_id_document_tag': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'txt_page_count': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'warning_message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'wg_submission': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}) + }, + 'submit.idsubmissionstatus': { + 'Meta': {'object_name': 'IdSubmissionStatus'}, + 'status_id': ('django.db.models.fields.IntegerField', [], {'primary_key': 'True'}), + 'status_value': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}) + }, + 'submit.preapproval': { + 'Meta': {'object_name': 'Preapproval'}, + 'by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"}), + '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'}) + }, + 'submit.tempidauthors': { + 'Meta': {'object_name': 'TempIdAuthors'}, + 'author_order': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'email_address': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'id_document_tag': ('django.db.models.fields.IntegerField', [], {}), + 'last_modified_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'last_modified_time': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'middle_initial': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'name_suffix': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'submission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['submit.IdSubmissionDetail']"}) + } + } + + complete_apps = ['submit'] diff --git a/ietf/submit/migrations/0004_fixup_idsubmissiondetail_fields.py b/ietf/submit/migrations/0004_fixup_idsubmissiondetail_fields.py new file mode 100644 index 000000000..298abaf72 --- /dev/null +++ b/ietf/submit/migrations/0004_fixup_idsubmissiondetail_fields.py @@ -0,0 +1,327 @@ +# encoding: utf-8 +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + +class Migration(SchemaMigration): + depends_on = ( + ("name", "0019_populate_draftsubmissionstate"), + ) + + def forwards(self, orm): + db.rename_table('submit_idsubmissiondetail', 'submit_submission') + + db.rename_column('submit_submission', 'submission_id', "id") + + db.rename_column('submit_submission', 'id_document_name', "title") + db.alter_column('submit_submission', 'title', self.gf('django.db.models.fields.CharField')(default='', max_length=255, blank=True)) + db.rename_column('submit_submission', 'creation_date', "document_date") + db.rename_column('submit_submission', 'group_acronym_id', 'group_id') + db.rename_column('submit_submission', 'txt_page_count', 'pages') + db.rename_column('submit_submission', 'comment_to_sec', 'note') + db.alter_column('submit_submission', 'note', self.gf('django.db.models.fields.TextField')(default='', blank=True)) + db.rename_column('submit_submission', 'filename', 'name') + db.alter_column('submit_submission', 'name', self.gf('django.db.models.fields.CharField')(db_index=True, default='', max_length=255, blank=True)) + db.rename_column('submit_submission', 'filesize', 'file_size') + db.rename_column('submit_submission', 'revision', 'rev') + db.alter_column('submit_submission', 'rev', self.gf('django.db.models.fields.CharField')(default='', max_length=3, blank=True)) + + db.delete_column('submit_submission', 'idnits_failed') + db.delete_column('submit_submission', 'invalid_version') + db.delete_column('submit_submission', 'temp_id_document_tag') + db.delete_column('submit_submission', 'error_message') + db.delete_column('submit_submission', 'wg_submission') + db.delete_column('submit_submission', 'warning_message') + db.delete_column('submit_submission', 'last_updated_date') + db.delete_column('submit_submission', 'last_updated_time') + + db.add_column('submit_submission', 'state', self.gf('django.db.models.fields.related.ForeignKey')(default='uploaded', to=orm['name.DraftSubmissionStateName'])) + db.add_column('submit_submission', 'authors', self.gf('django.db.models.fields.TextField')(default="")) + db.add_column('submit_submission', 'submitter', self.gf('django.db.models.fields.CharField')(max_length=255, default="")) + + db.alter_column('submit_submission', 'submission_date', self.gf('django.db.models.fields.DateField')()) + + db.alter_column('submit_submission', 'replaces', self.gf('django.db.models.fields.CharField')(default='', max_length=255)) + + db.rename_column('submit_submission', 'file_type', 'file_types') + db.alter_column('submit_submission', 'file_types', self.gf('django.db.models.fields.CharField')(default='', max_length=50)) + + db.alter_column('submit_submission', 'abstract', self.gf('django.db.models.fields.TextField')(default='')) + + db.alter_column('submit_submission', 'idnits_message', self.gf('django.db.models.fields.TextField')(default='')) + + db.alter_column('submit_submission', 'first_two_pages', self.gf('django.db.models.fields.TextField')(default='')) + + db.alter_column('submit_submission', 'remote_ip', self.gf('django.db.models.fields.CharField')(default='', max_length=100)) + + db.alter_column('submit_submission', 'auth_key', self.gf('django.db.models.fields.CharField')(default='', max_length=255)) + + db.rename_column('submit_submission', 'submission_hash', "access_key") + db.alter_column('submit_submission', 'access_key', self.gf('django.db.models.fields.CharField')(default='', max_length=255)) + + db.create_table('submit_submissionevent', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('submission', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['submit.Submission'])), + ('time', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)), + ('by', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['person.Person'], null=True, blank=True)), + ('desc', self.gf('django.db.models.fields.TextField')()), + )) + db.send_create_signal('submit', ['SubmissionEvent']) + + def backwards(self, orm): + pass + + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + '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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + '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', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + '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', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}) + }, + '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'}), + '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'}) + }, + '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': "orm['person.Person']"}), + 'authors': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['person.Email']", 'symmetrical': 'False', 'through': "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': "orm['group.Group']", 'null': 'True', 'blank': 'True'}), + 'intended_std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': "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': "orm['person.Person']"}), + 'states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}), + 'std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.StdLevelName']", 'null': 'True', 'blank': 'True'}), + 'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.StreamName']", 'null': 'True', 'blank': 'True'}), + 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "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': "orm['name.DocTypeName']", 'null': 'True', 'blank': 'True'}) + }, + 'doc.documentauthor': { + 'Meta': {'ordering': "['document', 'order']", 'object_name': 'DocumentAuthor'}, + 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Email']"}), + 'document': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.Document']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '1'}) + }, + 'doc.state': { + 'Meta': {'ordering': "['type', 'order']", 'object_name': 'State'}, + 'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + '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': "orm['doc.State']"}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'db_index': 'True'}), + 'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.StateType']"}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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'}) + }, + 'group.group': { + 'Meta': {'object_name': 'Group'}, + 'acronym': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '40', 'db_index': 'True'}), + 'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "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': "orm['doc.Document']"}), + 'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + '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': "orm['group.Group']", 'null': 'True', 'blank': 'True'}), + 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupStateName']", 'null': 'True'}), + 'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupTypeName']", 'null': 'True'}), + 'unused_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}), + 'unused_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['name.DocTagName']", 'symmetrical': 'False', 'blank': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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'}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': "orm['person.Person']", 'null': 'True'}), + 'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}) + }, + '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'}), + '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': "orm['auth.User']", 'unique': 'True', 'null': 'True', 'blank': 'True'}) + }, + 'submit.submission': { + 'Meta': {'object_name': 'Submission'}, + 'abstract': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'auth_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'document_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'file_size': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'file_types': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), + 'first_two_pages': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']", 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'idnits_message': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'man_posted_by': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'man_posted_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}), + 'note': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'pages': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'remote_ip': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), + 'replaces': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'submitter': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'rev': ('django.db.models.fields.CharField', [], {'max_length': '3', 'blank': 'True'}), + 'state': ('django.db.models.fields.related.ForeignKey', [], {'default': "'uploaded'", 'to': "orm['name.DraftSubmissionStateName']"}), + 'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['submit.IdSubmissionStatus']", 'null': 'True', 'db_column': "'status_id'", 'blank': 'True'}), + 'sub_email_priority': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'submission_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.date.today'}), + 'access_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'submitter_tag': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'authors': ('django.db.models.fields.TextField', [], {'blank': 'True'}) + }, + 'submit.submissionevent': { + 'Meta': {'ordering': "('-time', '-id')", 'object_name': 'SubmissionEvent'}, + 'by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']", 'null': 'True', 'blank': 'True'}), + 'desc': ('django.db.models.fields.TextField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'submission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['submit.Submission']"}), + 'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}) + }, + 'submit.idsubmissionstatus': { + 'Meta': {'object_name': 'IdSubmissionStatus'}, + 'status_id': ('django.db.models.fields.IntegerField', [], {'primary_key': 'True'}), + 'status_value': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}) + }, + 'submit.preapproval': { + 'Meta': {'object_name': 'Preapproval'}, + 'by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"}), + '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'}) + }, + 'submit.tempidauthors': { + 'Meta': {'object_name': 'TempIdAuthors'}, + 'author_order': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'email_address': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'id_document_tag': ('django.db.models.fields.IntegerField', [], {'default': '-1'}), + 'last_modified_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'last_modified_time': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'middle_initial': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'name_suffix': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'submission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['submit.Submission']"}) + } + } + + complete_apps = ['submit'] diff --git a/ietf/submit/migrations/0005_fill_in_new_fields.py b/ietf/submit/migrations/0005_fill_in_new_fields.py new file mode 100644 index 000000000..0c47a81c3 --- /dev/null +++ b/ietf/submit/migrations/0005_fill_in_new_fields.py @@ -0,0 +1,392 @@ +# encoding: utf-8 +import datetime +from south.db import db +from south.v2 import DataMigration +from django.db import models + +class Migration(DataMigration): + + def forwards(self, orm): + import hashlib, random, time + from django.conf import settings + + state_map = dict((n.slug, n) for n in orm["name.DraftSubmissionStateName"].objects.all()) + status_map = { + -4: "cancel", + -2: "posted", # Secretariat + -1: "posted", + 1: "uploaded", + 4: "auth", + 5: "manual", + 10: "grp-appr", + } + + from django.core.validators import validate_email, ValidationError + + for d in orm.Submission.objects.all().iterator(): + if not d.name: + # get rid of a few mishaps that seem to have been + # accepted without a name + d.delete() + continue + + # map state + state = state_map[status_map.get(d.status_id, "cancel")] + + # map authors + authors = [] + submitter = "" + submitter_email = "" + + for a in d.tempidauthors_set.order_by("author_order"): + parts = (a.first_name or '', a.middle_initial or '', a.last_name or '', a.name_suffix or '') + name = u" ".join(x.strip() for x in parts if x.strip()) + email = a.email_address + orig = email + + # clean + name = name.replace("\n", "").replace("\r", "").replace("<", "").replace(">", "").strip() + email = email.replace("Email:", "").replace("E-mail:", "").replace("mailto:", "").replace(">", "").replace("<", "").replace("\n", "").replace(" ", "").rstrip(",").lstrip(":").strip(".").rstrip(";").rstrip("-").rstrip("\"").lstrip("\"").rstrip("@") + + if email: + line = u"%s <%s>" % (name, email) + else: + line = name + + if a.author_order == 0: + submitter = line + submitter_email = email + else: + authors.append(line) + + # make sure we always have a key + access_key = d.access_key + if not access_key: + access_key = hashlib.sha256(settings.SECRET_KEY + ("%.16f" % time.time()) + ("%.16f" % random.random()) + str(d.name.encode("utf-8"))).hexdigest()[:32] + + + # fill in submission event + submitter_person = None + if d.submitter_tag: + try: + submitter_person = orm["person.Person"].objects.get(id=d.submitter_tag) + except models.ObjectDoesNotExist: + pass + + if submitter_email: + try: + submitter_person = orm["person.Person"].objects.get(email__address=submitter_email) + except models.ObjectDoesNotExist: + pass + + if submitter_person and not submitter: + submitter = submitter_person.name + + if submitter_person: + orm.SubmissionEvent.objects.get_or_create( + submission=d, + time=d.submission_date, + by=submitter_person, + desc="Uploaded submission", + ) + + + # fill in manual post events + if d.status_id == -2 and d.man_posted_by: + if d.man_posted_by == "Amy Vezza": + d.man_posted_by = "Amy K. Vezza" + + try: + by = orm["person.Person"].objects.get(name=d.man_posted_by) + orm.SubmissionEvent.objects.get_or_create( + submission=d, + time=d.man_posted_date or d.submission_date, + by=by, + desc="Posted submission manually", + ) + except models.ObjectDoesNotExist: + pass + + # update the new revision doc events that are set to + # "(System)" with our newly discovered submitter + if submitter_person and d.state_id == "posted": + orm["doc.NewRevisionDocEvent"].objects.filter(doc=d.name, rev=d.rev, type="new_revision", by=0).update(by=submitter_person) + + # update the submission itself + orm.Submission.objects.filter(pk=d.pk).update( + submitter=submitter, + state=state, + authors="\n".join(authors), + access_key=access_key, + ) + + + def backwards(self, orm): + "Write your backwards methods here." + + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + '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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + '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', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + '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', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}) + }, + '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'}), + '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'}) + }, + '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': "orm['person.Person']"}), + 'authors': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['person.Email']", 'symmetrical': 'False', 'through': "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': "orm['group.Group']", 'null': 'True', 'blank': 'True'}), + 'intended_std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': "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': "orm['person.Person']"}), + 'states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}), + 'std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.StdLevelName']", 'null': 'True', 'blank': 'True'}), + 'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.StreamName']", 'null': 'True', 'blank': 'True'}), + 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "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': "orm['name.DocTypeName']", 'null': 'True', 'blank': 'True'}) + }, + 'doc.documentauthor': { + 'Meta': {'ordering': "['document', 'order']", 'object_name': 'DocumentAuthor'}, + 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Email']"}), + 'document': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.Document']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '1'}) + }, + 'doc.docevent': { + 'Meta': {'ordering': "['-time', '-id']", 'object_name': 'DocEvent'}, + 'by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"}), + 'desc': ('django.db.models.fields.TextField', [], {}), + 'doc': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.Document']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'doc.newrevisiondocevent': { + 'Meta': {'ordering': "['-time', '-id']", 'object_name': 'NewRevisionDocEvent', '_ormbases': ['doc.DocEvent']}, + 'docevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['doc.DocEvent']", 'unique': 'True', 'primary_key': 'True'}), + 'rev': ('django.db.models.fields.CharField', [], {'max_length': '16'}) + }, + 'doc.state': { + 'Meta': {'ordering': "['type', 'order']", 'object_name': 'State'}, + 'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + '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': "orm['doc.State']"}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'db_index': 'True'}), + 'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.StateType']"}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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'}) + }, + 'group.group': { + 'Meta': {'object_name': 'Group'}, + 'acronym': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '40', 'db_index': 'True'}), + 'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "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': "orm['doc.Document']"}), + 'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + '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': "orm['group.Group']", 'null': 'True', 'blank': 'True'}), + 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupStateName']", 'null': 'True'}), + 'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupTypeName']", 'null': 'True'}), + 'unused_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}), + 'unused_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['name.DocTagName']", 'symmetrical': 'False', 'blank': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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'}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': "orm['person.Person']", 'null': 'True'}), + 'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}) + }, + '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'}), + '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': "orm['auth.User']", 'unique': 'True', 'null': 'True', 'blank': 'True'}) + }, + 'submit.submission': { + 'Meta': {'object_name': 'Submission'}, + 'abstract': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'auth_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'document_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'file_size': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'file_types': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), + 'first_two_pages': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']", 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'idnits_message': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'man_posted_by': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'man_posted_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}), + 'note': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'pages': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'remote_ip': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), + 'replaces': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'submitter': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'rev': ('django.db.models.fields.CharField', [], {'max_length': '3', 'blank': 'True'}), + 'state': ('django.db.models.fields.related.ForeignKey', [], {'default': "'uploaded'", 'to': "orm['name.DraftSubmissionStateName']"}), + 'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['submit.IdSubmissionStatus']", 'null': 'True', 'db_column': "'status_id'", 'blank': 'True'}), + 'sub_email_priority': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'submission_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.date.today'}), + 'access_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'submitter_tag': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'authors': ('django.db.models.fields.TextField', [], {'blank': 'True'}) + }, + 'submit.submissionevent': { + 'Meta': {'ordering': "('-time', '-id')", 'object_name': 'SubmissionEvent'}, + 'by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']", 'null': 'True', 'blank': 'True'}), + 'desc': ('django.db.models.fields.TextField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'submission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['submit.Submission']"}), + 'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}) + }, + 'submit.idsubmissionstatus': { + 'Meta': {'object_name': 'IdSubmissionStatus'}, + 'status_id': ('django.db.models.fields.IntegerField', [], {'primary_key': 'True'}), + 'status_value': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}) + }, + 'submit.preapproval': { + 'Meta': {'object_name': 'Preapproval'}, + 'by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"}), + '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'}) + }, + 'submit.tempidauthors': { + 'Meta': {'object_name': 'TempIdAuthors'}, + 'author_order': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'email_address': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'id_document_tag': ('django.db.models.fields.IntegerField', [], {'default': '-1'}), + 'last_modified_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'last_modified_time': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'middle_initial': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'name_suffix': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'submission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['submit.Submission']"}) + } + } + + complete_apps = ['submit'] diff --git a/ietf/submit/migrations/0006_auto__del_tempidauthors__del_idsubmissionstatus__del_field_submission_.py b/ietf/submit/migrations/0006_auto__del_tempidauthors__del_idsubmissionstatus__del_field_submission_.py new file mode 100644 index 000000000..7269d3c93 --- /dev/null +++ b/ietf/submit/migrations/0006_auto__del_tempidauthors__del_idsubmissionstatus__del_field_submission_.py @@ -0,0 +1,301 @@ +# encoding: utf-8 +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + +class Migration(SchemaMigration): + + def forwards(self, orm): + + # Deleting model 'TempIdAuthors' + db.delete_table('submit_tempidauthors') + + # Deleting model 'IdSubmissionStatus' + db.delete_table('submit_idsubmissionstatus') + + # Deleting field 'Submission.man_posted_date' + db.delete_column('submit_submission', 'man_posted_date') + + # Deleting field 'Submission.status' + db.delete_column('submit_submission', 'status_id') + + # Deleting field 'Submission.submitter_tag' + db.delete_column('submit_submission', 'submitter_tag') + + # Deleting field 'Submission.sub_email_priority' + db.delete_column('submit_submission', 'sub_email_priority') + + # Deleting field 'Submission.man_posted_by' + db.delete_column('submit_submission', 'man_posted_by') + + + def backwards(self, orm): + + # Adding model 'TempIdAuthors' + db.create_table('submit_tempidauthors', ( + ('last_name', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)), + ('last_modified_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True)), + ('id_document_tag', self.gf('django.db.models.fields.IntegerField')(default=-1)), + ('last_modified_time', self.gf('django.db.models.fields.CharField')(max_length=100, blank=True)), + ('email_address', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)), + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('middle_initial', self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True)), + ('first_name', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)), + ('submission', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['submit.Submission'])), + ('name_suffix', self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True)), + ('author_order', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)), + )) + db.send_create_signal('submit', ['TempIdAuthors']) + + # Adding model 'IdSubmissionStatus' + db.create_table('submit_idsubmissionstatus', ( + ('status_value', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)), + ('status_id', self.gf('django.db.models.fields.IntegerField')(primary_key=True)), + )) + db.send_create_signal('submit', ['IdSubmissionStatus']) + + # Adding field 'Submission.man_posted_date' + db.add_column('submit_submission', 'man_posted_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True), keep_default=False) + + # Adding field 'Submission.status' + db.add_column('submit_submission', 'status', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['submit.IdSubmissionStatus'], null=True, db_column='status_id', blank=True), keep_default=False) + + # Adding field 'Submission.submitter_tag' + db.add_column('submit_submission', 'submitter_tag', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True), keep_default=False) + + # Adding field 'Submission.sub_email_priority' + db.add_column('submit_submission', 'sub_email_priority', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True), keep_default=False) + + # Adding field 'Submission.man_posted_by' + db.add_column('submit_submission', 'man_posted_by', self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True), keep_default=False) + + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + '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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + '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', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + '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', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}) + }, + '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'}), + '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'}) + }, + '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': "orm['person.Person']"}), + 'authors': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['person.Email']", 'symmetrical': 'False', 'through': "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': "orm['group.Group']", 'null': 'True', 'blank': 'True'}), + 'intended_std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': "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': "orm['person.Person']"}), + 'states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}), + 'std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.StdLevelName']", 'null': 'True', 'blank': 'True'}), + 'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.StreamName']", 'null': 'True', 'blank': 'True'}), + 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "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': "orm['name.DocTypeName']", 'null': 'True', 'blank': 'True'}) + }, + 'doc.documentauthor': { + 'Meta': {'ordering': "['document', 'order']", 'object_name': 'DocumentAuthor'}, + 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Email']"}), + 'document': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.Document']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '1'}) + }, + 'doc.state': { + 'Meta': {'ordering': "['type', 'order']", 'object_name': 'State'}, + 'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + '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': "orm['doc.State']"}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'db_index': 'True'}), + 'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.StateType']"}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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'}) + }, + 'group.group': { + 'Meta': {'object_name': 'Group'}, + 'acronym': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '40', 'db_index': 'True'}), + 'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "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': "orm['doc.Document']"}), + 'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + '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': "orm['group.Group']", 'null': 'True', 'blank': 'True'}), + 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupStateName']", 'null': 'True'}), + 'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupTypeName']", 'null': 'True'}), + 'unused_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}), + 'unused_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['name.DocTagName']", 'symmetrical': 'False', 'blank': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': "orm['name.DraftSubmissionStateName']"}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': '8', 'primary_key': 'True'}), + 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + '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': "orm['person.Person']", 'null': 'True'}), + 'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}) + }, + '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'}), + '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': "orm['auth.User']", 'unique': 'True', 'null': 'True', 'blank': 'True'}) + }, + 'submit.preapproval': { + 'Meta': {'object_name': 'Preapproval'}, + 'by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"}), + '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'}) + }, + 'submit.submission': { + 'Meta': {'object_name': 'Submission'}, + 'abstract': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'access_key': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'auth_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'authors': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'document_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'file_size': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'file_types': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), + 'first_two_pages': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']", 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'idnits_message': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'note': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'pages': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'remote_ip': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), + 'replaces': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'rev': ('django.db.models.fields.CharField', [], {'max_length': '3', 'blank': 'True'}), + 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.DraftSubmissionStateName']"}), + 'submission_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.date.today'}), + 'submitter': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}) + }, + 'submit.submissionevent': { + 'Meta': {'ordering': "('-time', '-id')", 'object_name': 'SubmissionEvent'}, + 'by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']", 'null': 'True', 'blank': 'True'}), + 'desc': ('django.db.models.fields.TextField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'submission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['submit.Submission']"}), + 'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}) + } + } + + complete_apps = ['submit'] diff --git a/ietf/submit/models.py b/ietf/submit/models.py index e73a91611..27184fe45 100644 --- a/ietf/submit/models.py +++ b/ietf/submit/models.py @@ -1,85 +1,80 @@ -import re, datetime # +import re, datetime, hashlib from django.conf import settings from django.db import models -from django.utils.hashcompat import md5_constructor -from ietf.idtracker.models import InternetDraft, IETFWG from ietf.person.models import Person +from ietf.group.models import Group +from ietf.name.models import DraftSubmissionStateName +from ietf.utils.accesstoken import generate_random_key, generate_access_token -class IdSubmissionStatus(models.Model): - status_id = models.IntegerField(primary_key=True) - status_value = models.CharField(blank=True, max_length=255) +def parse_email_line(line): + """Split line on the form 'Some Name '""" + m = re.match("([^<]+) <([^>]+)>$", line) + if m: + return dict(name=m.group(1), email=m.group(2)) + else: + return dict(name=line, email="") + +class Submission(models.Model): + state = models.ForeignKey(DraftSubmissionStateName) + remote_ip = models.CharField(max_length=100, blank=True) + + access_key = models.CharField(max_length=255, default=generate_random_key) + auth_key = models.CharField(max_length=255, blank=True) + + # draft metadata + name = models.CharField(max_length=255, db_index=True) + group = models.ForeignKey(Group, null=True, blank=True) + title = models.CharField(max_length=255, blank=True) + abstract = models.TextField(blank=True) + rev = models.CharField(max_length=3, blank=True) + pages = models.IntegerField(null=True, blank=True) + authors = models.TextField(blank=True, help_text="List of author names and emails, one author per line, e.g. \"John Doe <john@example.org>\"") + note = models.TextField(blank=True) + replaces = models.CharField(max_length=255, blank=True) + + first_two_pages = models.TextField(blank=True) + file_types = models.CharField(max_length=50, blank=True) + file_size = models.IntegerField(null=True, blank=True) + document_date = models.DateField(null=True, blank=True) + submission_date = models.DateField(default=datetime.date.today) + + submitter = models.CharField(max_length=255, blank=True, help_text="Name and email of submitter, e.g. \"John Doe <john@example.org>\"") + + idnits_message = models.TextField(blank=True) def __unicode__(self): - return self.status_value + return u"%s-%s" % (self.name, self.rev) -class IdSubmissionDetail(models.Model): - submission_id = models.AutoField(primary_key=True) - temp_id_document_tag = models.IntegerField(null=True, blank=True) - status = models.ForeignKey(IdSubmissionStatus, db_column='status_id', null=True, blank=True) - last_updated_date = models.DateField(null=True, blank=True) - last_updated_time = models.CharField(null=True, blank=True, max_length=25) - id_document_name = models.CharField(null=True, blank=True, max_length=255) - group_acronym = models.ForeignKey(IETFWG, null=True, blank=True) - filename = models.CharField(null=True, blank=True, max_length=255, db_index=True) - creation_date = models.DateField(null=True, blank=True) - submission_date = models.DateField(null=True, blank=True) - remote_ip = models.CharField(null=True, blank=True, max_length=100) - revision = models.CharField(null=True, blank=True, max_length=3) - submitter_tag = models.IntegerField(null=True, blank=True) - auth_key = models.CharField(null=True, blank=True, max_length=255) - idnits_message = models.TextField(null=True, blank=True) - file_type = models.CharField(null=True, blank=True, max_length=50) - comment_to_sec = models.TextField(null=True, blank=True) - abstract = models.TextField(null=True, blank=True) - txt_page_count = models.IntegerField(null=True, blank=True) - error_message = models.CharField(null=True, blank=True, max_length=255) - warning_message = models.TextField(null=True, blank=True) - wg_submission = models.IntegerField(null=True, blank=True) - filesize = models.IntegerField(null=True, blank=True) - man_posted_date = models.DateField(null=True, blank=True) - man_posted_by = models.CharField(null=True, blank=True, max_length=255) - first_two_pages = models.TextField(null=True, blank=True) - sub_email_priority = models.IntegerField(null=True, blank=True) - invalid_version = models.IntegerField(null=True, blank=True) - idnits_failed = models.IntegerField(null=True, blank=True) - submission_hash = models.CharField(null=True, blank=True, max_length=255) + def authors_parsed(self): + res = [] + for line in self.authors.replace("\r", "").split("\n"): + line = line.strip() + if line: + res.append(parse_email_line(line)) + return res + + def submitter_parsed(self): + return parse_email_line(self.submitter) + + def access_token(self): + return generate_access_token(self.access_key) + + +class SubmissionEvent(models.Model): + submission = models.ForeignKey(Submission) + time = models.DateTimeField(default=datetime.datetime.now) + by = models.ForeignKey(Person, null=True, blank=True) + desc = models.TextField() def __unicode__(self): - return u"%s-%s" % (self.filename, self.revision) + return u"%s %s by %s at %s" % (self.submission.name, self.desc, self.by.plain_name() if self.by else "(unknown)", self.time) - def create_hash(self): - self.submission_hash = md5_constructor(settings.SECRET_KEY + self.filename).hexdigest() + class Meta: + ordering = ("-time", "-id") - def get_hash(self): - if not self.submission_hash: - self.create_hash() - self.save() - return self.submission_hash - def draft_link(self): - if self.status_id == -1: - return '%s' % (self.filename, self.revision, self.filename) - else: - return self.filename - draft_link.allow_tags = True - def status_link(self): - return '%s' % (self.submission_id, self.submission_hash, self.status) - status_link.allow_tags = True - - def confirmation_email_list(self): - try: - draft = InternetDraft.objects.get(filename=self.filename) - email_list = list(set(u'%s <%s>' % (i.person.ascii, i.email()) for i in draft.authors)) - except InternetDraft.DoesNotExist: - email_list = list(set(u'%s <%s>' % i.email() for i in self.tempidauthors_set.all())) - return email_list - -def create_submission_hash(sender, instance, **kwargs): - instance.create_hash() - -models.signals.pre_save.connect(create_submission_hash, sender=IdSubmissionDetail) class Preapproval(models.Model): """Pre-approved draft submission name.""" @@ -89,29 +84,3 @@ class Preapproval(models.Model): def __unicode__(self): return self.name - -class TempIdAuthors(models.Model): - id_document_tag = models.IntegerField() - first_name = models.CharField(blank=True, max_length=255) # with new schema, this contains the full name while the other name fields are empty to avoid loss of information - last_name = models.CharField(blank=True, max_length=255) - email_address = models.CharField(blank=True, max_length=255) - last_modified_date = models.DateField(null=True, blank=True) - last_modified_time = models.CharField(blank=True, max_length=100) - author_order = models.IntegerField(null=True, blank=True) - submission = models.ForeignKey(IdSubmissionDetail) - middle_initial = models.CharField(blank=True, max_length=255, null=True) - name_suffix = models.CharField(blank=True, max_length=255, null=True) - - class Meta: - if not settings.USE_DB_REDESIGN_PROXY_CLASSES: - db_table = 'temp_id_authors' - - def email(self): - return (self.get_full_name(), self.email_address) - - def get_full_name(self): - parts = (self.first_name or '', self.middle_initial or '', self.last_name or '', self.name_suffix or '') - return u" ".join(x.strip() for x in parts if x.strip()) - - def __unicode__(self): - return u"%s <%s>" % self.email() diff --git a/ietf/submit/parsers/base.py b/ietf/submit/parsers/base.py index 7dd8618ae..53c0afa38 100644 --- a/ietf/submit/parsers/base.py +++ b/ietf/submit/parsers/base.py @@ -1,26 +1,28 @@ import re - -CUTOFF_HOUR = 17 - - -class MetaDataDraft(object): - revision = None - filename = None +class MetaData(object): + rev = None + name = None group = None - filesize = None + file_size = None first_two_pages = None - page_count = None + pages = None submission_date = None - creation_date = None + document_date = None authors = None class ParseInfo(object): + """Collect errors from a parse""" def __init__(self): self.errors = [] + # warnings are currently unused by the parsers self.warnings = {} - self.metadraft = MetaDataDraft() + # the metadata fields are currently unused, i.e. the plain + # text parser fills in some fields but they are not used + # anywhere (instead the draft parser is used for .txt and the + # other file types have no actual parsing at the moment) + self.metadata = MetaData() def add_error(self, error_str): self.errors.append(error_str) diff --git a/ietf/submit/parsers/plain_parser.py b/ietf/submit/parsers/plain_parser.py index 40e92c054..fb1e4c723 100644 --- a/ietf/submit/parsers/plain_parser.py +++ b/ietf/submit/parsers/plain_parser.py @@ -2,12 +2,9 @@ import datetime import re from django.conf import settings -from ietf.idtracker.models import InternetDraft, IETFWG from django.template.defaultfilters import filesizeformat from ietf.submit.parsers.base import FileParser -NONE_WG_PK = 1027 - class PlainParser(FileParser): @@ -20,14 +17,14 @@ class PlainParser(FileParser): super(PlainParser, self).critical_parse() self.parse_max_size() self.parse_file_charset() - self.parse_filename() + self.parse_name() return self.parsed_info def parse_max_size(self): - if self.fd.size > settings.MAX_PLAIN_DRAFT_SIZE: - self.parsed_info.add_error('File size is larger than %s' % filesizeformat(settings.MAX_PLAIN_DRAFT_SIZE)) - self.parsed_info.metadraft.filesize = self.fd.size - self.parsed_info.metadraft.submission_date = datetime.date.today() + if self.fd.size > settings.IDSUBMIT_MAX_PLAIN_DRAFT_SIZE: + self.parsed_info.add_error('File size is larger than %s' % filesizeformat(settings.IDSUBMIT_MAX_PLAIN_DRAFT_SIZE)) + self.parsed_info.metadata.file_size = self.fd.size + self.parsed_info.metadata.submission_date = datetime.date.today() def parse_file_charset(self): import magic @@ -43,9 +40,9 @@ class PlainParser(FileParser): magic.magic_load(m.cookie, None) filetype = m.from_buffer(content) if not 'ascii' in filetype: - self.parsed_info.add_error('A plain text document must be submitted.') + self.parsed_info.add_error('A plain text ASCII document must be submitted.') - def parse_filename(self): + def parse_name(self): self.fd.file.seek(0) draftre = re.compile('(draft-\S+)') revisionre = re.compile('.*-(\d+)$') @@ -56,24 +53,24 @@ class PlainParser(FileParser): match = draftre.search(line) if not match: continue - filename = match.group(1) - filename = re.sub('^[^\w]+', '', filename) - filename = re.sub('[^\w]+$', '', filename) - filename = re.sub('\.txt$', '', filename) - extra_chars = re.sub('[0-9a-z\-]', '', filename) + name = match.group(1) + name = re.sub('^[^\w]+', '', name) + name = re.sub('[^\w]+$', '', name) + name = re.sub('\.txt$', '', name) + extra_chars = re.sub('[0-9a-z\-]', '', name) if extra_chars: if len(extra_chars) == 1: - self.parsed_info.add_error((u'The filename contains a disallowed character: %s ' % (', '.join(set(extra_chars))).decode('ascii','replace')) + + self.parsed_info.add_error((u'The name contains a disallowed character: %s ' % (', '.join(set(extra_chars))).decode('ascii','replace')) + u'(see http://www.ietf.org/id-info/guidelines.html#naming for details).') else: - self.parsed_info.add_error((u'The filename contains disallowed characters: %s ' % (', '.join(set(extra_chars))).decode('ascii','replace')) + + self.parsed_info.add_error((u'The name contains disallowed characters: %s ' % (', '.join(set(extra_chars))).decode('ascii','replace')) + u'(see http://www.ietf.org/id-info/guidelines.html#naming for details).') - match_revision = revisionre.match(filename) + match_revision = revisionre.match(name) if match_revision: - self.parsed_info.metadraft.revision = match_revision.group(1) + self.parsed_info.metadata.rev = match_revision.group(1) else: - self.parsed_info.add_error(u'The filename found on the first page of the document does not contain a revision: "%s"' % (filename,)) - filename = re.sub('-\d+$', '', filename) - self.parsed_info.metadraft.filename = filename + self.parsed_info.add_error(u'The name found on the first page of the document does not contain a revision: "%s"' % (name,)) + name = re.sub('-\d+$', '', name) + self.parsed_info.metadata.name = name return - self.parsed_info.add_error('The first page of the document does not contain a legitimate filename that start with draft-*') + self.parsed_info.add_error('The first page of the document does not contain a legitimate name that start with draft-*') diff --git a/ietf/submit/templatetags/submit_tags.py b/ietf/submit/templatetags/submit_tags.py index e86142050..5692db021 100644 --- a/ietf/submit/templatetags/submit_tags.py +++ b/ietf/submit/templatetags/submit_tags.py @@ -4,40 +4,37 @@ from django import template from django.conf import settings from django.utils.html import mark_safe, escape -from ietf.submit.utils import POSTED, POSTED_BY_SECRETARIAT - - register = template.Library() @register.inclusion_tag('submit/submission_files.html', takes_context=True) def show_submission_files(context, submission): result = [] - for ext in submission.file_type.split(','): + for ext in submission.file_types.split(','): exists = False - source = os.path.join(settings.IDSUBMIT_STAGING_PATH, '%s-%s%s' % (submission.filename, submission.revision, ext)) + source = os.path.join(settings.IDSUBMIT_STAGING_PATH, '%s-%s%s' % (submission.name, submission.rev, ext)) if os.path.exists(source): exists = True - elif submission.status_id in [POSTED, POSTED_BY_SECRETARIAT]: + elif submission.state_id == "posted": continue - result.append({'name': '[%s version ]' % ext[1:].capitalize(), + result.append({'name': '[%s version]' % ext[1:].upper(), 'exists': exists, - 'url': '%s%s-%s%s' % (settings.IDSUBMIT_STAGING_URL, submission.filename, submission.revision, ext)}) + 'url': '%s%s-%s%s' % (settings.IDSUBMIT_STAGING_URL, submission.name, submission.rev, ext)}) return {'files': result} @register.filter -def two_pages_decorated_with_validation(value, validation): - pages = value.first_two_pages or '' - if not 'revision' in validation.warnings.keys(): - return mark_safe('' % escape(pages)) - result = ' +{% endfilter %} +{% endif %} +{% if num == "1.4" %} {% filter linebreaks_crlf %}
      -{{ action_items }}
      -
      {% endfilter %} +{{ section.text }} + +{% endfilter %} +{% endif %} - - - +{% if num >= "2" and num < "5" %} + {% if "doc" in section %} + {% with section.doc as doc %} + {% if doc.type_id == "draft" or doc.type_id == "statchg" %}{% include "iesg/moderator_doc.html" %}{% endif %} + {% if doc.type_id == "conflrev" %}{% include "iesg/moderator_conflict_doc.html" %}{% endif %} + {% if doc.type_id == "charter" %}{% include "iesg/moderator_charter.html" %}{% endif %} + {% endwith %} + {% else %} +

      NONE

      + {% endif %} +{% endif %} -{% with "iesg/moderator_doc.html" as doc_template %} -{% with "iesg/moderator_conflict_doc.html" as doc_conflict_template %} -{% include "iesg/agenda_outline_23.html" %} -{% endwith %} -{% endwith %} +{% if num >= "6" and num < "7" %} + {% if num == "6" %} +

      NONE

      + {% else %} +

      Is there anything that you would like the Secretariat to record in the minutes for this management issue?

      - - - +

      Decision:

      -{% with "iesg/moderator_wg.html" as wg_template %} -{% include "iesg/agenda_outline_4.html" %} -{% endwith %} +

      The management issue was discussed.

      - - - - -

      5. IAB News We Can Use

      - - - - - -{% for m in mgmt %} -

      6. Management Items
      -6.{{forloop.counter}} {{m.title}}

      - -

      Is there anything that you would like the Secretariat to record in the minutes for this management issue?

      - -

      Decision:

      - -

      The management issue was discussed.

      - -

      Action Item (if applicable):

      - -{% empty %} -

      6. Management Items

      - -

      NONE

      -{% endfor %} - - - - - -

      7. Working Group News

      +

      Action Item (if applicable):

      + {% endif %} +{% endif %} +{% if num == "7" %} {% filter linebreaks_crlf %}
      -{% for name in ad_names %}[ ] {{ name }}
      +{% for ad in section.ads %}[ ] {{ ad.plain_name }}
       {% endfor %}
       
      {% endfilter %} +{% endif %} - +{% endfor %} + + + diff --git a/ietf/templates/iesg/review_decisions.html b/ietf/templates/iesg/review_decisions.html new file mode 100644 index 000000000..e67f966b9 --- /dev/null +++ b/ietf/templates/iesg/review_decisions.html @@ -0,0 +1,26 @@ +{% extends "base.html" %} + +{% block title %}IESG Review Decisions in {{ timeframe }}{% endblock %} + +{% block morecss %} +div.decisions h3 { margin-bottom: 0.5em; } +div.decisions div { padding-left: 1em; text-indent: -1em; } +{% endblock %} + +{% block content %} +

      IESG Review Decisions in {{ timeframe }}

      + +

      Showing review decisions announced in {{ timeframe }}.

      + +

      Announcements in: + {% for y in years %}{{ y }}{% if not forloop.last %}, {% endif %}{% endfor %} +

      + +
      +{% for e in events %} + {% ifchanged %}

      {{ e.time|date:"F j, Y" }}

      {% endifchanged %} +
      {{ e.desc }}: {{ e.doc.name }} {% if e.doc.intended_std_level %}({{ e.doc.intended_std_level }}){% endif %} - {{ e.doc.title }}
      +{% endfor %} +
      + +{% endblock %} diff --git a/ietf/templates/iesg/scribe_conflict_doc.html b/ietf/templates/iesg/scribe_conflict_doc.html index 8c618f9aa..8508438d4 100644 --- a/ietf/templates/iesg/scribe_conflict_doc.html +++ b/ietf/templates/iesg/scribe_conflict_doc.html @@ -1,98 +1,23 @@ -{% comment %} -Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). -All rights reserved. Contact: Pasi Eronen +
    • + {{ doc.title }} -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: +
      {{doc.canonical_name}} + [txt] - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. +
      + {{ doc.conflictdoc.title }} ({{ doc.conflictdoc.stream }}: {{ doc.conflictdoc.intended_std_level }}) +
      {{ doc.conflictdoc.canonical_name }} + [txt] + {% if doc.conflictdoc.note %} +
      Note: {{ doc.conflictdoc.note|linebreaksbr }} + {% endif %} + {% for ipr in doc.conflictdoc.ipr %} + {% if ipr.ipr.status == 1 %} +
      IPR: {{ ipr.ipr.title }} + {% endif %} + {% endfor %} +
      + Token: {{ doc.ad }} - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * Neither the name of the Nokia Corporation and/or its - subsidiary(-ies) nor the names of its contributors may be used - to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -{% endcomment %}{% comment %} -Some parts Copyright (c) 2009 The IETF Trust, all rights reserved. -{% endcomment %} -{% load ietf_filters %} -{% if title2_first %} - {% if title1_first %} -

      {{ title1 }}

      - {% endif %} -

      {{ title2 }}

      - {% endif %}

      {{ title3 }}

      - -
        - {% for doc in section_docs %} -
      • - {{ doc.obj.title|escape }} -
        {{doc.obj.canonical_name}} - [txt] -
        - {{ doc.obj.conflictdoc.title|escape }} ({{doc.obj.conflictdoc.stream}}: {{ doc.obj.conflictdoc.intended_std_level }}) -
        {{doc.obj.conflictdoc.canonical_name}} - [txt] - {% if doc.obj.conflictdoc.note %} -
        Note: {{ doc.obj.conflictdoc.note|linebreaksbr }} - {% endif %} - {% for ipr in doc.obj.conflictdoc.ipr %} - {% ifequal ipr.ipr.status 1 %} -
        IPR: {{ ipr.ipr.title|escape }} - {% endifequal %} - {% endfor %} -
        - Token: {{ doc.obj.ad.plain_name|escape }} - {% if doc.obj.active_ballot %} -
        Discusses/comments [ballot]: - - {% endif %} - -

        Telechat:

        -
          -
        • ...
        • -
        • ...
        • -
        • ...
        • -
        • ...
        • -
        • ...
        • -
        + {% include "iesg/scribe_doc_ballot.html" %}
      • -{% empty %} -
      • (none)
      • -{% endfor %} -
      diff --git a/ietf/templates/iesg/scribe_doc.html b/ietf/templates/iesg/scribe_doc.html index 22491e7ea..29b76a018 100644 --- a/ietf/templates/iesg/scribe_doc.html +++ b/ietf/templates/iesg/scribe_doc.html @@ -1,99 +1,25 @@ -{% comment %}{% endcomment %}{% comment %} -Some parts Copyright (c) 2009 The IETF Trust, all rights reserved. -{% endcomment %} -{% load ietf_filters %} -{% if title2_first %} - {% if title1_first %} -

      {{ title1 }}

      - {% endif %} -

      {{ title2 }}

      - {% endif %}

      {{ title3 }}

      - -
        - {% for doc in section_docs %} -
      • - {{ doc.obj.title|escape }} ({{ doc.obj.intended_std_level }}) -
        {{doc.obj.canonical_name}} - {% with doc.obj.rfc_number as rfc_number %} - {% if rfc_number %} - [txt] - {% else %} - [txt] - {% endif %} - {% endwith %} -
        Token: {{ doc.obj.ad.plain_name|escape }} ({{doc.obj.area_acronym}} area) - {% if doc.obj.note %} -
        Note: {{ doc.obj.note|linebreaksbr }} - {% endif %} - {% for ipr in doc.obj.ipr %} - {% ifequal ipr.ipr.status 1 %} -
        IPR: {{ ipr.ipr.title|escape }} - {% endifequal %} - {% endfor %} - {% if doc.obj.active_ballot %} -
        Discusses/comments [ballot]: - - {% endif %} - -

        Telechat:

        -
          -
        • ...
        • -
        • ...
        • -
        • ...
        • -
        • ...
        • -
        • ...
        • -
        + {% include "iesg/scribe_doc_ballot.html" %}
      • -{% empty %} -
      • (none)
      • -{% endfor %} -
      diff --git a/ietf/templates/iesg/scribe_doc2.html b/ietf/templates/iesg/scribe_doc2.html deleted file mode 100644 index a33ffd316..000000000 --- a/ietf/templates/iesg/scribe_doc2.html +++ /dev/null @@ -1,57 +0,0 @@ -{% comment %}{% endcomment %}{% comment %} -Some parts Copyright (c) 2009 The IETF Trust, all rights reserved. -{% endcomment %} -{% load ietf_filters %} - - -

      {{ doc.obj.name }}

      -{% autoescape off %} -{% if doc.obj.active_ballot %} - -{% endif%} -{% endautoescape %} \ No newline at end of file diff --git a/ietf/templates/iesg/scribe_doc_ballot.html b/ietf/templates/iesg/scribe_doc_ballot.html new file mode 100644 index 000000000..f00f67f93 --- /dev/null +++ b/ietf/templates/iesg/scribe_doc_ballot.html @@ -0,0 +1,33 @@ + {% with doc.active_ballot as ballot %} + {% if ballot %} +
      Discusses/comments [ballot]: + + {% endif %} + {% endwith %} + +

      Telechat:

      + +
        +
      • ...
      • +
      • ...
      • +
      • ...
      • +
      • ...
      • +
      • ...
      • +
      \ No newline at end of file diff --git a/ietf/templates/iesg/scribe_template.html b/ietf/templates/iesg/scribe_template.html index 78c97dd1b..980089927 100644 --- a/ietf/templates/iesg/scribe_template.html +++ b/ietf/templates/iesg/scribe_template.html @@ -41,40 +41,50 @@ Some parts Copyright (c) 2009 The IETF Trust, all rights reserved. {% load ietf_filters %}{% filter compress_empty_lines %} -

      Scribe template for IESG Narrative Minutes, {{date}}

      +

      Scribe template for IESG Narrative Minutes, {{ date }}

      -{% with "iesg/scribe_doc.html" as doc_template %} -{% with "iesg/scribe_conflict_doc.html" as doc_conflict_template %} -{% include "iesg/agenda_outline_23.html" %} -{% endwith %} -{% endwith %} +{% for num, section in sections %} +

      {{ num }}{% if num|sectionlevel == 1 %}.{% endif %} {{ section.title|safe }}

      + + {% if "docs" in section %} +
        {% for doc in section.docs %} +{% if doc.type_id == "draft" or doc.type_id == "statchg" %}{% include "iesg/scribe_doc.html" %}{% endif %} +{% if doc.type_id == "conflrev" %}{% include "iesg/scribe_conflict_doc.html" %}{% endif %} + {% empty %} +
      • (none)
      • {% endfor %} +
      + {% endif %} +{% endfor %}

      Appendix: Snapshot of discusses/comments

      (at {% now "Y-m-d H:i:s T" %})

      -{% for doc in docs.s211 %}{% include "iesg/scribe_doc2.html" %}{%endfor%} -{% for doc in docs.s212 %}{% include "iesg/scribe_doc2.html" %}{%endfor%} -{% for doc in docs.s213 %}{% include "iesg/scribe_doc2.html" %}{%endfor%} -{% for doc in docs.s221 %}{% include "iesg/scribe_doc2.html" %}{%endfor%} -{% for doc in docs.s222 %}{% include "iesg/scribe_doc2.html" %}{%endfor%} -{% for doc in docs.s223 %}{% include "iesg/scribe_doc2.html" %}{%endfor%} -{% for doc in docs.s231 %}{% include "iesg/scribe_doc2.html" %}{%endfor%} -{% for doc in docs.s232 %}{% include "iesg/scribe_doc2.html" %}{%endfor%} -{% for doc in docs.s233 %}{% include "iesg/scribe_doc2.html" %}{%endfor%} -{% for doc in docs.s311 %}{% include "iesg/scribe_doc2.html" %}{%endfor%} -{% for doc in docs.s312 %}{% include "iesg/scribe_doc2.html" %}{%endfor%} -{% for doc in docs.s313 %}{% include "iesg/scribe_doc2.html" %}{%endfor%} -{% for doc in docs.s321 %}{% include "iesg/scribe_doc2.html" %}{%endfor%} -{% for doc in docs.s322 %}{% include "iesg/scribe_doc2.html" %}{%endfor%} -{% for doc in docs.s323 %}{% include "iesg/scribe_doc2.html" %}{%endfor%} -{% for doc in docs.s331 %}{% include "iesg/scribe_doc2.html" %}{%endfor%} -{% for doc in docs.s332 %}{% include "iesg/scribe_doc2.html" %}{%endfor%} -{% for doc in docs.s333 %}{% include "iesg/scribe_doc2.html" %}{%endfor%} -{% for doc in docs.s341 %}{% include "iesg/scribe_doc2.html" %}{%endfor%} -{% for doc in docs.s342 %}{% include "iesg/scribe_doc2.html" %}{%endfor%} -{% for doc in docs.s343 %}{% include "iesg/scribe_doc2.html" %}{%endfor%} +{% for doc in appendix_docs %} + +

      {{ doc.name }}

      + + {% with doc.active_ballot as ballot %} + {% if ballot %} + + {% endif %} + {% endwith %} + +{% endfor %} {% endfilter %} diff --git a/ietf/templates/iesg/working_group_actions.html b/ietf/templates/iesg/working_group_actions.html deleted file mode 100644 index 7ab3e7783..000000000 --- a/ietf/templates/iesg/working_group_actions.html +++ /dev/null @@ -1,68 +0,0 @@ -{% extends "base.html" %} - -{% block title %}Working Group Actions{% endblock %} - -{% block morecss %} -.working-group-action .name, -.working-group-action .edit { - padding-left: 10px; -} -.working-group-action form input { - margin-left: 10px; -} -{% endblock %} - -{% block content %} -{% load ietf_filters %} -

      Working Group Actions

      - -

      These are the submitted WG descriptions and milestones for all -Proposed Working Groups and recharter submissions, along with -whatever status information is available.

      - -

      NOTE: Explicit direction by the AD is required to add the group to -an IESG Telechat agenda.

      - -

      Current Items

      - - -{% for wga in current_items %} - - - - {% if user|in_group:"Secretariat" %} - - {% endif %} - -{% endfor %} -
      {{ wga.status_date|date:"Y, M d" }}{{ wga.group_acronym.name }} ({{ wga.group_acronym.acronym }}) -
      - Edit - -
      -
      - -

      Possible Items

      - - -{% for wga in possible_items %} - - - - {% if user|in_group:"Secretariat" %} - - {% endif %} - -{% endfor %} -
      {{ wga.status_date|date:"Y, M d" }}{{ wga.name }} ({{ wga.acronym }}) -
      - - - -
      -
      -{% endblock %} - -{% block content_end %} - -{% endblock %} diff --git a/ietf/templates/ietfworkflows/annotation_tags_updated_mail.txt b/ietf/templates/ietfworkflows/annotation_tags_updated_mail.txt deleted file mode 100644 index dafe2376b..000000000 --- a/ietf/templates/ietfworkflows/annotation_tags_updated_mail.txt +++ /dev/null @@ -1,11 +0,0 @@ -{% autoescape off %} -The annotation tags of document {{ doc }} have been updated. See more information below. - -Annotation tags set: {{ entry.setted }} -Annotation tags reset: {{ entry.unsetted }} -Date of the change: {{ entry.change_date }} -Author of the change: {{ entry.person }} - -Comment: -{{ entry.comment }} -{% endautoescape %} diff --git a/ietf/templates/ietfworkflows/edit_actions.html b/ietf/templates/ietfworkflows/edit_actions.html deleted file mode 100644 index 214905233..000000000 --- a/ietf/templates/ietfworkflows/edit_actions.html +++ /dev/null @@ -1,6 +0,0 @@ -
      - {% for action_name, url in actions %} - {% if not forloop.first %} | {% endif%} {{ action_name }} - {% endfor %} -
      - diff --git a/ietf/templates/ietfworkflows/noworkflow_state_form.html b/ietf/templates/ietfworkflows/noworkflow_state_form.html deleted file mode 100644 index d5e3f0372..000000000 --- a/ietf/templates/ietfworkflows/noworkflow_state_form.html +++ /dev/null @@ -1,23 +0,0 @@ -
      - - - - - -
      Adopt this draft in your group
      -
      - {{ form.comment.errors }} - Comment:
      - -
      -
      - {{ form.weeks.errors }} - Estimated time in 'Call for Adoption by WG/RG Issued': (in weeks) -
      -
      - Adopt in Group: {{ form.group }} - {{ form.group.errors }} -
      - -
      -
      diff --git a/ietf/templates/ietfworkflows/state_edit.html b/ietf/templates/ietfworkflows/state_edit.html deleted file mode 100644 index 5cef5eb00..000000000 --- a/ietf/templates/ietfworkflows/state_edit.html +++ /dev/null @@ -1,51 +0,0 @@ -{% extends "base.html" %} -{% load ietf_streams %} - -{% block morecss %} -table.state-history p { margin: 0px; } -table.edit-form ul { padding: 0px; list-style-type: none; margin: 0px; margin-bottom: 2em; } -table.edit-form ul li, table.edit-form div.free-change { padding: 0px 2em; } -table.edit-form ul li.evenrow { background-color: #edf5ff; } -table.edit-form textarea { width: 95%; height: 120px; } -table.edit-form span.required { color: red; } -table.edit-form ul.errorlist { border-width: 0px; padding: 0px; margin: 0px;} -table.edit-form ul.errorlist li { color: red; margin: 0px; padding: 0px;} -table.edit-form div.field { margin: 1em 0px; } -table.edit-form div.submit-row { margin: 0px 2em; } -table.edit-form div.error { border: 1px solid red; background-color: #ffeebb; padding: 5px 10px; } -table.edit-form-tags tr { vertical-align: top; } -table.edit-form-tags textarea { height: 200px; } -table.edit-form-tags ul { border-width: 0px; padding: 0px 2em; } -table.edit-form-tags ul li { padding: 0px; } - -#new-edit-form { clear:both; padding-top: 1em; } -#new-edit-form th { padding-left:0; max-width: 8em;} -#new-edit-form #id_comment { width: 30em; height: 5em; } -#new-edit-form #id_weeks { width: 2em;} -#new-edit-form ul {list-style-type: none; padding-left:0; margin-top:0; margin-bottom:0; } -.rec-state-header { float:left; padding-left:2px; padding-right:.5em; } -.rec-statelist {list-style-type: none; padding-left:0; margin-top:0; margin-bottom:0; } -.rec-state { float:left; padding-right:.5em; } - -{% endblock morecss %} - -{% block title %}Change state for {{ draft }}{% endblock %} - -{% block content %} -

      Change state for {{ draft }}

      - -{% if state and state.slug == "wg-doc" and not milestones %} -

      This document is not part of any milestone. You may wish to add it to one.

      -{% endif %} - -{% if state and state.slug == "sub-pub" and milestones %} -

      This document is part of {% if milestones|length > 1 %}{{ milestones|length }} -milestones{% else %}a milestone{% endif %}. Now that the draft is -submitted to IESG for publication, you may wish to -update the -milestone{{ milestones|pluralize }}.

      -{% endif %} - -{{ form }} - -{% endblock %} diff --git a/ietf/templates/ietfworkflows/state_form.html b/ietf/templates/ietfworkflows/state_form.html deleted file mode 100644 index a96b20f3e..000000000 --- a/ietf/templates/ietfworkflows/state_form.html +++ /dev/null @@ -1,32 +0,0 @@ -
      - -
      - {% with form.get_next_states as next_states %} - {% if next_states %} - Recommended next state{{next_states|pluralize}}: -
        - {% for state in next_states %} -
      • '{{ state.name }}'{% if not forloop.last %}, {% endif %}
      • - {% endfor %} -
      - {% endif %} - {% endwith %} -
      - - - {% for field in form.visible_fields %} - - - - - {% endfor %} -
      {{ field.label_tag }}:{{ field }} - {% if field.help_text %}
      {{ field.help_text }}
      {% endif %} - - {{ field.errors }} -
      -
      - - -
      -
      diff --git a/ietf/templates/ietfworkflows/state_updated_mail.txt b/ietf/templates/ietfworkflows/state_updated_mail.txt deleted file mode 100644 index 7eb828edd..000000000 --- a/ietf/templates/ietfworkflows/state_updated_mail.txt +++ /dev/null @@ -1,12 +0,0 @@ -{% autoescape off %} -The state of document {{ doc }} has been updated. See more information below. - -Previous state: {{ entry.from_state }} -Current state: {{ entry.to_state }} -Transition date: {{ entry.transition_date }} -Author of the change: {{ entry.person }} -{% if entry.set_tags %}Annotation tags set: {{ entry.set_tags }}{% endif %} -{% if entry.reset_tags %}Annotation tags reset: {{ entry.reset_tags }}{% endif %} -Comment: -{{ entry.comment }} -{% endautoescape %} diff --git a/ietf/templates/ietfworkflows/stream_delegates.html b/ietf/templates/ietfworkflows/stream_delegates.html deleted file mode 100644 index ca77c9575..000000000 --- a/ietf/templates/ietfworkflows/stream_delegates.html +++ /dev/null @@ -1,43 +0,0 @@ -{% extends "base.html" %} -{% load ietf_streams ietf_filters %} - -{% block title %}Manage delegates for {{ stream.name }} stream{% endblock %} - -{% block content %} -

      Stream: {{ stream.name }}

      - -{% if chairs %} -

      {{ stream.name }} stream chairs

      - - -{% for chair in chairs %} - -{% endfor %} -
      NameEmail
      {{ chair }}{{ chair.email.0 }} <{{ chair.email.1 }}>
      -{% endif %} - -

      {{ stream.name }} stream delegates

      -
      -{% if delegates %} - - -{% for delegate in delegates %} - -{% endfor %} -
      NameEmail
      {{ delegate }}{{ delegate.email.0 }} <{{ delegate.email.1 }}>
      -

      - -

      -{% else %} -

      -No delegates for {{ stream.name }} stream assigned. -

      -{% endif %} -

      -Enter a valid e-mail address to add a new delegate. -

      -{% if form.errors.email %}{{ form.errors.email }}{% endif %} -{{ form.email }} - -
      -{% endblock %} diff --git a/ietf/templates/ietfworkflows/stream_form.html b/ietf/templates/ietfworkflows/stream_form.html deleted file mode 100644 index 268f9ecef..000000000 --- a/ietf/templates/ietfworkflows/stream_form.html +++ /dev/null @@ -1,22 +0,0 @@ -
      - - - - - - - - -
      Select the new stream
      -
      - {{ form.comment.errors }} - Comment: *
      - -
      -
      -
      - {{ form.stream.errors }} - {{ form.stream }} -
      -
      -
      diff --git a/ietf/templates/ietfworkflows/stream_history.html b/ietf/templates/ietfworkflows/stream_history.html deleted file mode 100644 index ae4fb7b19..000000000 --- a/ietf/templates/ietfworkflows/stream_history.html +++ /dev/null @@ -1,44 +0,0 @@ -{% load ietf_streams %} - - - - - -
      - {% if workflow %} -
        - {% for tag in tags %} - {{ tag }} - {% endfor %} -
      - {% endif %} -
      -
      - {% if stream %} -

      - {{ stream|default:"Without stream" }}{% if stream.with_groups and streamed.group %} :: {{ streamed.group|default:"" }}{% endif %} -

      -

      Current state: {{ state|default:"None" }}

      - {% else %} -

      Without stream

      - {% endif %} -
      - - {% if history %} -
      - {% if show_more %} -

      Viewing the last 20 entries. Show full log.

      - {% endif %} - {% for entry in history %} - {% workflow_history_entry entry %} - {% endfor %} - {% if show_more %} -

      Viewing the last 20 entries. Show full log.

      - {% endif %} -
      - {% else %} -

      - There is no stream history for this document. -

      - {% endif %} -
      diff --git a/ietf/templates/ietfworkflows/stream_state.html b/ietf/templates/ietfworkflows/stream_state.html deleted file mode 100644 index d06c4ac1e..000000000 --- a/ietf/templates/ietfworkflows/stream_state.html +++ /dev/null @@ -1,11 +0,0 @@ -{% if draft %} -
      -
      -{% if stream %} -{% if state %}{{ state.name }}{% else %}{{ stream }}{% endif %} -{% if milestones %}{% for m in milestones %}{{ m.due|date:"M Y" }}{% endfor %}{% endif %} -{% else %} - No stream assigned -{% endif %} -
      -{% endif %} diff --git a/ietf/templates/ietfworkflows/stream_state_redesign.html b/ietf/templates/ietfworkflows/stream_state_redesign.html deleted file mode 100644 index 0c334f865..000000000 --- a/ietf/templates/ietfworkflows/stream_state_redesign.html +++ /dev/null @@ -1,10 +0,0 @@ -{% if doc %} -
      -
      -{% if stream %} -{% if state %}{{ state.name }}{% else %}{{ stream }}{% endif %} -{% else %} - No stream assigned -{% endif %} -
      -{% endif %} diff --git a/ietf/templates/ietfworkflows/stream_updated_mail.txt b/ietf/templates/ietfworkflows/stream_updated_mail.txt deleted file mode 100644 index b98640b88..000000000 --- a/ietf/templates/ietfworkflows/stream_updated_mail.txt +++ /dev/null @@ -1,11 +0,0 @@ -{% autoescape off %} -The stream of document {{ doc }} has been updated. See more information below. - -Previous stream: {{ entry.from_stream }} -Current stream: {{ entry.to_stream }} -Transition date: {{ entry.transition_date }} -Author of the change: {{ entry.person }} - -Comment: -{{ entry.comment }} -{% endautoescape %} diff --git a/ietf/templates/ietfworkflows/tags_form.html b/ietf/templates/ietfworkflows/tags_form.html deleted file mode 100644 index e3388a868..000000000 --- a/ietf/templates/ietfworkflows/tags_form.html +++ /dev/null @@ -1,22 +0,0 @@ -
      - - - - - - -
      1. Input information about change2. Select annotation tags
      -
      - {{ form.errors.comment }} - Comment: *
      - -
      -
      -
      - {{ form.tags }} -
      -
      - -
      -
      -
      diff --git a/ietf/templates/ietfworkflows/workflow_history_entry.html b/ietf/templates/ietfworkflows/workflow_history_entry.html deleted file mode 100644 index 3f30673f2..000000000 --- a/ietf/templates/ietfworkflows/workflow_history_entry.html +++ /dev/null @@ -1,12 +0,0 @@ -
      -
      - - {{ entry.person }} -
      -
      - {{ entry.describe_change|safe|linebreaks }} -
      -
      - {{ entry.comment }} -
      - diff --git a/ietf/templates/ipr/details.html b/ietf/templates/ipr/details.html index f63ae8181..c657da35f 100644 --- a/ietf/templates/ipr/details.html +++ b/ietf/templates/ipr/details.html @@ -21,8 +21,10 @@ table.ipr { margin-top: 1em; } {% endblock %} {% block content %} + {% load ietf_filters %} + {% if section_list.title %} -

      {{ ipr.title|escape }}

      +

      {{ ipr.title }}

      {% endif %} @@ -59,15 +61,15 @@ Template for {{ section_list.disclosure_type }}" where the submitter provided {% for item in ipr.updates.all %}

      This IPR disclosure updates IPR disclosure ID #{{ item.updated.ipr_id }}, - {% ifequal item.updated.status 0 %} - "{{ item.updated.title|escape }}". + {% if item.updated.status == 0 %} + "{{ item.updated.title }}". {% else %} - {% ifequal item.updated.status 1 %} - "{{ item.updated.title|escape }}". + {% if item.updated.status == 1 %} + "{{ item.updated.title }}". {% else %} - "{{ item.updated.title|escape }}", which was removed at the request of the submitter. - {% endifequal %} - {% endifequal %} + "{{ item.updated.title }}", which was removed at the request of the submitter. + {% endif %} + {% endif %}

      {% endfor %} @@ -75,11 +77,11 @@ Template for {{ section_list.disclosure_type }}" where the submitter provided {% if item.processed == 1 and item.ipr.status != 2 %}

      This IPR disclosure has been updated by IPR disclosure ID #{{ item.ipr.ipr_id }}, - {% ifequal item.status_to_be 1 %} - "{{ item.ipr.title|escape }}". + {% if item.status_to_be == 1 %} + "{{ item.ipr.title }}". {% else %} - "{{ item.ipr.title|escape }}", which was removed at the request of the submitter. - {% endifequal %} + "{{ item.ipr.title }}", which was removed at the request of the submitter. + {% endif %}

      {% endif %} {% endfor %} @@ -103,7 +105,7 @@ Template for {{ section_list.disclosure_type }}" where the submitter provided - Legal Name: {{ ipr.legal_name|escape }} + Legal Name: {{ ipr.legal_name }} {% endif %} @@ -115,14 +117,14 @@ Template for {{ section_list.disclosure_type }}" where the submitter provided Patent Holder's Contact for License Application - Name: {{ ipr.holder_contact.name|escape }} - Title: {{ ipr.holder_contact.title|escape }} - Department: {{ ipr.holder_contact.department|escape }} - Address1: {{ ipr.holder_contact.address1|escape }} - Address2: {{ ipr.holder_contact.address2|escape }} - Telephone: {{ ipr.holder_contact.telephone|escape }} - Fax: {{ ipr.holder_contact.fax|escape }} - Email: {{ ipr.holder_contact.email|escape }} + Name: {{ ipr.holder_contact.name }} + Title: {{ ipr.holder_contact.title }} + Department: {{ ipr.holder_contact.department }} + Address1: {{ ipr.holder_contact.address1 }} + Address2: {{ ipr.holder_contact.address2 }} + Telephone: {{ ipr.holder_contact.telephone }} + Fax: {{ ipr.holder_contact.fax }} + Email: {{ ipr.holder_contact.email }} {% endif %} @@ -136,14 +138,14 @@ Template for {{ section_list.disclosure_type }}" where the submitter provided {% if ipr.ietf_contact.name %} - Name: {{ ipr.ietf_contact.name|escape }} - Title: {{ ipr.ietf_contact.title|escape }} - Department: {{ ipr.ietf_contact.department|escape }} - Address1: {{ ipr.ietf_contact.address1|escape }} - Address2: {{ ipr.ietf_contact.address2|escape }} - Telephone: {{ ipr.ietf_contact.telephone|escape }} - Fax: {{ ipr.ietf_contact.fax|escape }} - Email: {{ ipr.ietf_contact.email|escape }} + Name: {{ ipr.ietf_contact.name }} + Title: {{ ipr.ietf_contact.title }} + Department: {{ ipr.ietf_contact.department }} + Address1: {{ ipr.ietf_contact.address1 }} + Address2: {{ ipr.ietf_contact.address2 }} + Telephone: {{ ipr.ietf_contact.telephone }} + Fax: {{ ipr.ietf_contact.fax }} + Email: {{ ipr.ietf_contact.email }} {% else %} No information submitted {% endif %} @@ -162,15 +164,15 @@ Template for {{ section_list.disclosure_type }}" where the submitter provided {% if ipr.rfclist %} RFC Numbers:{{ ipr.rfclist }} {% else %} - {% for doc in ipr.rfcs.all %} - RFC {{ doc.document.rfc_number }}:"{{ doc.document.title }}" + {% for iprdocalias in ipr.rfcs %} + {{ iprdocalias.formatted_name|rfcspace }}:"{{ iprdocalias.doc_alias.document.title }}" {% endfor %} {% endif %} {% if ipr.draftlist %} I-D Filenames (draft-...):{{ ipr.draftlist }} {% else %} - {% for doc in ipr.drafts.all %} - Internet-Draft:"{{ doc.document.title }}"
      ({{ doc.document.filename }}{% if doc.revision %}-{{ doc.revision }}{% endif %}) + {% for iprdocalias in ipr.drafts %} + Internet-Draft:"{{ iprdocalias.doc_alias.document.title }}"
      ({{ iprdocalias.formatted_name }}) {% endfor %} {% endif %} {% if ipr.other_designations %} @@ -200,7 +202,7 @@ Template for {{ section_list.disclosure_type }}" where the submitter provided Date(s) granted or applied for: {{ ipr.date_applied }} Country: {{ ipr.country }} - Additional Notes:{{ ipr.notes|escape|linebreaks }} + Additional Notes:{{ ipr.notes|linebreaks }} B. Does this disclosure relate to an unpublished pending patent application?: @@ -228,7 +230,7 @@ Template for {{ section_list.disclosure_type }}" where the submitter provided {% if ipr.document_sections %} - {{ ipr.document_sections|escape|linebreaks }} + {{ ipr.document_sections|linebreaks }} {% else %} No information submitted {% endif %} @@ -283,7 +285,7 @@ Template for {{ section_list.disclosure_type }}" where the submitter provided {% if ipr.comments %} - {{ ipr.comments|escape|linebreaks }} + {{ ipr.comments|linebreaks }} {% else %} No information submitted {% endif %} @@ -353,14 +355,14 @@ Template for {{ section_list.disclosure_type }}" where the submitter provided {% endif %} {% endif %} - Name: {{ ipr.submitter.name|escape }} - Title: {{ ipr.submitter.title|escape }} - Department: {{ ipr.submitter.department|escape }} - Address1: {{ ipr.submitter.address1|escape }} - Address2: {{ ipr.submitter.address2|escape }} - Telephone: {{ ipr.submitter.telephone|escape }} - Fax: {{ ipr.submitter.fax|escape }} - Email: {{ ipr.submitter.email|escape }} + Name: {{ ipr.submitter.name }} + Title: {{ ipr.submitter.title }} + Department: {{ ipr.submitter.department }} + Address1: {{ ipr.submitter.address1 }} + Address2: {{ ipr.submitter.address2 }} + Telephone: {{ ipr.submitter.telephone }} + Fax: {{ ipr.submitter.fax }} + Email: {{ ipr.submitter.email }} {% else %} No information submitted {% endif %} @@ -377,7 +379,7 @@ Template for {{ section_list.disclosure_type }}" where the submitter provided {% if ipr.other_notes %} - {{ ipr.other_notes|escape|linebreaks }} + {{ ipr.other_notes|linebreaks }} {% else %} No information submitted {% endif %} diff --git a/ietf/templates/ipr/drafts.html b/ietf/templates/ipr/drafts.html deleted file mode 100644 index 07ca916ee..000000000 --- a/ietf/templates/ipr/drafts.html +++ /dev/null @@ -1,3 +0,0 @@ -# Machine-readable list of ipr disclosures by draft name -{% for doc in docs %}{{doc.name}}{% for num in doc.iprs %} {{ num }}{% endfor %} -{% endfor %} \ No newline at end of file diff --git a/ietf/templates/ipr/list.html b/ietf/templates/ipr/list.html index 7b9ebc6d2..a96f2bfa7 100644 --- a/ietf/templates/ipr/list.html +++ b/ietf/templates/ipr/list.html @@ -12,7 +12,7 @@ The IETF takes no position regarding the validity or scope of any intellectual property rights or other rights that might be claimed to pertain to the implementation or use of the technology described in any IETF documents or the extent to which any license under such rights might or might not be available; nor does it represent that it has made any independent effort to identify any such rights.

      -

      Click here to submit an IPR disclosure

      +

      Click here to submit an IPR disclosure

      Search the IPR Disclosures diff --git a/ietf/templates/ipr/list_item.html b/ietf/templates/ipr/list_item.html index 65d82183c..4f916ff68 100644 --- a/ietf/templates/ipr/list_item.html +++ b/ietf/templates/ipr/list_item.html @@ -3,17 +3,17 @@ {{ ipr.submitted_date }} {{ ipr.ipr_id }} - {% ifequal ipr.status 1 %} + {% if ipr.status == 1 %} {{ ipr.title|escape }} {% else %} {{ ipr.title|escape }}
      This IPR disclosure was removed at the request of the submitter. - {% endifequal %} + {% endif %}
      {% for item in ipr.updates.all %} - {% ifequal item.updated.status 1 %} + {% if item.updated.status == 1 %} Updates ID #{{ item.updated.ipr_id }}.
      - {% endifequal %} + {% endif %} {% endfor %} {% for item in ipr.updated_by.all %} {% if item.processed == 1 and item.ipr.status != 2 %} @@ -22,7 +22,7 @@ {% endfor %} - {% ifequal ipr.status 1 %} + {% if ipr.status == 1 %} {% if ipr.legacy_title_1 %} @@ -43,4 +43,4 @@ {% endif %} - {% endifequal %} + {% endif %} diff --git a/ietf/templates/ipr/removed.html b/ietf/templates/ipr/removed.html index 53a31604d..64dd488a0 100644 --- a/ietf/templates/ipr/removed.html +++ b/ietf/templates/ipr/removed.html @@ -1,9 +1,9 @@ {% extends "base.html" %} {# Copyright The IETF Trust 2009, All Rights Reserved #} -{% block title %}IPR Details - {{ ipr.title|escape }}{% endblock %} +{% block title %}IPR Details - {{ ipr.title }}{% endblock %} {% block content %} -

      {{ ipr.title|escape }}

      +

      {{ ipr.title }}

      This IPR disclosure was removed at the submitter's request. diff --git a/ietf/templates/ipr/search.html b/ietf/templates/ipr/search.html index 2693e5e89..29fdff2a1 100644 --- a/ietf/templates/ipr/search.html +++ b/ietf/templates/ipr/search.html @@ -11,92 +11,92 @@ label { float:left; width: 200px; }

      IPR Search

      Document Search

      -
      - + + + + + +
      - - - - + -
      - - - - -
      + function check_numeric(val) { + if (IsNumeric(val)) { + return true; + } else { + alert ("Please enter numerics only"); + return false; + } + return false; + } + // --> + +
      + + + + +

      Keyword Search

      -
      - - - - -
      -
      - - - - -
      - * 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. +
      + + + + +
      +
      + + + + +
      -
      - - - - -
      -
      - - - - -
      -
      - - - - -
      + * 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. + +
      + + + + +
      +
      + + + + +
      +
      + + + + +

      Back to IPR Disclosure Page

      diff --git a/ietf/templates/ipr/search_doc_list.html b/ietf/templates/ipr/search_doc_list.html index df3f64b98..c117740c8 100644 --- a/ietf/templates/ipr/search_doc_list.html +++ b/ietf/templates/ipr/search_doc_list.html @@ -8,7 +8,7 @@

      Please select one of following I-Ds

      {% endblock %} diff --git a/ietf/templates/ipr/search_doc_result.html b/ietf/templates/ipr/search_doc_result.html index 2cef0e467..8e636289e 100644 --- a/ietf/templates/ipr/search_doc_result.html +++ b/ietf/templates/ipr/search_doc_result.html @@ -18,8 +18,8 @@ - Search result on {{ doc.name|rfcspace|lstrip:"0"|rfcnospace }}, "{{ doc.document.title|escape }}"{% ifnotequal doc first %}{% if doc.related %}, that was {{ doc.relation|lower }} {{ doc.related.source|rfcspace|lstrip:"0"|rfcnospace }}, "{{ doc.related.source.title }}"{% endif %} - {% endifnotequal %} + Search result on {{ doc.name|rfcspace|lstrip:"0"|rfcnospace }}, "{{ doc.document.title|escape }}"{% 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 %} {% if doc.iprs %} @@ -35,7 +35,7 @@ No IPR disclosures have been submitted directly on {{ doc.name|rfcspace|lstrip:"0" }}{% if iprs %}, - but there are disclosures on {% ifequal docs|length 2 %}a related document{% else %}related documents{% endifequal %}, listed on this page{% endif %}. + but there are disclosures on {% if docs|length == 2 %}a related document{% else %}related documents{% endif %}, listed on this page{% endif %}.
      diff --git a/ietf/templates/ipr/search_doctitle_result.html b/ietf/templates/ipr/search_doctitle_result.html index 66ea47d6b..988545d17 100644 --- a/ietf/templates/ipr/search_doctitle_result.html +++ b/ietf/templates/ipr/search_doctitle_result.html @@ -19,7 +19,7 @@ - IPR that is related to {{ alias.name|rfcspace|lstrip:"0"|rfcnospace }}, "{{ alias.document.title|escape }}"{% if alias.related %}, that was {{ alias.relation|lower }} {{ alias.related.source.name|rfcspace|lstrip:"0"|rfcnospace }}, "{{ alias.related.source.title }}"{% endif %} + IPR that is related to {{ 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 %} @@ -31,10 +31,10 @@ {% for item in ipr.updated_by.all %} {% if item.processed == 1 and item.ipr.status != 2 %} - IPR disclosure ID# {{ item.ipr.ipr_id }} "{{ item.ipr.title|escape }}" Updates + IPR disclosure ID# {{ item.ipr.ipr_id }} "{{ item.ipr.title }}" Updates {% endif %} {% endfor %} - "{{ ipr.title|escape }}" + "{{ ipr.title }}" {% endfor %} diff --git a/ietf/templates/ipr/search_result.html b/ietf/templates/ipr/search_result.html index 7ca31e583..9345e2e5b 100644 --- a/ietf/templates/ipr/search_result.html +++ b/ietf/templates/ipr/search_result.html @@ -5,6 +5,7 @@ {% block doctype %}{% endblock %} {% block title %}IPR Search Result{% endblock %} {% block content %} +{% load ietf_filters %}

      IPR Disclosures

      {% block search_result %} @@ -23,36 +24,38 @@ - + {% for item in ipr.updates.all %} - {% ifnotequal item ipr %} + {% if item != ipr %} - {% endifnotequal %} + {% endif %} {% endfor %} {% endfor %} diff --git a/ietf/templates/ipr/search_wg_result.html b/ietf/templates/ipr/search_wg_result.html index 527428b6d..a49f86313 100644 --- a/ietf/templates/ipr/search_wg_result.html +++ b/ietf/templates/ipr/search_wg_result.html @@ -31,9 +31,9 @@ diff --git a/ietf/templates/liaisons/approval_detail.html b/ietf/templates/liaisons/approval_detail.html new file mode 100644 index 000000000..6b94c32e2 --- /dev/null +++ b/ietf/templates/liaisons/approval_detail.html @@ -0,0 +1,10 @@ +{% extends "liaisons/detail.html" %} +{# Copyright The IETF Trust 2007, All Rights Reserved #} + +{% block content %} +{{ block.super }} + + + + +{% endblock %} diff --git a/ietf/templates/liaisons/liaisondetail_approval_list.html b/ietf/templates/liaisons/approval_list.html similarity index 86% rename from ietf/templates/liaisons/liaisondetail_approval_list.html rename to ietf/templates/liaisons/approval_list.html index aba7092d4..0e5dba6d7 100644 --- a/ietf/templates/liaisons/liaisondetail_approval_list.html +++ b/ietf/templates/liaisons/approval_list.html @@ -1,4 +1,4 @@ -{% extends "liaisons/liaisondetail_list.html" %} +{% extends "liaisons/overview.html" %} {# Copyright The IETF Trust 2007, All Rights Reserved #} {% block title %}Pending Liaison Statements{% endblock %} diff --git a/ietf/templates/liaisons/detail.html b/ietf/templates/liaisons/detail.html new file mode 100644 index 000000000..007006e6f --- /dev/null +++ b/ietf/templates/liaisons/detail.html @@ -0,0 +1,122 @@ +{% extends "base.html" %} +{# Copyright The IETF Trust 2007, All Rights Reserved #} +{% load ietf_filters %} + +{% block title %}Liaison Statement: {% include 'liaisons/liaison_title.html' %}{% endblock %} + +{% block pagehead %} + + + +{% endblock %} + +{% block morecss %} +.ietf-liaison-details tr { vertical-align:top; } +{% endblock morecss %} + +{% block content %} +

      Liaison Statement: {% include 'liaisons/liaison_title.html' %}

      + +
      {% block intro_prefix %}IPR that was submitted by {{ q }}, and{% endblock %} - {% block related %} - {% if not ipr.docs %} - is not related to a specific IETF contribution. - {% else %} - is related to - {% for item in ipr.docs %} - {% ifequal item ipr.last_draft %} and {% endifequal %} - {{ item.document }}, "{{ item.document.title|escape }},"{% if item.document.related %}, {{ item.document.relation }} {{ item.document.related }}, "{{ item.document.related.title|escape }}"{% endif %} - {% endfor %} - {% endif %} - {% endblock %} + {% block related %} + {% with ipr.docs as iprdocaliases %} + {% if not iprdocaliases %} + is not related to a specific IETF contribution. + {% else %} + is related to + {% for item in iprdocaliases %} + {% if forloop.last and forloop.counter > 1 %}and{% endif %} + {{ item.formatted_name|rfcspace }}, "{{ item.doc_alias.document.title }}"{% if not forloop.last and forloop.counter > 1 %},{% endif %} + {% endfor %} + {% endif %} + {% endwith %} + {% endblock %} {% block intro_suffix %}{% endblock %}
      {{ ipr.submitted_date }}
    • ID # {{ ipr.ipr_id }}
    • "{{ ipr.title|escape }}""{{ ipr.title }}"
      {{ item.updated.submitted_date }}
    • ID # {{ item.updated.ipr_id }}
    • - IPR disclosure ID# {{ ipr.ipr_id }} "{{ ipr.title|escape }}" - Updates {{ item.updated.title|escape }} + IPR disclosure ID# {{ ipr.ipr_id }} "{{ ipr.title }}" + Updates {{ item.updated.title }}
    • ID # {{ ipr.ipr_id }}
    • {% for item in ipr.updates.all %} - {% ifequal item.updated.status 1 %} + {% if item.updated.status == 1 %} IPR disclosure ID# {{ item.updated.ipr_id }}, "{{ item.updated.title|escape }}" Updated by - {% endifequal %} + {% endif %} {% endfor %} "{{ ipr.title|escape }}"
      + + + + + + + + + + + + + +{% if liaison.from_contact %} + + + + + + + + + + + + + + + + + + + + {% if liaison.deadline %} + + + + + {% endif %} +{% endif %} + +{% if relations %} + + + + +{% endif %} + +{% if liaison.related_to %} +{% if liaison.related_to.approved or is_approving %} + + + + +{% endif %} +{% endif %} + + + + + + +{% if liaison.from_contact and liaison.body %} + + + + +{% endif %} +
      Submission Date:{{ liaison.submitted|date:"Y-m-d" }}
      From:{{ liaison.from_name }} + {% if liaison.from_contact %}({{ liaison.from_contact.person }}){% endif %} +
      To: + {% if liaison.from_contact %} + {{ liaison.to_name }} ({{ liaison.to_contact|parse_email_list }}) + {% else %} + {{ liaison.to_name|urlize }} + {% endif %} +
      Cc:{{ liaison.cc|parse_email_list|make_one_per_line|safe|linebreaksbr }}
      Response Contact:{{ liaison.response_contact|parse_email_list|make_one_per_line|safe|linebreaksbr }}
      Technical Contact:{{ liaison.technical_contact|parse_email_list|make_one_per_line|safe|linebreaksbr }}
      Purpose:{{ liaison.purpose.name }}
      Deadline:{{ liaison.deadline }} + {% if liaison.action_taken %}Action Taken{% else %}Action Needed{% endif %} + {% if can_take_care %} +
      + +
      + {% endif %} +
      Liaisons referring to this one: + {% for rel in relations %} + {% if rel.title %}{{ rel.title }}{% else %}Liaison #{{ rel.pk }}{% endif %}
      + {% endfor %} +
      Referenced liaison: + {% if liaison.related_to.title %}{{ liaison.related_to.title }}{% else %}Liaison #{{ liaison.related_to.pk }}{% endif %} +
      Attachments: + {% for doc in liaison.attachments.all %} + {{ doc.title }}{% if not forloop.last %}
      {% endif %} + {% empty %} + (none) + {% endfor %} +
      Body:
      {{ liaison.body|wordwrap:"71" }}
      + +{% if can_edit %} +

      Edit Liaison

      +{% endif %} + +{% endblock %} diff --git a/ietf/templates/liaisons/edit.html b/ietf/templates/liaisons/edit.html new file mode 100644 index 000000000..8286ebf34 --- /dev/null +++ b/ietf/templates/liaisons/edit.html @@ -0,0 +1,32 @@ +{% extends "base.html" %} +{# Copyright The IETF Trust 2007, All Rights Reserved #} +{% load ietf_filters %} +{% block title %}{% if liaison %}Edit liaison: {{ liaison }}{% else %}Send Liaison Statement{% endif %}{% endblock %} + +{% block pagehead %} + + +{% endblock %} + +{% block content %} +

      {% if liaison %}Edit liaison: {{ liaison }}{% else %}Send Liaison Statement{% endif %}

      + + + +{% if not liaison %} +
        +
      • If you wish to submit your liaison statement by e-mail, then please send it to statements@ietf.org
      • +
      • Fields marked with * are required. For detailed descriptions of the fields see Field help
      • +
      +{% endif %} + +{{ form }} + +{% endblock %} + +{% block js %} + + +{% endblock %} diff --git a/ietf/templates/liaisons/liaison_mail.txt b/ietf/templates/liaisons/liaison_mail.txt index a79a1a437..c9c2369da 100644 --- a/ietf/templates/liaisons/liaison_mail.txt +++ b/ietf/templates/liaisons/liaison_mail.txt @@ -1,19 +1,19 @@ {% load ietf_filters %}{% autoescape off %}Title: {{ liaison.title|clean_whitespace }} -Submission Date: {{ liaison.submitted_date }} +Submission Date: {{ liaison.submitted|date:"Y-m-d" }} URL of the IETF Web page: {{ url }} -{% if liaison.deadline_date %}Please reply by {{ liaison.deadline_date }}{% endif %} -From: {{ liaison.from_body }} ({{ liaison.person }} <{{ liaison.replyto|default:liaison.from_email }}>) -To: {{ liaison.to_body }} ({{ liaison.to_poc }}) -Cc: {{ liaison.cc1 }} -Reponse Contact: {{ liaison.response_contact }} +{% if liaison.deadline %}Please reply by {{ liaison.deadline }}{% endif %} +From: {{ liaison.from_name }} ({{ liaison.from_contact.person }} <{{ liaison.reply_to|default:liaison.from_contact.address }}>) +To: {{ liaison.to_name }} ({{ liaison.to_contact }}) +Cc: {{ liaison.cc }} +Response Contact: {{ liaison.response_contact }} Technical Contact: {{ liaison.technical_contact }} -Purpose: {% if liaison.purpose_text %}{{ liaison.purpose_text }}{% else %}{{ liaison.purpose }}{% endif %} +Purpose: {{ liaison.purpose.name }} {% if liaison.related_to %}Referenced liaison: {% if liaison.related_to.title %}{{ liaison.related_to.title }}{% else %}Liaison #{{ liaison.related_to.pk }}{% endif %} ({{ referenced_url }}){% endif %} Body: {{ liaison.body }} Attachments: -{% for file in liaison.uploads_set.all %} - {{ file.file_title }} - https://datatracker.ietf.org/documents/LIAISON/{{ file.filename }} +{% for doc in liaison.attachments.all %} + {{ doc.title }} + https://datatracker.ietf.org/documents/LIAISON/{{ doc.external_url }} {% empty %} No document has been attached {% endfor %}{% endautoescape %} diff --git a/ietf/templates/liaisons/liaison_mail_detail.html b/ietf/templates/liaisons/liaison_mail_detail.html deleted file mode 100644 index 43ad036ae..000000000 --- a/ietf/templates/liaisons/liaison_mail_detail.html +++ /dev/null @@ -1,31 +0,0 @@ -{% extends "base.html" %} -{# Copyright The IETF Trust 2007, All Rights Reserved #} -{% load ietf_filters %} -{% block title %}{{ liaison.title }}{% endblock %} - -{% block content %} -

      Simulated Mail for Liaison Statement

      - -

      -Demo version of this tool does NOT actually send the liaison statement to the recipients. -

      -

      -Rather, the actual email body (including mail header) is displayed below. -

      -

      -In production mode, you will not see this screen. -

      - -
      -From: {{ message.From }}
      -To: {{ message.To }}
      -Cc: {{ message.Cc }}
      -Bcc: {{ message.Bcc }}
      -Subject: {{ message.Subject }}
      -
      -{{ mail.body }}
      -
      - -Return to liaison list - -{% endblock %} diff --git a/ietf/templates/liaisons/liaison_main_management.html b/ietf/templates/liaisons/liaison_main_management.html deleted file mode 100644 index edc259a6f..000000000 --- a/ietf/templates/liaisons/liaison_main_management.html +++ /dev/null @@ -1,62 +0,0 @@ -{% extends "base.html" %} -{# Copyright The IETF Trust 2007, All Rights Reserved #} -{% load ietf_filters %} -{% block title %}Liaison Management{% endblock %} - -{% block content %} -

      Liaison Management

      - -{% if can_send_incoming or can_send_outgoing %} -
      -

      Add new liaison

      -
      -{% endif %} - -{% if to_aprove %} -
      -

      Liaisons that need your approval

      - {% for liaison in to_aprove %} - {{ liaison }} - {% endfor %} -
      -{% endif %} - -{% if to_edit %} -
      -

      Liaisons you can edit

      -{% for liaison in to_edit %} - -{{ liaison.submitted_date|date:"Y-m-d" }} -{{ liaison.from_body|escape }} - -{% if liaison.by_secretariat %} - {% if liaison.submitter_email %} - {{ liaison.submitter_name|escape }} - {% else %} - {{ liaison.submitter_name|escape }} - {% endif %} -{% else %} - {{ liaison.to_body|escape }} -{% endif %} - - -{% if liaison.by_secretariat %} - {% for file in liaison.uploads_set.all %} - {{ file.file_title|escape }}
      - {% endfor %} -{% else %} - {{ liaison.title|escape }} -{% endif %} - - -{% endfor %} - - - -
      -{% endif %} - -{% endblock %} diff --git a/ietf/templates/liaisons/liaison_table.html b/ietf/templates/liaisons/liaison_table.html new file mode 100644 index 000000000..60fc22f9a --- /dev/null +++ b/ietf/templates/liaisons/liaison_table.html @@ -0,0 +1,39 @@ +{% load ietf_filters %} + + + + + + + + + + +{% for liaison in liaisons %} + + + + + + + +{% endfor %} + +
      DateFromToDeadlineTitle
      {{ liaison.submitted|date:"Y-m-d" }}{{ liaison.from_name }} + {% if liaison.from_contact_id %} + {{ liaison.to_name }} + {% else %} + {{ liaison.to_name|strip_email }} + {% endif %} + + {{ liaison.deadline|default:"-"|date:"Y-m-d" }} + + {% if not liaison.from_contact_id %} + {% for doc in liaison.attachments.all %} + {{ doc.title }}
      + {% endfor %} + {% else %} + {{ liaison.title }} + {% endif %} + +
      diff --git a/ietf/templates/liaisons/liaison_title.html b/ietf/templates/liaisons/liaison_title.html index dbf83f37c..5556aaafa 100644 --- a/ietf/templates/liaisons/liaison_title.html +++ b/ietf/templates/liaisons/liaison_title.html @@ -1,5 +1,5 @@ -{% if object.by_secretariat %} -Liaison statement submitted by email from {{ object.from_body|escape }} to {{ object.submitter_name|escape }} on {{ object.submitted_date }} +{% load ietf_filters %}{% if not liaison.from_contact %} + Liaison statement submitted by email from {{ liaison.from_name }} to {{ liaison.to_name|strip_email }} on {{ liaison.submitted|date:"Y-m-d" }} {% else %} -{{ object.title }} + {{ liaison.title }} {% endif %} diff --git a/ietf/templates/liaisons/liaisondetail_approval_detail.html b/ietf/templates/liaisons/liaisondetail_approval_detail.html deleted file mode 100644 index 2391dc956..000000000 --- a/ietf/templates/liaisons/liaisondetail_approval_detail.html +++ /dev/null @@ -1,10 +0,0 @@ -{% extends "liaisons/liaisondetail_detail.html" %} -{# Copyright The IETF Trust 2007, All Rights Reserved #} - -{% block content %} -{{ block.super }} - -
      - -
      -{% endblock %} diff --git a/ietf/templates/liaisons/liaisondetail_detail.html b/ietf/templates/liaisons/liaisondetail_detail.html deleted file mode 100644 index cc151b62e..000000000 --- a/ietf/templates/liaisons/liaisondetail_detail.html +++ /dev/null @@ -1,110 +0,0 @@ -{% extends "base.html" %} -{# Copyright The IETF Trust 2007, All Rights Reserved #} -{% load ietf_filters %} -{% block title %}Liaison Statement: {% include 'liaisons/liaison_title.html' %}{% endblock %} - -{% block pagehead %} - - - -{% endblock %} - -{% block morecss %} -.ietf-liaison-details tr { vertical-align:top; } -{% endblock morecss %} - -{% block content %} -

      Liaison Statement: {% include 'liaisons/liaison_title.html' %}

      - - - - - - - - -{% endif %} - -{% if not object.by_secretariat %} - - - - - - - - - - - - -{% if object.deadline_date %} - - -{% if can_take_care %} - -{% else %} - -{% endif %} - -{% endif %} - -{% endif %} - -{% if relations %} - - - -{% endif %} - -{% if object.related_to %} - - - -{% endif %} - - - - - -{% if not object.by_secretariat and object.body %} - - -{% endif %} -
      Submission Date:{{ object.submitted_date }}
      From:{{ object.from_body }} ({{ object.person }})
      To: -{% if object.by_secretariat %} - {% if object.submitter_email %} - {{ object.submitter_name }} - {% else %} - {{ object.submitter_name }} - {% endif %} -{% else %} -{{ object.to_body }} ({{ object.to_poc|parse_email_list|safe }})
      Cc:{{ object.cc1|parse_email_list|make_one_per_line|safe|linebreaksbr }}
      Response Contact: -{{ object.response_contact|parse_email_list|make_one_per_line|safe|linebreaksbr }} -
      Technical Contact:{{ object.technical_contact|parse_email_list|make_one_per_line|safe|linebreaksbr }}
      Purpose:{% if object.purpose_text %}{{ object.purpose_text }}{% else %}{{ object.purpose }}{% endif %}
      Deadline:
      -{{ object.deadline_date }} -{% if object.action_taken %}Action Taken{% else %}Action Required{% endif %} - -
      {{ object.deadline_date }} -{% if object.action_taken %}Action Taken{% else %}Action Needed{% endif %} -
      Liaisons referring to this one: -{% for liaison in relations %} -{% if liaison.title %}{{ object.title }}{% else %}Liaison #{{ liaison.pk }}{% endif %}
      -{% endfor %} -
      Referenced liaison: -{% if object.related_to.title %}{{ object.related_to.title }}{% else %}Liaison #{{ object.related_to.pk }}{% endif %} -
      Attachments: -{% for file in object.uploads_set.all %} -{{ file.file_title }}{% if not forloop.last %}
      {% endif %} -{% empty %} -(none) -{% endfor %} -
      Body:
      {{ object.body|wordwrap:"71"|escape }}
      - -{% if can_edit %} -
      - -
      -{% endif %} - -{% endblock %} diff --git a/ietf/templates/liaisons/liaisondetail_edit.html b/ietf/templates/liaisons/liaisondetail_edit.html deleted file mode 100644 index 59757909b..000000000 --- a/ietf/templates/liaisons/liaisondetail_edit.html +++ /dev/null @@ -1,31 +0,0 @@ -{% extends "base.html" %} -{# Copyright The IETF Trust 2007, All Rights Reserved #} -{% load ietf_filters %} -{% block title %}{% if liaison %}Edit liaison: {{ liaison }}{% else %}Send Liaison Statement{% endif %}{% endblock %} - -{% block pagehead %} -{{ form.media }} -{% endblock %} - -{% block content %} -

      {% if liaison %}Edit liaison: {{ liaison }}{% else %}Send Liaison Statement{% endif %}

      - -
      -Your browser has Javascript disabled. Please enable javascript and reload the page. - -
      - -{% if not liaison %} -
        -
      • If you wish to submit your liaison statement by e-mail, then please send it to statements@ietf.org
      • -
      • Fields marked with * are required. For detailed descriptions of the fields see Field help
      • -
      -{% endif %} - -{{ form }} - -{% endblock %} diff --git a/ietf/templates/liaisons/liaisondetail_simple_list.html b/ietf/templates/liaisons/liaisondetail_simple_list.html deleted file mode 100644 index f93088f2a..000000000 --- a/ietf/templates/liaisons/liaisondetail_simple_list.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - - -{% for liaison in object_list %} - - - - - - - -{% endfor %} - -
      - From - - To - - Deadline - - Title -
      {{ liaison.submitted_date|date:"Y-m-d" }}{{ liaison.from_body|escape }} -{% if liaison.by_secretariat %} - {% if liaison.submitter_email %} - {{ liaison.submitter_name|escape }} - {% else %} - {{ liaison.submitter_name|escape }} - {% endif %} -{% else %} - {{ liaison.to_body|escape }} -{% endif %} - - {{ liaison.deadline_date|default:"--" }} - -{% if liaison.by_secretariat %} - {% for file in liaison.uploads_set.all %} - {{ file.file_title|escape }}
      - {% endfor %} -{% else %} - {{ liaison.title|escape }} -{% endif %} - -
      diff --git a/ietf/templates/liaisons/liaisonform.html b/ietf/templates/liaisons/liaisonform.html index 980589ca5..7e5961051 100644 --- a/ietf/templates/liaisons/liaisonform.html +++ b/ietf/templates/liaisons/liaisonform.html @@ -1,5 +1,3 @@ -{% load i18n %} -
      + +
      + +
      + +{% endif %} + +{% include "submit/problem-reports-footer.html" %} + +{% endblock %} diff --git a/ietf/templates/wgchairs/confirm_management_writeup.html b/ietf/templates/wgchairs/confirm_management_writeup.html deleted file mode 100644 index 3bc5ceab9..000000000 --- a/ietf/templates/wgchairs/confirm_management_writeup.html +++ /dev/null @@ -1,55 +0,0 @@ -{% extends "wginfo/wg_base.html" %} -{% load ietf_filters wgchairs_tags %} - -{% block title %}Change shepherd write-up for {{ doc }}{% endblock %} - -{% block wg_content %} - -

      -Return to shepherd list -

      - -

      Updating write-up for {{ doc }}

      - -

      -Before you modify the shepherd write-up please revise the 'Doc Shepherd Follow-up Underway' annotation tag and set or reset it if appropriate. -

      -

      -Remember that you must provide a comment if you change the annotation tag state. -

      - -
      -
      - - -{% if form.message %} - -{% endif %} - - -
      Doc Shepherd Follow-up Underway
      - {{ form.message.value }} -
      - - - - -
      -{{ form.comment }} -
      -

      - Change write-up and ...
      - -
      - Cancel, I don't want to do any change! -

      - -
      - - - -
      New shepherd write-up
      {{ form.get_writeup|linebreaksbr }}
      - -
      -
      -{% endblock %} diff --git a/ietf/templates/wgchairs/draft_state.html b/ietf/templates/wgchairs/draft_state.html deleted file mode 100644 index 956ebd44f..000000000 --- a/ietf/templates/wgchairs/draft_state.html +++ /dev/null @@ -1 +0,0 @@ -{{ state.name }} diff --git a/ietf/templates/wgchairs/edit_management_shepherd.html b/ietf/templates/wgchairs/edit_management_shepherd.html deleted file mode 100644 index b9a9e616a..000000000 --- a/ietf/templates/wgchairs/edit_management_shepherd.html +++ /dev/null @@ -1,41 +0,0 @@ -{% extends "wginfo/wg_base.html" %} -{% load ietf_filters %} - -{% block title %}Change shepherd for {{ doc }}{% endblock %} - -{% block wg_content %} - -

      -Return to shepherd list -Return to {{ doc }} -

      - -

      Change shepherd for {{ doc }}

      - -
      -
      - - - -
      Actual shepherd
      {% if doc.shepherd %}{{ doc.shepherd }}{% else %}No shepherd assigned{% endif %}
      - - - -
      -
      -
      - - -{% if form.message %} - -{% endif %} - - -
      Change shepherd
      - {{ form.message.value }} -
      {{ form.as_p }}
      - - {% if form.can_cancel %}No! I don't want to continue{% endif %} -
      -
      -{% endblock %} diff --git a/ietf/templates/wgchairs/edit_management_writeup.html b/ietf/templates/wgchairs/edit_management_writeup.html deleted file mode 100644 index 7a61437c0..000000000 --- a/ietf/templates/wgchairs/edit_management_writeup.html +++ /dev/null @@ -1,67 +0,0 @@ -{% extends "wginfo/wg_base.html" %} -{% load ietf_filters wgchairs_tags %} - -{% block title %} {% if can_edit %} Change {% else %} View {% endif %} shepherd write-up for {{ doc }}{% endblock %} - -{% block wg_content %} - -

      -Return to shepherd list -

      - -

      {% if can_edit %} Change {% else %} View {% endif %} shepherd write-up for {{ doc }}

      - - - - -
      Draft stateActual shepherd write-upLast updated
      {% show_state doc %}{{ writeup.writeup|linebreaksbr }}{% if writeup %}{{ writeup.date }} by {{ writeup.person }}{% endif %}
      - -

      -Please, note that the 'Doc Shepherd Follow-up Underway' annotation tag is {% if not followup %}NOT{% endif %} set for {{ doc }}. -

      - -{% if can_edit %} -
      -
      - - -{% if form.message %} - -{% endif %} - - -
      Edit shepherd write-up
      - {{ form.message.value }} -
      -
      - -
      - -
      - -
      - - - -
      Upload a new shepherd write-up
      -

      Replace the current write-up with the contents of a plain ascii file:

      -
      - -
      -
      -{% else %} -{% if authorized_user %} - - - -
      Edit shepherd write-up
      -

      - You can not edit or upload the shepherd write-up for {{ doc }} because the draft is not on "WG Consensus: Waiting for Write-Up" state. -

      -

      - Please contact with the {{ wg }} Working Group chair. -

      -
      -{% endif %} -{% endif %} -{% endblock %} diff --git a/ietf/templates/wgchairs/manage_delegates.html b/ietf/templates/wgchairs/manage_delegates.html deleted file mode 100644 index f1f2eaf58..000000000 --- a/ietf/templates/wgchairs/manage_delegates.html +++ /dev/null @@ -1,60 +0,0 @@ -{% extends "wginfo/wg_base.html" %} - - -{% block wg_titledetail %}Delegates{% endblock %} - -{% block wg_content %} -
      - -

      Manage delegates

      -

      -Sometimes, a WG has one (or more) WG Secretaries, in addition to the WG Chairs. -This page lets the WG Chairs delegate the authority to do updates to the WG state of WG documents in the datatracker. -

      - -

      -You may at most delegate the datatracker update rights to {{ max_delegates }} persons at any given time. -

      - - - - -
      -{% if delegates %} -
      - - - {% for delegate in delegates %} - - {% endfor %} -
      RemoveDelegate name
      {{ delegate.person }}
      - -
      -{% else %} -No delegates -{% endif %} -
      - - -{% if add_form.message %} - -{% endif %} - -
      Add new delegate
      - {{ add_form.message.value }} -
      -{% if can_add %} -
      - {{ add_form.as_p }} -

      - - {% if add_form.can_cancel %}No! I don't want to continue{% endif %} -

      -
      -{% else %} -You can only assign {{ max_delegates }} delegates. Please remove delegates to add a new one. -{% endif %} -
      -
      -
      -{% endblock %} diff --git a/ietf/templates/wgchairs/manage_workflow.html b/ietf/templates/wgchairs/manage_workflow.html deleted file mode 100644 index bc5a4fbd7..000000000 --- a/ietf/templates/wgchairs/manage_workflow.html +++ /dev/null @@ -1,165 +0,0 @@ -{% extends "wginfo/wg_base.html" %} - -{% block wg_titledetail %}Manage Workflow{% endblock %} - -{% block pagehead %} -{{ block.super }} - - - -{% endblock pagehead %} - -{% block wg_content %} -
      -

      Edit workflow

      -
      - - -
      -
      -
      - - - - - {% for state in states %} - - - -{% endfor %} -
      States used in {{ wg }} Working Group
      {{ state.name }}

      - - - - - {% for tag in tags %} - - - -{% endfor %} -
      Annotation tags used in {{ wg }} Working Group
      {{ tag.name }}
      -
      - - - - - {% for transition in workflow.transitions.all %} - - - - - - {% endfor %} - {% if not workflow.transitions.all.count %} - - {% endif %} -
      Transition nameInitial statesDestination state
      - {{ transition.name }} - - {% for state in transition.states.all %} - {{state.name }}{% if not forloop.last %}
      {% endif %} - {% endfor %} -
      - {{ transition.destination.name }} -
      There are no transitions defined so any state change is allowed
      -
      -
      - -
      -

      -Please note that the states you can not uncheck are needed in all IETF WGs. -

      -

      -You can see the default Working Group I-D State Diagram in Section 4.1 of RFC6174 -

      -
      - - - - - {% for state in default_states %} - - - - - -{% endfor %} -
      Used in {{ wg }}Available statesDefinition
      -
      -
      [+] {{ state.statedescription_set.all.0.definition|safe }}
      -
      -
      - -
      -
      - -
      -

      -You can see the default Working Group I-D State Diagram in Section 4.1 of RFC6174 -

      -
      - - - - -{{ formset.as_table }} -
      DeleteTransition nameInitial statesDestination state
      - -
      -
      - -
      -
      - - - - - {% for tag in default_tags %} - - - - -{% endfor %} -
      Used in {{ wg }}Available annotation tags
      - -
      -
      -
      -
      - - - -{% endblock %} diff --git a/ietf/templates/wgchairs/notexistdelegate.html b/ietf/templates/wgchairs/notexistdelegate.html deleted file mode 100644 index 706907022..000000000 --- a/ietf/templates/wgchairs/notexistdelegate.html +++ /dev/null @@ -1,28 +0,0 @@ -{% if shepherd %} -

      -The shepherd you are trying to designate does not have a personal user-id and password to log-on to the Datatracker. -

      -

      -An email will be sent to the following addresses to inform that -the person you have designated to be one of your document shepherds -currently does not have login credentials for the Datatracker -and should contact the Secretariat to obtain their own user-id and -password for the Datatracker. -

      -{% else %} -

      -The delegate you are trying to designate does not have a personal user-id and password to log-on to the Datatracker. -

      -

      -An email will be sent to the following addresses to inform that -the person you have designated to be one of your delegates -currently does not have login credentials for the Datatracker -and should contact the Secretariat to obtain their own user-id and -password for the Datatracker. -

      -{% endif %} -
        -{% for email in email_list %} -
      • {{ email }}
      • -{% endfor %} -
      diff --git a/ietf/templates/wgchairs/notexistsdelegate_delegate_email.txt b/ietf/templates/wgchairs/notexistsdelegate_delegate_email.txt deleted file mode 100644 index de2318a93..000000000 --- a/ietf/templates/wgchairs/notexistsdelegate_delegate_email.txt +++ /dev/null @@ -1,10 +0,0 @@ -{% autoescape off %}{{ chair }} as a WG Chair of {{ wg }} wants to add you as a {{ wg }} {% if shepherd %}shepherd of document {{ shepherd }}{% else %}WG Delegate{% endif %}. - -You don't have an user/password to log into the datatracker so you must contact -the Secretariat at iesg-secretary@ietf.org in order to get your credentials. - -When you get your credentials, please inform {{ chair }} at -{{ chair.email.1 }} so he/she can finish the designate process. - -Thank you. -{% endautoescape %} diff --git a/ietf/templates/wgchairs/notexistsdelegate_secretariat_email.txt b/ietf/templates/wgchairs/notexistsdelegate_secretariat_email.txt deleted file mode 100644 index 27edacc11..000000000 --- a/ietf/templates/wgchairs/notexistsdelegate_secretariat_email.txt +++ /dev/null @@ -1,15 +0,0 @@ -{% autoescape off %}{{ chair }} as a WG Chair of {{ wg }} wants to add a person with email -{{ delegate_email }} as a {% if shepherd %}shepherd of document {{ shepherd }}{% else %}WG Delegate{% endif %}. - -This person don't have an user/password to log into the datatracker so -an email has been seent to {{ delegate_email }} in order to he/she contacs the -Secretariat to request his/her credentials. - -{% if delegate_persons %} -Please, note that the following persons with {{ delegate_email }} email address -already exists in the system but they can not log in. -{% for person in delegate_persons %} -{{ person.pk }} - {{ person }} -{% endfor %} -{% endif %} -{% endautoescape %} \ No newline at end of file diff --git a/ietf/templates/wgchairs/notexistsdelegate_wgchairs_email.txt b/ietf/templates/wgchairs/notexistsdelegate_wgchairs_email.txt deleted file mode 100644 index 477111dcf..000000000 --- a/ietf/templates/wgchairs/notexistsdelegate_wgchairs_email.txt +++ /dev/null @@ -1,12 +0,0 @@ -{% autoescape off %}{{ chair }} as a WG Chair of {{ wg }} wants to add a person with email -{{ delegate_email }} as a {% if shepherd %}shepherd of document {{ shepherd }}{% else %}WG Delegate{% endif %}. - -This person don't have an user/password to log into the datatracker so -an email has been seent to {{ delegate_email }} in order to he/she contacs the -Secretariat to request his/her credentials. - -When he/she gets her credentials then he/she will send an email to -{{ chair }} at {{ chair.email.1 }}. - -{{ chair }} could then assign this person as {% if shepherd %}shepherd of document {{ shepherd }}{% else %}WG Delegate{% endif %}. -{% endautoescape%} \ No newline at end of file diff --git a/ietf/templates/wgchairs/shepherd_document_row.html b/ietf/templates/wgchairs/shepherd_document_row.html deleted file mode 100644 index a58e1eac5..000000000 --- a/ietf/templates/wgchairs/shepherd_document_row.html +++ /dev/null @@ -1,17 +0,0 @@ -{% load wgchairs_tags %} - - - - {{ doc.title }} - - - Change shepherd - - - {% writeup doc %} - [Edit] - - - {% writeupdate doc %} - - diff --git a/ietf/templates/wgchairs/wg_shepherd_documents.html b/ietf/templates/wgchairs/wg_shepherd_documents.html deleted file mode 100644 index 2afcd9bac..000000000 --- a/ietf/templates/wgchairs/wg_shepherd_documents.html +++ /dev/null @@ -1,122 +0,0 @@ -{% extends "wginfo/wg_base.html" %} -{% comment %} -Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -All rights reserved. Contact: Pasi Eronen - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * Neither the name of the Nokia Corporation and/or its - subsidiary(-ies) nor the names of its contributors may be used - to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -{% endcomment %} -{% block wg_titledetail %}Documents{% endblock %} - -{% block pagehead %} -{{ block.super }} - - - -{% endblock pagehead %} - -{% block wg_content %} - -

      Documents by its shepherd

      -
      - - -
      -
      - - - - - - - - - {% for doc in no_shepherd %} - {% include "wgchairs/shepherd_document_row.html" %} - {% endfor %} - -
      DocumentChange shepherdShepherd write-upShepherd write-up last update
      -
      - -
      - - - - - - - - - {% for doc in my_documents %} - {% include "wgchairs/shepherd_document_row.html" %} - {% endfor %} - -
      DocumentStatusShepherd write-upShepherd write-up last update
      -
      - -
      -{% regroup other_shepherds by shepherd as regrouped %} -{% for documents in regrouped %} -

      {{ documents.grouper }}

      - - - - - - - - {% for doc in documents.list %} - {% include "wgchairs/shepherd_document_row.html" %} - {% endfor %} -
      DocumentStatusShepherd write-upShepherd write-up last update
      -{% endfor %} -
      - - -{% endblock wg_content %} - diff --git a/ietf/templates/wgchairs/wgchairs_admin_options.html b/ietf/templates/wgchairs/wgchairs_admin_options.html deleted file mode 100644 index b8c45a00f..000000000 --- a/ietf/templates/wgchairs/wgchairs_admin_options.html +++ /dev/null @@ -1,23 +0,0 @@ -{% if can_manage_workflow %} - {% ifequal selected "manage_workflow" %} - Manage workflow - {% else %} - Manage workflow - {% endifequal %} | -{% endif %} - -{% if can_manage_delegates %} - {% ifequal selected "manage_delegates" %} - Manage delegations - {% else %} - Manage delegations - {% endifequal %} | -{% endif %} - -{% if can_manage_shepherds %} - {% ifequal selected "manage_shepherds" %} - Manage shepherds - {% else %} - Manage shepherds - {% endifequal %} | -{% endif %} diff --git a/ietf/templates/wginfo/1wg-charters-by-acronym.txt b/ietf/templates/wginfo/1wg-charters-by-acronym.txt index 247e1466c..bad8939cd 100644 --- a/ietf/templates/wginfo/1wg-charters-by-acronym.txt +++ b/ietf/templates/wginfo/1wg-charters-by-acronym.txt @@ -1,4 +1,4 @@ -{% load ietf_filters %}{% for wg in wg_list|dictsort:"group_acronym.acronym" %}{% if wg.area.area.status_id == 1 and wg.area.area.acronym != "iesg" %}{% if wg.start_date %}{{ wg }} -{% endif %}{% endif %}{% endfor %} -{% for wg in wg_list|dictsort:"group_acronym.acronym" %}{% if wg.area.area.status_id == 1 and wg.area.area.acronym != "iesg" %}{% if wg.start_date %}{% include "wginfo/wg-charter.txt" %} -{% endif %}{% endif %}{% endfor %} +{% autoescape off %}{% load ietf_filters %}{% for group in groups %}{{ group.acronym }} +{% endfor %} + +{% for group in groups %}{% include "wginfo/group_entry_with_charter.txt" %}{% endfor %}{% endautoescape %} diff --git a/ietf/templates/wginfo/1wg-charters.txt b/ietf/templates/wginfo/1wg-charters.txt index 4e5e70941..767dd1bb0 100644 --- a/ietf/templates/wginfo/1wg-charters.txt +++ b/ietf/templates/wginfo/1wg-charters.txt @@ -1,7 +1,6 @@ -{% load ietf_filters %}{% regroup wg_list|dictsort:"area_acronym.acronym" by area.area as wga_list %}{% for area in wga_list %}{% for wg in area.list|dictsort:"group_acronym.name" %}{% if wg.area.area.status_id == 1 and wg.area.area.acronym != "iesg" %}{% if wg.start_date %}{{ wg }} -{% endif %}{% endif %}{% endfor %}{% endfor %} +{% autoescape off %}{% load ietf_filters %}{% for area in areas %}{% for group in area.groups %}{{ group.acronym }} +{% endfor %}{% endfor %} + +{% for area in areas %}{% for group in area.groups %}{% include "wginfo/group_entry_with_charter.txt" %}{% endfor %}{% endfor %}{% endautoescape %} -{% regroup wg_list|dictsort:"area_acronym.acronym" by area.area as wga_list %}{% for area in wga_list %}{% for wg in area.list|dictsort:"group_acronym.name" %}{% if wg.area.area.status_id == 1 and wg.area.area.acronym != "iesg" %}{% if wg.start_date %} -{% include "wginfo/wg-charter.txt" %} -{% endif %}{% endif %}{% endfor %}{% endfor %} diff --git a/ietf/templates/wginfo/1wg-summary-by-acronym.txt b/ietf/templates/wginfo/1wg-summary-by-acronym.txt index d1a0f46be..028d5fd0e 100644 --- a/ietf/templates/wginfo/1wg-summary-by-acronym.txt +++ b/ietf/templates/wginfo/1wg-summary-by-acronym.txt @@ -1,10 +1,10 @@ -{% load ietf_filters %} +{% autoescape off %}{% load ietf_filters %} IETF Working Group Summary (By Acronym) The following Area Abbreviations are used in this document -{% for area in area_list %} -{{ area|upper }} - {{ area.area_acronym.name }}{% endfor %} -{% for wg in wg_list|dictsort:"group_acronym.acronym" %}{% if wg.start_date %} -{{ wg.group_acronym.name|safe }} ({{ wg }}) -- {{ wg.area.area|upper }} -{% include "wginfo/wg_summary.txt" %}{% endif %}{% endfor %} +{% for area in areas %} +{{ area.acronym|upper }} - {{ area.name }}{% endfor %} +{% for group in groups %} +{{ group.name }} ({{ group.acronym }}) -- {{ group.parent.acronym|upper }} +{% include "wginfo/group_entry.txt" %}{% endfor %}{% endautoescape %} diff --git a/ietf/templates/wginfo/1wg-summary.txt b/ietf/templates/wginfo/1wg-summary.txt index 55d76d1e2..f6ae51202 100644 --- a/ietf/templates/wginfo/1wg-summary.txt +++ b/ietf/templates/wginfo/1wg-summary.txt @@ -1,8 +1,11 @@ -{% load ietf_filters %} IETF Working Group Summary (By Area) -{% regroup wg_list|dictsort:"area.area.area_acronym.acronym" by area.area as wga_list %}{% for area in wga_list %}{% for wg in area.list|dictsort:"group_acronym.acronym" %}{% ifequal wg.area.area.status_id 1 %}{% if forloop.first %} -{{ wg.area_acronym.name }} ({{ wg.area_acronym }}) -{{ wg.area_acronym.name|dashify }}------{% for ad in wg.area_directors %} - {{ ad.person }} <{{ ad.person.email.1 }}>{% endfor %} -{% endif %}{% if wg.start_date %} -{{ wg.group_acronym.name|safe }} ({{ wg }}) -{% include "wginfo/wg_summary.txt" %}{% endif %}{% endifequal %}{% endfor %}{% endfor %} +{% autoescape off %}{% load ietf_filters %} + IETF Working Group Summary (By Area) + + +{% for area in areas %}{{ area.name }} ({{ area.acronym }}) +{{ area.name|dashify }}------{% for ad in area.ads %} + {{ ad.person.plain_name }} <{{ ad.email.address }}>{% endfor %} + +{% for group in area.groups %}{{ group.name }} ({{ group.acronym }}) +{% include "wginfo/group_entry.txt" %} +{% endfor %}{% endfor %}{% endautoescape %} diff --git a/ietf/templates/wginfo/wg-dirREDESIGN.html b/ietf/templates/wginfo/active_wgs.html similarity index 69% rename from ietf/templates/wginfo/wg-dirREDESIGN.html rename to ietf/templates/wginfo/active_wgs.html index a74f48ba9..4d88435fa 100644 --- a/ietf/templates/wginfo/wg-dirREDESIGN.html +++ b/ietf/templates/wginfo/active_wgs.html @@ -53,47 +53,44 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. {% for area in areas %}

      {{ area.name }}

      - {% for ad in area.ads %} - {% if forloop.first %} -

      Area Director{{ forloop.revcounter|pluralize }}:

      + {% if area.ads %} +

      Area Director{{ area.ads|pluralize }}:

      - {% endif %} - - {% if forloop.last %} + {% for ad in area.ads %} + + + + + {% endfor %}
        {{ ad.person.plain_name }} <{{ ad.address }}>{% if ad.incoming %} (Incoming AD){% endif %}
       {{ ad.person.plain_name }} <{{ ad.email.address }}>{% if ad.name == "pre-ad" %} (Incoming AD){% endif %}
      {% endif %} - {% endfor %} - {% for url in area.urls %} - {% if forloop.first %} -

      Area Specific Web Page{{ forloop.revcounter|pluralize}}:

      + {% if area.urls %} +

      Area Specific Web Page{{ area.urls|pluralize}}:

      - {% endif %} + {% for url in area.urls %} {{ url.name }}{% if not forloop.last %}
      {% endif %} - {% if forloop.last %} + {% endfor %}

      {% endif %} - {% endfor %} - {% for wg in area.wgs %} - {% if forloop.first %} -

      Active Working Groups:

      + {% if area.groups %} +

      Active Working Group{{ area.groups|pluralize}}:

      - {% endif %} + {% for group in area.groups %} - - - - + + + + - {% if forloop.last %} + {% endfor %}
      {{ wg.acronym }}{% for ad in area.ads %}{% ifequal ad.person_id wg.ad_id %}{% endifequal %}{% endfor %}{{ wg.name }}{% for chair in wg.chairs %}{{ chair.person.plain_name }}{% if not forloop.last %}, {% endif %}{% endfor %}{{ group.acronym }}{% for ad in area.ads %}{% if ad.person_id == group.ad_id %}{% endif %}{% endfor %}{{ group.name }}{% for chair in group.chairs %}{{ chair.person.plain_name }}{% if not forloop.last %}, {% endif %}{% endfor %}
      - {% endif %} - {% empty %} + {% else %}

      No Active Working Groups

      - {% endfor %}{# wg #} + {% endif %} {% endfor %}{# area #} diff --git a/ietf/templates/wginfo/bofs.html b/ietf/templates/wginfo/bofs.html index 60df23342..3d2d5134a 100644 --- a/ietf/templates/wginfo/bofs.html +++ b/ietf/templates/wginfo/bofs.html @@ -25,7 +25,7 @@ {% for g in groups %} - {{ g.acronym }} + {{ g.acronym }} {{ g.name }} diff --git a/ietf/templates/wginfo/chartering_wgs.html b/ietf/templates/wginfo/chartering_wgs.html index 291daa6a5..67255ca0b 100644 --- a/ietf/templates/wginfo/chartering_wgs.html +++ b/ietf/templates/wginfo/chartering_wgs.html @@ -28,7 +28,7 @@ {% for g in groups %} - {{ g.acronym }} + {{ g.acronym }} {{ g.name }} diff --git a/ietf/templates/wginfo/conclude.html b/ietf/templates/wginfo/conclude.html index d233057c1..76f0ad03c 100644 --- a/ietf/templates/wginfo/conclude.html +++ b/ietf/templates/wginfo/conclude.html @@ -1,6 +1,6 @@ {% extends "base.html" %} -{% block title %}Request closing of WG {{ wg.acronym }}{% endblock %} +{% block title %}Request closing of {{ wg.acronym }} {{ wg.type.name }}{% endblock %} {% block morecss %} #id_instructions { @@ -14,22 +14,23 @@ form.conclude .actions { {% endblock %} {% block content %} -

      Request closing of {{ wg.acronym }}

      +

      Request closing of {{ wg.acronym }} {{ wg.type.name }}

      Please provide instructions regarding the disposition of each active Internet-Draft (such as to withdraw the draft, move it to - another WG, convert it to an individual submission, and so on), - wording for the closure announcement, and the status of the WG + another group, convert it to an individual submission, and so on), + wording for the closure announcement, and the status of the group mailing list (will it remain open or should it be closed).

      +
      {{ form.as_table }}
      - Back - + Cancel +
      diff --git a/ietf/templates/wgchairs/manage_workflowREDESIGN.html b/ietf/templates/wginfo/customize_workflow.html similarity index 65% rename from ietf/templates/wgchairs/manage_workflowREDESIGN.html rename to ietf/templates/wginfo/customize_workflow.html index 4a385afaf..147267aaf 100644 --- a/ietf/templates/wgchairs/manage_workflowREDESIGN.html +++ b/ietf/templates/wginfo/customize_workflow.html @@ -1,65 +1,45 @@ -{% extends "wginfo/wg_base.html" %} +{% extends "base.html" %} -{% block wg_titledetail %}Manage Workflow{% endblock %} - -{% block pagehead %} -{{ block.super }} - - - -{% endblock pagehead %} +{% block title %}Customize Workflow for {{ group.acronym }} {{ group.type.name }}{% endblock %} {% block morecss %} {{ block.super }} .state-table .inactive, -.tag-table .inactive { - font-style: italic; - color: #666; -} -.state-table .state { - padding-right: 0.6em; -} -.set-next-states { - margin-top: 1em; -} -.set-next-states label { - display: block; - cursor: pointer; -} -.set-next-states label input { - vertical-align: middle; -} -.set-state input, .set-tag input { - width: 6em; -} -.toggled { - display: none; -} -.toggler { - color: #000; +.tag-table .inactive { font-style: italic; color: #666; } +.state-table .state { margin-bottom: 0.1em; } +.state-table .set-next-states label { display: block; cursor: pointer; } +.state-table .set-next-states label input { vertical-align: middle; } +.state-table .set-state input, .set-tag input { width: 6em; } +.state-table .toggled { display: none; } +.state-table .toggler { + color: #444; + background: #ddd; + font-weight: bold; text-decoration: none; - padding: 0px 3px; + padding: 1px 3px; display: inline-block; margin-left: 0.5em; - font-size: 15px; - font-weight: bold; -} -.inactive .toggler { - color: #666; -} -.toggler:hover { - background-color: #999; - color: #fff; + margin-top: 0.5em; + margin-bottom: 0.5em; } +.state-table .inactive .toggler { color: #aaa; background: #eee; } +.state-table .toggler:hover { color: #fff; background-color: #999; } {% endblock %} -{% block wg_content %} -
      -

      Edit workflow

      +{% block content %} +{% load ietf_filters %} -

      Below you can customize the draft states and tags used in the {{ wg.acronym }} WG. Note that some states are mandatory for WG operation and cannot be deactivated.

      +
      + +

      Customize Workflow for {{ group.acronym }} {{ group.type.name }}

      + +

      Below you can customize the draft states and tags used in the +{{ group.acronym }} {{ group.type.name }}. Note that some states are +mandatory for group operation and cannot be deactivated.

      + +

      You can see the default Working Group I-D State Diagram +in Section 4.1 of RFC6174.

      -

      You can see the default Working Group I-D State Diagram in Section 4.1 of RFC6174.

      States

      @@ -90,20 +70,16 @@ {% endif %} -
      - {{ state.name }} {% if not state.used %} (not used in {{ wg.acronym }}){% endif %} - + -
      -
      {{ state.desc|safe|linebreaks }}
      + {{ state.name }} {% if not state.used %} (not used in {{ group.acronym }}){% endif %} {{ state|statehelp }}
      {% if state.used_next_states %} - {% for n in state.used_next_states %}{{ n.name }}{% if not forloop.last %} {% endif %}{% endfor %} + {% for n in state.used_next_states %}
      {{ n.name }}
      {% endfor %} {% else %} - None +
      None
      {% endif %} - + + + customize
      Select the next states: @@ -142,11 +118,14 @@ - {{ tag.name }} {% if not tag.used %} (not used in {{ wg.acronym }}){% endif %} + {{ tag.name }} {% if not tag.used %} (not used in {{ group.acronym }}){% endif %} {% endfor %} +{% endblock content %} + +{% block js %} - {% endblock %} diff --git a/ietf/templates/wginfo/edit.html b/ietf/templates/wginfo/edit.html index ad77789a9..8af9917b8 100644 --- a/ietf/templates/wginfo/edit.html +++ b/ietf/templates/wginfo/edit.html @@ -9,6 +9,7 @@ Start chartering new WG {% endblock %} {% block morecss %} +form.edit td { padding-bottom: .5em; } form.edit #id_name, form.edit #id_list_email, form.edit #id_list_subscribe, @@ -16,8 +17,7 @@ form.edit #id_list_archive, form.edit #id_urls, form.edit #id_comments { width: 400px; } form.edit input[type=checkbox] { vertical-align: middle; } -ul.errorlist { border-width: 0px; padding: 0px; margin: 0px;} -ul.errorlist li { color: #a00; margin: 0px; padding: 0px; list-style: none; } +form.edit #id_urls { height: 4em; } {% endblock %} {% block pagehead %} @@ -27,28 +27,30 @@ ul.errorlist li { color: #a00; margin: 0px; padding: 0px; list-style: none; } {% block content %} {% load ietf_filters %}

      -{% ifequal action "edit" %} +{% if action == "edit" %} Edit WG {{ wg.acronym }} {% else %} - {% ifequal action "charter" %} + {% if action == "charter" %} Start chartering new WG {% else %} Create new WG or BoF - {% endifequal %} -{% endifequal %} + {% endif %} +{% endif %}

      +

      Note that persons with authorization to manage information, e.g. +chairs and delegates, need a Datatracker account to actually do +so. New accounts can be created here.

      +
      {% for field in form.visible_fields %} @@ -65,16 +67,16 @@ Create new WG or BoF
      {{ field.label_tag }}: {% if field.field.required %}*{% endif %} {{ field }} - {% ifequal field.name "ad" %} - {% if user|has_role:"Area Director" %} + {% if field.name == "ad" and user|has_role:"Area Director" %} {% endif %} - {% endifequal %} {% if field.help_text %}
      {{ field.help_text }}
      {% endif %} {{ field.errors }}
      - {% ifequal action "edit" %} - Back - + {% if action == "edit" %} + Cancel + {% else %} - {% ifequal action "charter" %} + {% if action == "charter" %} {% else %} - {% endifequal %} - {% endifequal %} + {% endif %} + {% endif %}
      diff --git a/ietf/templates/wginfo/edit_milestones.html b/ietf/templates/wginfo/edit_milestones.html index ccbf0b3dd..e3a3a8a12 100644 --- a/ietf/templates/wginfo/edit_milestones.html +++ b/ietf/templates/wginfo/edit_milestones.html @@ -42,7 +42,7 @@ tr.milestone.add { font-style: italic; }

      Links: - {{ group.acronym }} {{ group.type.name }} + {{ group.acronym }} {{ group.type.name }} - {{ group.charter.canonical_name }}

      @@ -91,7 +91,7 @@ this list to the milestones currently in use for the {{ group.acronym }} {{ diff --git a/ietf/templates/wginfo/wg_base.html b/ietf/templates/wginfo/group_base.html similarity index 54% rename from ietf/templates/wginfo/wg_base.html rename to ietf/templates/wginfo/group_base.html index cbb96c240..a229f60cc 100644 --- a/ietf/templates/wginfo/wg_base.html +++ b/ietf/templates/wginfo/group_base.html @@ -32,8 +32,8 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. {% endcomment %} -{% load ietf_filters wgchairs_tags %} -{% block title %}{{wg.group_acronym.name}} ({{wg.group_acronym.acronym}}) - {% block wg_titledetail %}{% endblock %}{% endblock %} +{% load ietf_filters %} +{% block title %}{{ group.name }} ({{ group.acronym }}) - {% block group_subtitle %}{% endblock %}{% endblock %} {% block morecss %} .ietf-navset { @@ -45,39 +45,46 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .ietf-navset .selected { font-weight:bold; padding: 0 3px; } .ietf-navset a, .ietf-navset a:visited { color: white; padding:0 3px; } -.ietf-wg-details { float:right; padding: 4px;margin-top:16px; margin-left: 16px; } -.ietf-wg-details tr { vertical-align: top; } +.ietf-group-details { float:right; padding: 4px;margin-top:16px; margin-left: 16px; } +.ietf-group-details tr { vertical-align: top; } .ietf-concluded-bg {background-color: #F8F8D0; } .ietf-concluded-warning { background:red;color:white;padding:2px 2px;} .ietf-proposed-bg { } .ietf-proposed-warning { background:green;color:white;padding:2px 2px;} -.ietf-box th { - font-weight: bold; - padding-top: 1em; - text-align: left; -} -.ietf-box tr:first-child th { - padding-top: 0; -} +.ietf-box th { font-weight: bold; padding-top: 1em; text-align: left; } +.ietf-box tr:first-child th { padding-top: 0; } {% endblock morecss %} {% block content %} -
      -

      {{wg.group_acronym.name}} ({{wg.group_acronym.acronym}}){% if concluded %}
      (concluded {% if wg.state_id == "bof-conc" %}BoF{% else %}WG{% endif %}){% endif %}{% if proposed %}
      (proposed WG){% endif %}

      +
      + +

      {{ group.name}} ({{ group.acronym }}) + {% if group.state_id == "dormant" or group.state_id == "conclude" %}
      (concluded {{ group.type.name }}){% endif %} + {% if group.state_id == "proposed" %}
      (proposed {{ group.type.name }}){% endif %} +

      -{% ifequal selected "documents" %}Documents{% else %}Documents{% endifequal %} | -{% ifequal selected "charter" %}Charter{% else %}Charter{% endifequal %} | -{% wgchairs_admin_options wg %} -History | -{% if wg.clean_email_archive|startswith:"http:" or wg.clean_email_archive|startswith:"https:" or wg.clean_email_archive|startswith:"ftp:" %} -List Archive » | -{% endif %} -Tools WG Page » +
      + Documents | + Charter | + History | + {% if group.list_archive|startswith:"http:" or group.list_archive|startswith:"https:" or group.list_archive|startswith:"ftp:" %} + List Archive » | + {% endif %} + Tools WG Page » +
      + + {% if menu_actions %} +
      + {% for name, url in menu_actions %} + {{ name }} + {% endfor %} +
      + {% endif %}
      -{% block wg_content %} -{% endblock wg_content %} +{% block group_content %} +{% endblock group_content %}
      {% endblock content %} diff --git a/ietf/templates/wginfo/group_charter.html b/ietf/templates/wginfo/group_charter.html new file mode 100644 index 000000000..1f39ac850 --- /dev/null +++ b/ietf/templates/wginfo/group_charter.html @@ -0,0 +1,168 @@ +{% extends "wginfo/group_base.html" %} + +{% load ietf_filters %} +{% block group_subtitle %}Charter{% endblock %} + +{% block morecss %} +{{ block.super }} +h2 a.button { margin-left: 0.5em; font-size: 13px; } +{% endblock %} + +{% block group_content %} +
      + +{% if group.state_id == "conclude" %} +Note: The data for concluded WGs +is occasionally incorrect. +{% endif %} + + + + + + + + + + + + {% if group.parent %} + + {% endif %} + + + + + + + + + + + + + + + + + + + + + + + {% if group.techadvisors %} + + + + + {% endif %} + + {% if group.editors %} + + + + + {% endif %} + + {% if group.secretaries %} + + + + + {% endif %} + + {% if group.delegates %} + + + + + {% endif %} + + + + + + + + {% if group.state_id != "conclude" %} + + + + + + + + + + + + {% endif %} + +
      Group
      Name:{{ group.name }}
      Acronym:{{ group.acronym }}
      {{ group.parent.type.name }}:{{ group.parent.name }} ({{ group.parent.acronym }})
      State:{{ group.state.name }} + {% if requested_close %} + (but in the process of being closed) + {% endif %} +
      Charter: + {% if group.charter %} + {{ group.charter.name }}-{{ group.charter.rev }} ({{ group.charter.get_state.name }}) + {% else %} + none + {% if user|has_role:"Area Director,Secretariat" %} + - Submit Charter + {% endif %} + {% endif %} +
      Personnel
      Chair{{ group.chairs|pluralize }}: + {% for chair in group.chairs %} + {{ chair.person.plain_name }} <{{ chair.email.address }}>
      + {% endfor %} +
      Area Director: + {% if group.areadirector %} + {{ group.areadirector.person.plain_name }} <{{ group.areadirector.address }}> + {% else %}?{% endif %} +
      Tech Advisor{{ group.techadvisors|pluralize }}: + {% for techadvisor in group.techadvisors %} + {{ techadvisor.person.plain_name }} <{{ techadvisor.email.address }}>
      + {% endfor %} +
      Editor{{ group.editors|pluralize }}: + {% for editor in group.editors %} + {{ editor.person.plain_name }} <{{ editor.email.address }}>
      + {% endfor %} +
      Secretar{{ group.secretaries|pluralize:"y,ies" }}: + {% for secretary in group.secretaries %} + {{ secretary.person.plain_name }} <{{ secretary.email.address }}>
      + {% endfor %} +
      Delegate{{ group.delegates|pluralize }}: + {% for delegate in group.delegates %} + {{ delegate.person.plain_name }} <{{ delegate.email.address }}>
      + {% endfor %} +
      Mailing List
      Address:{{ group.list_email|urlize }}
      To Subscribe:{{ group.list_subscribe|urlize }}
      Archive:{{ group.list_archive|urlize }}
      Jabber Chat
      Room Address:xmpp:{{ group.acronym }}@jabber.ietf.org
      Logs:http://jabber.ietf.org/logs/{{ group.acronym }}/
      + +
      + +{% with group.groupurl_set.all as urls %} +{% if urls %} +

      In addition to the charter maintained by the IETF Secretariat, there is additional information about this working group on the Web at: + {% for url in urls %} + {{ url.name }}{% if not forloop.last %}, {% endif %} + {% endfor %} +

      +{% endif %} +{% endwith %} + +

      Charter for {% if group.state_id == "proposed" %}Proposed{% endif %} Working Group

      + +

      {{ group.charter_text|escape|format_charter|safe }}

      + +

      {% if group.state_id == "proposed" %}Proposed{% endif %} Milestones

      + +{% with group.milestones as milestones %} +{% include "wginfo/milestones.html" %} +{% endwith %} + +{% if milestones_in_review %} +

      + {{ milestones_in_review|length }} new milestone{{ milestones_in_review|pluralize }} +currently in Area Director review.

      +{% endif %} + +{% endblock %} diff --git a/ietf/templates/wginfo/group_documents.html b/ietf/templates/wginfo/group_documents.html new file mode 100644 index 000000000..a1adc68ef --- /dev/null +++ b/ietf/templates/wginfo/group_documents.html @@ -0,0 +1,18 @@ +{% extends "wginfo/group_base.html" %} + +{% block group_subtitle %}Documents{% endblock %} + +{% block group_content %} +
      + +{% include "doc/search/search_results.html" %} + +{% with docs_related as docs %}{% with meta_related as meta %}{% include "doc/search/search_results.html" %}{% endwith %}{% endwith %} + +
      +{% endblock group_content %} + +{% block js %} + + +{% endblock %} diff --git a/ietf/templates/wginfo/group_entry.txt b/ietf/templates/wginfo/group_entry.txt new file mode 100644 index 000000000..cd8d4b60c --- /dev/null +++ b/ietf/templates/wginfo/group_entry.txt @@ -0,0 +1,4 @@ +{% for chair in group.chairs %}{% if forloop.first %} Chair{{ forloop.revcounter|pluralize:": ,s:" }} {% else %} {% endif %}{{ chair.person.plain_name }} <{{ chair.email.address }}> +{% endfor %} WG Mail: {{ group.list_email }} + To Join: {{ group.list_subscribe }} + Archive: {{ group.list_archive }} diff --git a/ietf/templates/wginfo/group_entry_with_charter.txt b/ietf/templates/wginfo/group_entry_with_charter.txt new file mode 100644 index 000000000..abde2531a --- /dev/null +++ b/ietf/templates/wginfo/group_entry_with_charter.txt @@ -0,0 +1,48 @@ +{% autoescape off %}{% load ietf_filters %}{{ group.name }} ({{group.acronym}}) +{{ group.name|dashify }}{{ group.acronym|dashify }}--- + + Charter + Last Modified: {{ group.time.date|date }} + + Current Status: {{ group.state.name }} + + Chair{{ group.chairs|pluralize }}: +{% for chair in group.chairs %} {{ chair.person.name }} <{{chair.email.address}}> +{% endfor %} + {{ group.area.name}} Directors: +{% for ad in group.area.ads %} {{ ad.person.plain_name }} <{{ ad.email.address }}> +{% endfor %} +{% if group.areadirector %} {{ group.area.name }} Advisor: + {{ group.areadirector.person.plain_name }} <{{ group.areadirector.address }}> +{% endif %}{% if group.techadvisors %} + Tech Advisor{{ group.techadvisors|pluralize }}: +{% for techadvisor in group.techadvisors %} {{ techadvisor.person.plain_name }} <{{ techadvisor.email.address }}> +{% endfor %}{% endif %}{% if group.editors %} + Editor{{ group.editors|pluralize }}: +{% for editor in group.editors %} {{ editor.person.plain_name }} <{{ editor.email.address }}> +{% endfor %}{% endif %}{% if group.secretaries %} + Secretar{{ group.secretaries|pluralize:"y,ies" }}: +{% for secretary in group.secretaries %} {{ secretary.person.plain_name }} <{{ secretary.email.address }}> +{% endfor %}{% endif %} + Mailing Lists: + General Discussion: {{ group.list_email }} + To Subscribe: {{ group.list_subscribe }} + Archive: {{ group.list_archive }} + +Description of Working Group: + + {{ group.charter_text|indent }} + +Goals and Milestones: +{% for milestone in group.milestones %} {% if milestone.resolved %}{{ milestone.resolved }} {% else %}{{ milestone.due|date:"M Y" }}{% endif %} - {{ milestone.desc }} +{% endfor %} +Internet-Drafts: +{% for alias in group.drafts %} - {{ alias.document.title }} [{{ alias.name }}-{{ alias.document.rev }}] ({{ alias.document.pages }} pages) +{% endfor %} +{% if group.rfcs %}Requests for Comments: +{% for alias in group.rfcs %} {{ alias.name.upper }}: {{ alias.document.title}} ({{ alias.document.pages }} pages){% for r in alias.rel %} + * {{ r.action }} {{ r.target.name|upper }}{% endfor %}{% for r in alias.invrel %} + * {% if r.relationsship == "obs" %}{{ r.inverse_action|upper }}{% else %}{{ r.action }}{% endif %} {{ r.source.canonical_name|upper }}{% endfor %} +{% endfor %} +{% else %}No Requests for Comments{% endif %} +{% endautoescape %} diff --git a/ietf/templates/wginfo/history.html b/ietf/templates/wginfo/history.html index ed86d4324..bc1926609 100644 --- a/ietf/templates/wginfo/history.html +++ b/ietf/templates/wginfo/history.html @@ -1,15 +1,16 @@ -{% extends "wginfo/wg_base.html" %} +{% extends "wginfo/group_base.html" %} {% load ietf_filters %} -{% block wg_titledetail %}History{% endblock %} +{% block group_subtitle %}History{% endblock %} -{% block wg_content %} +{% block group_content %} {% load ietf_filters %} -

      WG History

      +

      Group History

      + {% for e in events %} diff --git a/ietf/templates/wginfo/wg-charter.txt b/ietf/templates/wginfo/wg-charter.txt deleted file mode 100644 index c0d8af0d4..000000000 --- a/ietf/templates/wginfo/wg-charter.txt +++ /dev/null @@ -1,47 +0,0 @@ -{% if USE_DB_REDESIGN_PROXY_CLASSES %}{% include "wginfo/wg-charterREDESIGN.txt" %}{% else %}{% load ietf_filters %}{{wg.group_acronym.name|safe}} ({{wg}}) -{{ wg.group_acronym.name|dashify }}{{ wg.group_acronym.acronym|dashify }}--- - - Charter - Last Modified: {{ wg.last_modified_date }} - - Current Status: {{ wg.status }} - - Chair{{ wg.chairs.count|pluralize:",s" }}: -{% for chair in wg.chairs %} {{ chair.person|safe }} <{{chair.person.email.1}}> -{% endfor %} - {{wg.area.area.area_acronym.name}} Directors: -{% for ad in wg.area_directors %} {{ ad.person|safe }} <{{ad.person.email.1}}> -{% endfor %} - {{wg.area.area.area_acronym.name}} Advisor: - {{ wg.area_director.person|safe }} <{{wg.area_director.person.email.1}}> -{% if wg.wgtechadvisor_set.count %} - Tech Advisor{{ wg.wgtechadvisor_set.count|pluralize:",s" }}: -{% for techadvisor in wg.wgtechadvisor_set.all %} {{ techadvisor.person|safe }} <{{techadvisor.person.email.1}}> -{% endfor %}{% endif %}{% if wg.wgeditor_set.count %} - Editor{{ wg.wgeditor_set.count|pluralize:",s" }}: -{% for editor in wg.wgeditor_set.all %} {{ editor.person|safe }} <{{editor.person.email.1}}> -{% endfor %}{% endif %}{% if wg.secretaries %} - Secretar{{ wg.secretaries.count|pluralize:"y,ies" }}: -{% for secretary in wg.secretaries %} {{ secretary.person|safe }} <{{secretary.person.email.1}}> -{% endfor %}{% endif %} - Mailing Lists: - General Discussion: {{ wg.email_address }} - To Subscribe: {{ wg.email_subscribe }} - Archive: {{ wg.email_archive }} - -Description of Working Group: - - {{ wg.charter_text|indent|safe }} - -Goals and Milestones: -{% for milestone in wg.milestones %} {% ifequal milestone.done 'Done' %}Done {% else %}{%ifequal milestone.expected_due_date.month 1 %}Jan{% endifequal %}{%ifequal milestone.expected_due_date.month 2 %}Feb{% endifequal %}{%ifequal milestone.expected_due_date.month 3 %}Mar{% endifequal %}{%ifequal milestone.expected_due_date.month 4 %}Apr{% endifequal %}{%ifequal milestone.expected_due_date.month 5 %}May{% endifequal %}{%ifequal milestone.expected_due_date.month 6 %}Jun{% endifequal %}{%ifequal milestone.expected_due_date.month 7 %}Jul{% endifequal %}{%ifequal milestone.expected_due_date.month 8 %}Aug{% endifequal %}{%ifequal milestone.expected_due_date.month 9 %}Sep{% endifequal %}{%ifequal milestone.expected_due_date.month 10 %}Oct{% endifequal %}{%ifequal milestone.expected_due_date.month 11 %}Nov{% endifequal %}{%ifequal milestone.expected_due_date.month 12 %}Dec{% endifequal %} {{ milestone.expected_due_date.year }}{% endifequal %} - {{ milestone.description|safe }} -{% endfor %} -Internet-Drafts: -{% for draft in wg.drafts %} - {{draft.title|safe}} [{{draft.filename}}-{{draft.revision}}] ({{ draft.txt_page_count }} pages) -{% endfor %} -{% if wg.rfcs %}Requests for Comments: -{% for rfc in wg.rfcs %} {{rfc}}: {{rfc.title|safe}} ({{ rfc.txt_page_count }} pages){% for obs in rfc.obsoletes%} - * {{obs.action}} RFC{{obs.rfc_acted_on_id}}{% endfor %}{% for obs in rfc.obsoleted_by%} - * {%ifequal obs.action 'Obsoletes'%}OBSOLETED BY{%else%}Updated by{%endifequal%} RFC{{obs.rfc_id}}{% endfor %} -{%endfor%} -{%else%}No Requests for Comments{% endif %}{% endif %} diff --git a/ietf/templates/wginfo/wg-charterREDESIGN.txt b/ietf/templates/wginfo/wg-charterREDESIGN.txt deleted file mode 100644 index 30e84e6ed..000000000 --- a/ietf/templates/wginfo/wg-charterREDESIGN.txt +++ /dev/null @@ -1,47 +0,0 @@ -{% load ietf_filters %}{{wg.name|safe}} ({{wg.acronym}}) -{{ wg.name|dashify }}{{ wg.acronym|dashify }}--- - - Charter - Last Modified: {{ wg.time.date }} - - Current Status: {{ wg.state.name }} - - Chair{{ wg.chairs|pluralize }}: -{% for chair in wg.chairs %} {{ chair.person.name|safe }} <{{chair.address}}> -{% endfor %} - {{wg.area.area.area_acronym.name}} Directors: -{% for ad in wg.area_directors %} {{ ad.person|safe }} <{{ad.address}}> -{% endfor %} - {{wg.area.area.area_acronym.name}} Advisor: - {{ wg.areadirector.person.name|safe }} <{{wg.areadirector.address}}> -{% if wg.techadvisors %} - Tech Advisor{{ wg.techadvisors|pluralize }}: -{% for techadvisor in wg.techadvisors %} {{ techadvisor.person.plain_name|safe }} <{{techadvisor.address}}> -{% endfor %}{% endif %}{% if wg.editors %} - Editor{{ wg.editors|pluralize }}: -{% for editor in wg.editors %} {{ editor.person.plain_name|safe }} <{{editor.address}}> -{% endfor %}{% endif %}{% if wg.secretaries %} - Secretar{{ wg.secretaries|pluralize:"y,ies" }}: -{% for secretary in wg.secretaries %} {{ secretary.person.plain_name|safe }} <{{secretary.address}}> -{% endfor %}{% endif %} - Mailing Lists: - General Discussion: {{ wg.email_address }} - To Subscribe: {{ wg.email_subscribe }} - Archive: {{ wg.email_archive }} - -Description of Working Group: - - {{ wg.charter_text|indent|safe }} - -Goals and Milestones: -{% for milestone in wg.milestones %} {% if milestone.resolved %}{{ milestone.resolved }} {% else %}{{ milestone.due|date:"M Y" }}{% endif %} - {{ milestone.desc|safe }} -{% endfor %} -Internet-Drafts: -{% for alias in wg.drafts %} - {{alias.document.title|safe}} [{{alias.name}}-{{alias.document.rev}}] ({{ alias.document.pages }} pages) -{% endfor %} -{% if wg.rfcs %}Requests for Comments: -{% for alias in wg.rfcs %} {{ alias.name.upper }}: {{ alias.document.title|safe}} ({{ alias.document.pages }} pages){% for r in alias.rel %} - * {{ r.action }} {{ r.target.name|upper }}{% endfor %}{% for r in alias.invrel %} - * {% ifequal r.relationsship "obs" %}{{ r.inverse_action|upper }}{% else %}{{ r.action }}{% endifequal %} {{ r.source.canonical_name|upper }}{% endfor %} -{%endfor%} -{%else%}No Requests for Comments{% endif %} diff --git a/ietf/templates/wginfo/wg-dir.html b/ietf/templates/wginfo/wg-dir.html deleted file mode 100644 index b9cfb208b..000000000 --- a/ietf/templates/wginfo/wg-dir.html +++ /dev/null @@ -1,99 +0,0 @@ -{% extends "base.html" %} -{# Copyright The IETF Trust 2009, All Rights Reserved #} -{% comment %} -Portion Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -All rights reserved. Contact: Pasi Eronen - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * Neither the name of the Nokia Corporation and/or its - subsidiary(-ies) nor the names of its contributors may be used - to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -{% endcomment %} - -{% block title %}Active IETF Working Groups{% endblock %} - -{% block morecss %} -.ietf-wg-table { width: 100%; max-width:50em; } -.ietf-wg-table tr { vertical-align:top; } -{% endblock morecss %} - -{% block content %} -

      Active IETF Working Groups

      - -

      See also: - Concluded Working Groups (www.ietf.org), - Concluded Working Groups (tools.ietf.org), - Historic Charters. -

      - - {% for area in areas|dictsort:"area_acronym.name" %} -

      {{ area.area_acronym.name }}

      - - {% for ad in area.areadirector_set.all|dictsort:"person.last_name" %} - {% if forloop.first %} -

      Area Director{{ forloop.revcounter|pluralize }}:

      -
      DateByText
      {{ e.time|date:"Y-m-d"}}
      - {% endif %} - - {% if forloop.last %} -
        {{ ad.person }} <{{ ad.person.email.1 }}>
      - {% endif %} - {% endfor %} - - {% for url in area.additional_urls %} - {% if forloop.first %} -

      Area Specific Web Page{{ forloop.revcounter|pluralize}}:

      -

      - {% endif %} - {{ url.description }}{% if not forloop.last %}
      {% endif %} - {% if forloop.last %} -

      - {% endif %} - {% endfor %} - - {% for wg in area.active_wgs %} - {% if forloop.first %} -

      Active Working Groups:

      -
      - - {% endif %} - - - - - - - {% if forloop.last %} -
      {{ wg }}{% for ad in area.areadirector_set.all|dictsort:"person.last_name" %}{% ifequal ad wg.area_director %}{% endifequal %}{% endfor %}{{ wg.group_acronym.name }}{% for chair in wg.chairs %}{{chair.person}}{% if not forloop.last %}, {% endif %}{% endfor %}
      -
      - {% endif %} - {% empty %} -

      No Active Working Groups

      - {% endfor %}{# wg #} - - {% endfor %}{# area #} -{% endblock %} diff --git a/ietf/templates/wginfo/wg_charter.html b/ietf/templates/wginfo/wg_charter.html deleted file mode 100644 index e4797950b..000000000 --- a/ietf/templates/wginfo/wg_charter.html +++ /dev/null @@ -1,182 +0,0 @@ -{% extends "wginfo/wg_base.html" %} -{% comment %} -Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -All rights reserved. Contact: Pasi Eronen - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * Neither the name of the Nokia Corporation and/or its - subsidiary(-ies) nor the names of its contributors may be used - to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -{% endcomment %} -{% load ietf_filters %} -{% block wg_titledetail %}Charter{% endblock %} - -{% block morecss %} -{{ block.super }} -h2 a.button { margin-left: 0.5em; font-size: 13px; } -{% endblock %} - -{% block wg_content %} -
      -{% if concluded %} -Note: The data for concluded WGs -is occasionally incorrect. -{% endif %} - - - - - - - - - - - {% if wg.parent %} - - {% endif %} - - - - - - - - - - - - - - - - - - - - - - {% if wg.techadvisors %} - - - - - {% endif %} - {% if wg.editors %} - - - {% endif %} - {% if wg.secretaries %} - - - - - {% endif %} - - - - - - - - {% if not concluded %} - - - - - {% endif %} - -
      Group
      Name:{{ wg.name }}
      Acronym:{{ wg.acronym }}
      Area:{{ wg.parent.name }} ({{ wg.parent.acronym }})
      State:{{ wg.state.name }} - {% if requested_close %} - (but in the process of being closed) - {% endif %} -
      Charter: - {% if wg.charter %} - {{ wg.charter.name }}-{{ wg.charter.rev }} ({{ wg.charter.get_state.name }}) - {% else %} - none - {% if user|has_role:"Area Director,Secretariat" %} - - Submit Charter - {% endif %} - {% endif %} -
      Personnel
      Chair{{ wg.chairs|pluralize }}: - {% for chair in wg.chairs %} - {{ chair.person.plain_name }} <{{ chair.address }}>
      - {% endfor %} -
      Area Director: - {% if not wg.ad %}?{% else %} - {{ wg.ad.plain_name }} <{{ wg.areadirector.address }}>{% endif %} -
      Tech Advisor{{ wg.techadvisors|pluralize }}: - {% for techadvisor in wg.techadvisors %} - {{ techadvisor.person.plain_name }} <{{ techadvisor.address }}>
      - {% endfor %} -
      Editor{{ wg.editors|pluralize }}: - {% for editor in wg.editors %} - {{ editor.person.plain_name }} <{{ editor.address }}>
      - {% endfor %} -
      Secretar{{ wg.secretaries|pluralize:"y,ies" }}: - {% for secretary in wg.secretaries %} - {{ secretary.person.plain_name }} <{{ secretary.address }}>
      - {% endfor %} -
      Mailing List
      Address:{{ wg.email_address|urlize }}
      To Subscribe:{{ wg.email_subscribe|urlize }}
      Archive:{{ wg.clean_email_archive|urlize }}
      Jabber Chat
      Room Address:xmpp:{{ wg.acronym }}@jabber.ietf.org
      Logs:http://jabber.ietf.org/logs/{{ wg.acronym }}/
      - -{% if user|has_role:"Area Director,Secretariat" %} -
      - {% for name, url in actions %} - {{ name }} - {% if not forloop.last %}|{% endif %} - {% endfor %} -
      -{% endif %} -
      - -{% if wg.additional_urls %} -

      In addition to the charter maintained by the IETF Secretariat, there is additional information about this working group on the Web at: -{% for url in wg.additional_urls %} -{{ url.name }}{% if not forloop.last %}, {% endif %} -{% endfor %} -

      -{% endif %} - -

      Charter for {% if wg.state_id == "proposed" %}Proposed{% endif %} Working Group

      -

      {{ wg.charter_text|escape|format_charter|safe }}

      - -

      {% if wg.state_id == "proposed" %}Proposed{% endif %} Milestones -{% if wg.state_id != "proposed" %} -{% if user|has_role:"Area Director,Secretariat" or is_chair %} -Add or edit milestones -{% endif %} -{% endif %} -

      - -{% with wg.milestones as milestones %}{% include "wginfo/milestones.html" %}{% endwith %} - -{% if milestones_in_review %} -

      + {{ milestones_in_review|length }} new milestone{{ milestones_in_review|pluralize }} -currently in Area Director review.

      -{% endif %} -{% endblock wg_content %} diff --git a/ietf/templates/wginfo/wg_documents.html b/ietf/templates/wginfo/wg_documents.html deleted file mode 100644 index f0fb4529b..000000000 --- a/ietf/templates/wginfo/wg_documents.html +++ /dev/null @@ -1,50 +0,0 @@ -{% extends "wginfo/wg_base.html" %} -{% comment %} -Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -All rights reserved. Contact: Pasi Eronen - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * Neither the name of the Nokia Corporation and/or its - subsidiary(-ies) nor the names of its contributors may be used - to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -{% endcomment %} -{% block wg_titledetail %}Documents{% endblock %} - -{% block wg_content %} -
      - -{% include "doc/search/search_results.html" %} - -{% with docs_related as docs %}{% include "doc/search/search_results.html" %}{% endwith %} - -
      -{% endblock wg_content %} - -{% block js %} - - -{% endblock %} diff --git a/ietf/templates/wginfo/wg_documents.txt b/ietf/templates/wginfo/wg_documents.txt deleted file mode 100644 index 69302b533..000000000 --- a/ietf/templates/wginfo/wg_documents.txt +++ /dev/null @@ -1,2 +0,0 @@ -{% load ietf_filters %}{% regroup docs by get_state as grouped_docs %}{% for doc_group in grouped_docs %}{% for doc in doc_group.list %}{% include "wginfo/wg_documents_entry.txt" %}{% endfor %}{% endfor %}{% regroup docs_related by get_state as grouped_docs_related %}{% for doc_group in grouped_docs_related %}{% for doc in doc_group.list %}Related {% include "wginfo/wg_documents_entry.txt" %}{% endfor %}{% endfor %} - diff --git a/ietf/templates/wginfo/wg_documents_entry.txt b/ietf/templates/wginfo/wg_documents_entry.txt deleted file mode 100644 index ad034af62..000000000 --- a/ietf/templates/wginfo/wg_documents_entry.txt +++ /dev/null @@ -1 +0,0 @@ -{% load ietf_filters %}{{doc_group.grouper}} {% if doc.get_state_slug == "rfc" %}{{doc.rfc_number}} {{doc.title|clean_whitespace}}{% else %}{{doc.name}}-{{doc.rev}} {{doc.title|clean_whitespace}}{% endif %} diff --git a/ietf/templates/wginfo/wg_summary.txt b/ietf/templates/wginfo/wg_summary.txt deleted file mode 100644 index 603d9e2f8..000000000 --- a/ietf/templates/wginfo/wg_summary.txt +++ /dev/null @@ -1,5 +0,0 @@ -{% for chair in wg.wgchair_set.all %}{% if forloop.first %} Chair{{ forloop.revcounter|pluralize:": ,s:" }} {% else %} {% endif %}{{ chair.person|safe }} <{{ chair.person.email.1 }}> -{% endfor %} WG Mail: {{ wg.email_address }} - To Join: {{ wg.email_subscribe }}{%if wg.email_keyword %} - In Body: {{ wg.email_keyword|safe }}{% endif %} - Archive: {{ wg.email_archive }} diff --git a/ietf/urls.py b/ietf/urls.py index 861f5fc55..536dfe6ea 100644 --- a/ietf/urls.py +++ b/ietf/urls.py @@ -7,13 +7,12 @@ from django.contrib import admin from ietf.iesg.feeds import IESGAgenda from ietf.doc.feeds import DocumentChanges, InLastCall from ietf.ipr.feeds import LatestIprDisclosures -from ietf.proceedings.feeds import LatestWgProceedingsActivity +from ietf.meeting.feeds import LatestMeetingMaterial from ietf.liaisons.feeds import Liaisons from ietf.wgcharter.feeds import GroupChanges from ietf.liaisons.sitemaps import LiaisonMap from ietf.ipr.sitemaps import IPRMap -from ietf.announcements.sitemaps import NOMCOMAnnouncementsMap from django.conf import settings @@ -36,13 +35,12 @@ feeds = { 'group-changes': GroupChanges, 'ipr': LatestIprDisclosures, 'liaison': Liaisons, - 'wg-proceedings' : LatestWgProceedingsActivity + 'wg-proceedings' : LatestMeetingMaterial, } sitemaps = { 'liaison': LiaisonMap, 'ipr': IPRMap, - 'nomcom-announcements': NOMCOMAnnouncementsMap, } urlpatterns = patterns('', @@ -50,7 +48,7 @@ urlpatterns = patterns('', (r'^accounts/', include('ietf.ietfauth.urls')), (r'^admin/', include(admin.site.urls)), (r'^admin/doc/', include('django.contrib.admindocs.urls')), - (r'^ann/', include('ietf.announcements.urls')), + (r'^ann/', include('ietf.nomcom.redirect_ann_urls')), (r'^community/', include('ietf.community.urls')), (r'^cookies/', include('ietf.cookies.urls')), (r'^doc/', include('ietf.doc.urls')), @@ -71,7 +69,6 @@ urlpatterns = patterns('', (r'^secr/', include('ietf.secr.urls')), (r'^sitemap-(?P
      .+).xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps}), (r'^sitemap.xml$', 'django.contrib.sitemaps.views.index', { 'sitemaps': sitemaps}), - (r'^streams/', include('ietf.ietfworkflows.urls')), (r'^submit/', include('ietf.submit.urls')), (r'^sync/', include('ietf.sync.urls')), (r'^wg/', include('ietf.wginfo.urls')), diff --git a/ietf/utils/__init__.py b/ietf/utils/__init__.py index 8a22d0761..087b887d4 100644 --- a/ietf/utils/__init__.py +++ b/ietf/utils/__init__.py @@ -1,7 +1,6 @@ # Copyright The IETF Trust 2007, All Rights Reserved from log import log -from cache_foreign_key import FKAsOneToOne from draft_search import normalize_draftname from test_utils import TestCase diff --git a/ietf/utils/accesstoken.py b/ietf/utils/accesstoken.py new file mode 100644 index 000000000..da07c9a3a --- /dev/null +++ b/ietf/utils/accesstoken.py @@ -0,0 +1,15 @@ +import time, random, hashlib + +from django.conf import settings + +def generate_random_key(max_length=32): + """Generate a random access token.""" + return hashlib.sha256(settings.SECRET_KEY + ("%.16f" % time.time()) + ("%.16f" % random.random())).hexdigest()[:max_length] + +def generate_access_token(key, max_length=32): + """Make an access token out of key.""" + assert key, "key must not be empty" + # we hash it with the private key to make sure only we can + # generate and use the final token - so storing the key in the + # database is safe + return hashlib.sha256(settings.SECRET_KEY + key).hexdigest()[:max_length] diff --git a/ietf/utils/broken_foreign_key.py b/ietf/utils/broken_foreign_key.py deleted file mode 100644 index da5648282..000000000 --- a/ietf/utils/broken_foreign_key.py +++ /dev/null @@ -1,43 +0,0 @@ -from django.db import models - -class InvalidToNoneOverrider(object): - """Converts invalid ids to None before returning them to Django.""" - def __init__(self, cls, fieldname, null_values): - self.fieldname = fieldname - self.real_field = getattr(cls, fieldname) - self.null_values = null_values - - def __get__(self, instance, instance_type=None): - if instance is None: # calls on the class - return self - - v = getattr(instance, u"%s_id" % self.fieldname) - if v == None or v in self.null_values: - return None - else: - # forward to real field - return self.real_field.__get__(instance, instance_type) - - def __set__(self, instance, value): - # forward to real field - self.real_field.__set__(instance, value) - -class BrokenForeignKey(models.ForeignKey): - """ForeignKey for when some null values aren't NULL in the database. - - Django is strict with foreign keys, invalid ids result in - DoesNotExist in inconvenient places. With this field, invalid ids - are overridden to return None. Takes a keyword argument - 'null_values' to determine which ids should be considered - invalid and equivalent to NULL.""" - - def __init__(self, *args, **kwargs): - self.broken_null_values = kwargs.pop('null_values', (0,)) - super(self.__class__, self).__init__(*args, **kwargs) - -def broken_foreign_key_class_prepared_handler(sender, **kwargs): - for f in sender._meta.fields: - if type(f) == BrokenForeignKey: - setattr(sender, f.name, InvalidToNoneOverrider(sender, f.name, f.broken_null_values)) - -models.signals.class_prepared.connect(broken_foreign_key_class_prepared_handler) diff --git a/ietf/utils/cache_foreign_key.py b/ietf/utils/cache_foreign_key.py deleted file mode 100644 index cbf43f8f7..000000000 --- a/ietf/utils/cache_foreign_key.py +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright The IETF Trust 2007, All Rights Reserved - -# Caching accessor for the reverse of a ForeignKey relatinoship -# Started by axiak on #django -class FKAsOneToOne(object): - def __init__(self, field, reverse = False, query = None): - self.field = field - self.reverse = reverse - self.query = query - - def __get_attr(self, instance): - if self.reverse: - field_name = '%s_set' % self.field - else: - field_name = self.field - return getattr(instance, field_name) - - def __get__(self, instance, Model): - if not hasattr(instance, '_field_values'): - instance._field_values = {} - try: - return instance._field_values[self.field] - except KeyError: - pass - - if self.reverse: - value_set = self.__get_attr(instance).all() - if self.query: - value_set = value_set.filter(self.query) - try: - instance._field_values[self.field] = value_set[0] - except IndexError: - instance._field_values[self.field] = None - else: - instance._field_values[self.field] = self.__get_attr(instance) - - return instance._field_values[self.field] - - # We don't try to be smart and define __set__ to adjust the other - # end of the relation since that could require setting several - # fields, failing silently with a naive implementation. Updating - # the other end is the responsibility of the caller. diff --git a/ietf/utils/cached_lookup_field.py b/ietf/utils/cached_lookup_field.py deleted file mode 100644 index 5c56ab7c8..000000000 --- a/ietf/utils/cached_lookup_field.py +++ /dev/null @@ -1,34 +0,0 @@ -from django.core.exceptions import ObjectDoesNotExist - -class CachedLookupField(object): - """Django field for looking up and caching another object, like a - ForeignKey only you must supply a function for doing the lookup - yourself (and there's no reverse magic). Useful in case a real foreign - key is missing. "lookup" is called on the first access to the field - and gets the instance as sole argument; it should return an object - or throw a DoesNotExist exception (which is normalized to None), e.g. - - class A(django.db.models.Model): - foo = CachedLookupField(lookup=lambda self: Foo.objects.get(key=self.key)) - key = CharField() - """ - - def __init__(self, lookup): - self.lookup = lookup - self.value = None - self.value_cached = False - - def __get__(self, instance, instance_type=None): - if not instance_type: - return self - - if not self.value_cached: - try: - self.value = self.lookup(instance) - except ObjectDoesNotExist: - self.value = None - self.value_cached = True - - return self.value - - diff --git a/ietf/utils/fields.py b/ietf/utils/fields.py index a564f9ba5..9508bd31e 100644 --- a/ietf/utils/fields.py +++ b/ietf/utils/fields.py @@ -1,6 +1,5 @@ from django import forms -from django.forms.util import ValidationError -from django.core.validators import email_re +from django.core.validators import validate_email, ValidationError class MultiEmailField(forms.CharField): @@ -8,15 +7,17 @@ class MultiEmailField(forms.CharField): def clean(self, value): super(MultiEmailField, self).clean(value) - if value: - if value.endswith(','): - value = value[:-1] - emails = map(unicode.strip, value.split(',')) - else: + if not value: return value + if value.endswith(','): + value = value[:-1] + emails = [v.strip() for v in value.split(',') if v.strip()] + for email in emails: - if not email_re.match(email): + try: + validate_email(email) + except ValidationError: raise ValidationError("This is not a valid comma separated email list.") return value diff --git a/ietf/utils/mail.py b/ietf/utils/mail.py index a99962b36..669fda92b 100644 --- a/ietf/utils/mail.py +++ b/ietf/utils/mail.py @@ -176,8 +176,13 @@ def send_mail_mime(request, to, frm, subject, msg, cc=None, extra=None, toUser=F if extra: for k, v in extra.items(): if v: - msg[k] = v - if test_mode or settings.SERVER_MODE == 'production': + msg[k] = v + # start debug server with python -m smtpd -n -c DebuggingServer localhost:2025 + # then put USING_DEBUG_EMAIL_SERVER=True and EMAIL_HOST='localhost' + # and EMAIL_PORT=2025 in settings_local.py + debugging = getattr(settings, "USING_DEBUG_EMAIL_SERVER", False) and settings.EMAIL_HOST == 'localhost' and settings.EMAIL_PORT == 2025 + + if test_mode or debugging or settings.SERVER_MODE == 'production': send_smtp(msg, bcc) elif settings.SERVER_MODE == 'test': if toUser: @@ -188,7 +193,7 @@ def send_mail_mime(request, to, frm, subject, msg, cc=None, extra=None, toUser=F copy_to = settings.EMAIL_COPY_TO except AttributeError: copy_to = "ietf.tracker.archive+%s@gmail.com" % settings.SERVER_MODE - if copy_to and not test_mode: # if we're running automated tests, this copy is just annoying + if copy_to and not test_mode and not debugging: # if we're running automated tests, this copy is just annoying if bcc: msg['X-Tracker-Bcc']=bcc copy_email(msg, copy_to,originalBcc=bcc) diff --git a/ietf/utils/proxy.py b/ietf/utils/proxy.py deleted file mode 100644 index 3d445b738..000000000 --- a/ietf/utils/proxy.py +++ /dev/null @@ -1,282 +0,0 @@ -# some helpers for the proxy layer bridging the gap between the legacy -# and the redesigned schema, eventually this should all go - -from django.db.models.manager import Manager -from django.db.models.query import QuerySet - -def proxy_personify_role(role): - """Turn role into person with email() method using email from role.""" - p = role.person - p.email = lambda: (p.plain_name(), role.email.address) - return p - -def proxy_role_email(e): - """Add email() method to person on email.""" - e.person.email = lambda: (e.person.plain_name(), e.address) - return e - -def chunks(l, n): - """Split list l up in chunks of max size n.""" - return (l[i:i+n] for i in xrange(0, len(l), n)) - -class TranslatingQuerySet(QuerySet): - """Query set that can do some simple mappings of the filter args.""" - - def translated_args(self, args): - trans = self.translated_attrs - res = [] - for a in args: - if a.startswith("-"): - prefix = "-" - a = a[1:] - else: - prefix = "" - - if a in trans: - t = trans[a] - if callable(t): - t, _ = t(None) - - if t: - res.append(prefix + t) - else: - res.append(prefix + a) - return res - - def translated_kwargs(self, kwargs): - trans = self.translated_attrs - res = dict() - for k, v in kwargs.iteritems(): - if k in trans: - t = trans[k] - if callable(t): - ts = t(v) - else: - ts = (t, v) - - for t, v in chunks(ts, 2): - if t: - res[t] = v - else: - res[k] = v - return res - - # overridden methods - def _clone(self, *args, **kwargs): - c = super(TranslatingQuerySet, self)._clone(*args, **kwargs) - c.translated_attrs = self.translated_attrs - return c - - def dates(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).dates(*args, **kwargs) - - def distinct(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).distinct(*args, **kwargs) - - def extra(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).extra(*args, **kwargs) - - def get(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).get(*args, **kwargs) - - def get_or_create(self, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).get_or_create(**kwargs) - - def create(self, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).create(**kwargs) - - def filter(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).filter(*args, **kwargs) - - def aggregate(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).aggregate(*args, **kwargs) - - def annotate(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).annotate(*args, **kwargs) - - def complex_filter(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).complex_filter(*args, **kwargs) - - def exclude(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).exclude(*args, **kwargs) - - def in_bulk(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).in_bulk(*args, **kwargs) - - def iterator(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).iterator(*args, **kwargs) - - def latest(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).latest(*args, **kwargs) - - def order_by(self, *args, **kwargs): - args = self.translated_args(args) - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).order_by(*args, **kwargs) - - def select_related(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).select_related(*args, **kwargs) - - def values(self, *args, **kwargs): - args = self.translated_args(args) - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).values(*args, **kwargs) - - def values_list(self, *args, **kwargs): - args = self.translated_args(args) - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).values_list(*args, **kwargs) - - def update(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).update(*args, **kwargs) - - def reverse(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).reverse(*args, **kwargs) - - def defer(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).defer(*args, **kwargs) - - def only(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).only(*args, **kwargs) - - def _insert(self, values, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return insert_query(self.model, values, **kwargs) - - def _update(self, values, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self)._update(values, **kwargs) - -class TranslatingManager(Manager): - """Translates keyword arguments for the ORM, for use in proxy - wrapping, e.g. given trans={'foo': 'bar'} it will transform a - lookup of the field foo to a lookup on the field bar. The right - hand side can either be a string or a function which is called - with the right-hand side to transform it.""" - - def __init__(self, trans, always_filter=None): - super(TranslatingManager, self).__init__() - self.translated_attrs = trans - self.always_filter = always_filter - - def get_query_set(self): - qs = TranslatingQuerySet(self.model) - qs.translated_attrs = self.translated_attrs - if self.always_filter: - qs = qs.filter(**self.always_filter) - return qs - - # def dates(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().dates(*args, **kwargs) - - # def distinct(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().distinct(*args, **kwargs) - - # def extra(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().extra(*args, **kwargs) - - # def get(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().get(*args, **kwargs) - - # def get_or_create(self, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().get_or_create(**kwargs) - - # def create(self, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().create(**kwargs) - - # def filter(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().filter(*args, **kwargs) - - # def aggregate(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().aggregate(*args, **kwargs) - - # def annotate(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().annotate(*args, **kwargs) - - # def complex_filter(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().complex_filter(*args, **kwargs) - - # def exclude(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().exclude(*args, **kwargs) - - # def in_bulk(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().in_bulk(*args, **kwargs) - - # def iterator(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().iterator(*args, **kwargs) - - # def latest(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().latest(*args, **kwargs) - - # def order_by(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().order_by(*args, **kwargs) - - # def select_related(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().select_related(*args, **kwargs) - - # def values(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().values(*args, **kwargs) - - # def values_list(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().values_list(*args, **kwargs) - - # def update(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().update(*args, **kwargs) - - # def reverse(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().reverse(*args, **kwargs) - - # def defer(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().defer(*args, **kwargs) - - # def only(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().only(*args, **kwargs) - - # def _insert(self, values, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return insert_query(self.model, values, **kwargs) - - # def _update(self, values, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set()._update(values, **kwargs) diff --git a/ietf/utils/test_data.py b/ietf/utils/test_data.py index 8d697b278..63e9fbc99 100644 --- a/ietf/utils/test_data.py +++ b/ietf/utils/test_data.py @@ -1,7 +1,7 @@ from django.conf import settings from django.contrib.auth.models import User -from ietf.iesg.models import TelechatDate, WGAction +from ietf.iesg.models import TelechatDate from ietf.ipr.models import IprDetail, IprDocAlias from ietf.meeting.models import Meeting from ietf.doc.models import * @@ -112,15 +112,6 @@ def make_test_data(): ) group.charter = charter group.save() - WGAction.objects.create( - pk=group.pk, - note="", - status_date=datetime.date.today(), - agenda=1, - token_name="Aread", - category=13, - telechat_date=date2 - ) # persons @@ -396,10 +387,15 @@ def make_test_data(): 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(), ) diff --git a/ietf/utils/test_runner.py b/ietf/utils/test_runner.py index b19b454ca..e97d0f2c1 100644 --- a/ietf/utils/test_runner.py +++ b/ietf/utils/test_runner.py @@ -32,7 +32,7 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -import socket +import socket, re, os from django.conf import settings from django.template import TemplateDoesNotExist @@ -44,6 +44,7 @@ import debug import ietf.utils.mail loaded_templates = set() +visited_urls = set() test_database_name = None old_destroy = None old_create = None @@ -74,6 +75,77 @@ def template_coverage_loader(template_name, dirs): template_coverage_loader.is_usable = True +class RecordUrlsMiddleware(object): + def process_request(self, request): + visited_urls.add(request.path) + +def get_patterns(module): + all = [] + try: + patterns = module.urlpatterns + except AttributeError: + patterns = [] + for item in patterns: + try: + subpatterns = get_patterns(item.urlconf_module) + except: + subpatterns = [""] + for sub in subpatterns: + if not sub: + all.append(item.regex.pattern) + elif sub.startswith("^"): + all.append(item.regex.pattern + sub[1:]) + else: + all.append(item.regex.pattern + ".*" + sub) + return all + +def check_url_coverage(): + patterns = get_patterns(ietf.urls) + + IGNORED_PATTERNS = ("admin",) + + patterns = [(p, re.compile(p)) for p in patterns if p[1:].split("/")[0] not in IGNORED_PATTERNS] + + covered = set() + for url in visited_urls: + for pattern, compiled in patterns: + if pattern not in covered and compiled.match(url[1:]): # strip leading / + covered.add(pattern) + break + + missing = list(set(p for p, compiled in patterns) - covered) + + if missing: + print "The following URL patterns were not tested" + for pattern in sorted(missing): + print " Not tested", pattern + +def get_templates(): + templates = set() + # Should we teach this to use TEMPLATE_DIRS? + templatepath = os.path.join(settings.BASE_DIR, "templates") + for root, dirs, files in os.walk(templatepath): + if ".svn" in dirs: + dirs.remove(".svn") + relative_path = root[len(templatepath)+1:] + for file in files: + if file.endswith("~") or file.startswith("#"): + continue + if relative_path == "": + templates.add(file) + else: + templates.add(os.path.join(relative_path, file)) + return templates + +def check_template_coverage(): + all_templates = get_templates() + + not_loaded = list(all_templates - loaded_templates) + if not_loaded: + print "The following templates were never loaded during test" + for t in sorted(not_loaded): + print " Not loaded", t + def run_tests_1(test_labels, *args, **kwargs): global old_destroy, old_create, test_database_name from django.db import connection @@ -81,18 +153,33 @@ def run_tests_1(test_labels, *args, **kwargs): connection.creation.__class__.create_test_db = safe_create_1 old_destroy = connection.creation.__class__.destroy_test_db connection.creation.__class__.destroy_test_db = safe_destroy_0_1 - if not test_labels: + + check_coverage = not test_labels + + if check_coverage: settings.TEMPLATE_LOADERS = ('ietf.utils.test_runner.template_coverage_loader',) + settings.TEMPLATE_LOADERS - test_labels = [x.split(".")[-1] for x in settings.INSTALLED_APPS if x.startswith("ietf")] + ['redirects.TemplateCoverageTestCase',] + settings.MIDDLEWARE_CLASSES = ('ietf.utils.test_runner.RecordUrlsMiddleware',) + settings.MIDDLEWARE_CLASSES + + if not test_labels: + test_labels = [x.split(".")[-1] for x in settings.INSTALLED_APPS if x.startswith("ietf")] + if settings.SITE_ID != 1: print " Changing SITE_ID to '1' during testing." settings.SITE_ID = 1 + if settings.TEMPLATE_STRING_IF_INVALID != '': print " Changing TEMPLATE_STRING_IF_INVALID to '' during testing." settings.TEMPLATE_STRING_IF_INVALID = '' + assert(not settings.IDTRACKER_BASE_URL.endswith('/')) - kwargs["verbosity"] = kwargs["verbosity"] - return django_run_tests(test_labels, *args, **kwargs) + + results = django_run_tests(test_labels, *args, **kwargs) + + if check_coverage: + check_url_coverage() + check_template_coverage() + + return results def run_tests(*args, **kwargs): # Tests that involve switching back and forth between the real diff --git a/ietf/wgchairs/.gitignore b/ietf/wgchairs/.gitignore deleted file mode 100644 index a74b07aee..000000000 --- a/ietf/wgchairs/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/*.pyc diff --git a/ietf/wgchairs/__init__.py b/ietf/wgchairs/__init__.py deleted file mode 100644 index e8d53c9a3..000000000 --- a/ietf/wgchairs/__init__.py +++ /dev/null @@ -1,18 +0,0 @@ -# coding: latin-1 - -from types import ModuleType -import urls, models, views, forms, accounts - -# These people will be sent a stack trace if there's an uncaught exception in -# code any of the modules imported above: -DEBUG_EMAILS = [ - ('Emilio A. Sánchez', 'esanchez@yaco.es'), -] - -for k in locals().keys(): - m = locals()[k] - if isinstance(m, ModuleType): - if hasattr(m, "DEBUG_EMAILS"): - DEBUG_EMAILS += list(getattr(m, "DEBUG_EMAILS")) - setattr(m, "DEBUG_EMAILS", DEBUG_EMAILS) - diff --git a/ietf/wgchairs/accounts.py b/ietf/wgchairs/accounts.py deleted file mode 100644 index c6b5b7645..000000000 --- a/ietf/wgchairs/accounts.py +++ /dev/null @@ -1,108 +0,0 @@ -from django.conf import settings -from ietf.group.models import Role - -def is_secretariat(user): - if not user or not user.is_authenticated(): - return False - return bool(user.groups.filter(name='Secretariat')) - - -def is_area_director_for_group(person, group): - return bool(group.area.area.areadirector_set.filter(person=person).count()) - -def is_area_director_for_groupREDESIGN(person, group): - return bool(Role.objects.filter(group=group.parent, person=person, name__in=("ad", "pre-ad"))) - - -def is_group_chair(person, group): - if group.chairs().filter(person=person): - return True - return False - -def is_group_chairREDESIGN(person, group): - return bool(Role.objects.filter(group=group, person=person, name="chair")) - - -def is_group_delegate(person, group): - return bool(group.wgdelegate_set.filter(person=person).count()) - -def is_group_delegateREDESIGN(person, group): - return bool(Role.objects.filter(group=group, person=person, name="delegate")) - - -def get_person_for_user(user): - try: - return user.get_profile().person() - except: - return None - - -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - from ietf.liaisons.accounts import is_secretariat, get_person_for_user - is_area_director_for_group = is_area_director_for_groupREDESIGN - is_group_chair = is_group_chairREDESIGN - is_group_delegate = is_group_delegateREDESIGN - - -def can_do_wg_workflow_in_group(user, group): - person = get_person_for_user(user) - if not person: - return False - return (is_secretariat(user) or is_group_chair(person, group)) - - -def can_do_wg_workflow_in_document(user, document): - person = get_person_for_user(user) - if not person or not document.group: - return False - return (is_secretariat(user) or can_do_wg_workflow_in_group(document.group.ietfwg)) - - -def can_manage_workflow_in_group(user, group): - person = get_person_for_user(user) - if not person: - return False - return (is_secretariat(user) or is_group_chair(person, group)) - - -def can_manage_delegates_in_group(user, group): - person = get_person_for_user(user) - if not person: - return False - return (is_secretariat(user) or is_group_chair(person, group)) - - -def can_manage_shepherds_in_group(user, group): - person = get_person_for_user(user) - if not person: - return False - return (is_secretariat(user) or is_group_chair(person, group)) - - -def can_manage_shepherd_of_a_document(user, document): - person = get_person_for_user(user) - if not person or not document.group: - return False - return can_manage_shepherds_in_group(user, document.group.ietfwg) - - -def can_manage_writeup_of_a_document_no_state(user, document): - person = get_person_for_user(user) - if not person or not document.group: - return False - group = document.group.ietfwg - return (is_secretariat(user) or - is_group_chair(person, group) or - is_area_director_for_group(person, group) or - is_group_delegate(person, group)) - - -def can_manage_writeup_of_a_document(user, document): - person = get_person_for_user(user) - if not person or not document.group: - return False - return (can_manage_writeup_of_a_document_no_state(user, document) or - person == document.shepherd) - - - diff --git a/ietf/wgchairs/forms.py b/ietf/wgchairs/forms.py deleted file mode 100644 index 001acec7c..000000000 --- a/ietf/wgchairs/forms.py +++ /dev/null @@ -1,478 +0,0 @@ -import datetime - -from django import forms -from django.conf import settings -from django.db.models import Q -from django.forms.models import BaseModelFormSet -from django.template.loader import render_to_string -from django.utils.safestring import mark_safe - -from ietf.wgchairs.models import WGDelegate, ProtoWriteUp -from ietf.wgchairs.accounts import get_person_for_user -from ietf.ietfworkflows.constants import REQUIRED_STATES -from ietf.ietfworkflows.utils import (get_default_workflow_for_wg, get_workflow_for_wg, - update_tags, FOLLOWUP_TAG, get_state_by_name) -from ietf.ietfworkflows.models import AnnotationTag, State -from ietf.idtracker.models import PersonOrOrgInfo -from ietf.utils.mail import send_mail_text - -from workflows.models import Transition - -from ietf.doc.models import WriteupDocEvent -from ietf.person.models import Person, Email -from ietf.group.models import Group, Role, RoleName -from ietf.group.utils import save_group_in_history -from ietf.name.models import DocTagName - - -class RelatedWGForm(forms.Form): - - can_cancel = False - - def __init__(self, *args, **kwargs): - self.wg = kwargs.pop('wg', None) - self.user = kwargs.pop('user', None) - self.message = {} - super(RelatedWGForm, self).__init__(*args, **kwargs) - - def get_message(self): - return self.message - - def set_message(self, msg_type, msg_value): - self.message = {'type': msg_type, - 'value': msg_value, - } - - -class TagForm(RelatedWGForm): - - tags = forms.ModelMultipleChoiceField(AnnotationTag.objects.filter(workflow__name='Default WG Workflow'), - widget=forms.CheckboxSelectMultiple, required=False) - - def save(self): - workflow = get_workflow_for_wg(self.wg) - workflow.selected_tags.clear() - for tag in self.cleaned_data['tags']: - workflow.selected_tags.add(tag) - return workflow - - -class StateForm(RelatedWGForm): - - states = forms.ModelMultipleChoiceField(State.objects.filter(workflow__name='Default WG Workflow'), - widget=forms.CheckboxSelectMultiple, required=False) - - def update_transitions(self, workflow): - for transition in workflow.transitions.all(): - if not workflow.selected_states.filter(pk=transition.destination.pk).count(): - transition.delete() - continue - for state in transition.states.all(): - if not workflow.selected_states.filter(pk=state.pk).count(): - transition.states.remove(state) - if not transition.states.count(): - transition.delete() - continue - - def save(self): - workflow = get_workflow_for_wg(self.wg) - workflow.selected_states.clear() - for state in self.cleaned_data['states']: - workflow.selected_states.add(state) - for name in REQUIRED_STATES: - rstate = get_state_by_name(name) - if rstate: - workflow.selected_states.add(rstate) - self.update_transitions(workflow) - return workflow - - -class DeleteTransitionForm(RelatedWGForm): - - transitions = forms.ModelMultipleChoiceField(Transition.objects.all(), - widget=forms.CheckboxSelectMultiple) - - def __init__(self, *args, **kwargs): - super(DeleteTransitionForm, self).__init__(*args, **kwargs) - workflow = get_workflow_for_wg(self.wg) - self.fields['transitions'].queryset = self.fields['transitions'].queryset.filter(workflow=workflow) - - def save(self): - for transition in self.cleaned_data['transitions']: - transition.delete() - - -class TransitionForm(forms.ModelForm): - - states = forms.ModelMultipleChoiceField(State.objects.filter(workflow__name='Default WG Workflow')) - - class Meta: - model = Transition - fields = ('name', 'states', 'destination', ) - - def __init__(self, *args, **kwargs): - self.wg = kwargs.pop('wg', None) - self.user = kwargs.pop('user', None) - super(TransitionForm, self).__init__(*args, **kwargs) - workflow = get_workflow_for_wg(self.wg) - self.fields['states'].queryset = workflow.selected_states.all() - self.fields['destination'].queryset = workflow.selected_states.all() - self.fields['destination'].required = True - if self.instance.pk: - self.fields['states'].initial = [i.pk for i in self.instance.states.all()] - self.instance.workflow = workflow - - def as_row(self): - return self._html_output(u'%(errors)s%(field)s%(help_text)s', u'%s', '', u'
      %s', False) - - def save(self, *args, **kwargs): - instance = super(TransitionForm, self).save(*args, **kwargs) - for state in self.cleaned_data['states']: - state.transitions.add(instance) - - -class TransitionFormSet(BaseModelFormSet): - - form = TransitionForm - can_delete = True - extra = 2 - max_num = 0 - can_order = False - model = Transition - - def __init__(self, *args, **kwargs): - self.wg = kwargs.pop('wg', None) - self.user = kwargs.pop('user', None) - super(TransitionFormSet, self).__init__(*args, **kwargs) - - def _construct_form(self, i, **kwargs): - kwargs = kwargs or {} - kwargs.update({'wg': self.wg, 'user': self.user}) - return super(TransitionFormSet, self)._construct_form(i, **kwargs) - - def as_table(self): - html = u'' - csscl = 'oddrow' - for form in self.forms: - html += u'' % csscl - html += form.as_row() - html += u'' - if csscl == 'oddrow': - csscl = 'evenrow' - else: - csscl = 'oddrow' - return mark_safe(u'\n'.join([unicode(self.management_form), html])) - - -def workflow_form_factory(request, wg, user): - - if request.POST.get('update_transitions', None): - return TransitionFormSet(wg=wg, user=user, data=request.POST) - elif request.POST.get('update_states', None): - return StateForm(wg=wg, user=user, data=request.POST) - return TagForm(wg=wg, user=user, data=request.POST) - - -class RemoveDelegateForm(RelatedWGForm): - - delete = forms.MultipleChoiceField() - - def __init__(self, *args, **kwargs): - super(RemoveDelegateForm, self).__init__(*args, **kwargs) - self.fields['delete'].choices = [(i.pk, i.pk) for i in self.wg.wgdelegate_set.all()] - - def save(self): - delegates = self.cleaned_data.get('delete') - save_group_in_history(Group.objects.get(pk=self.wg.pk)) - WGDelegate.objects.filter(pk__in=delegates).delete() - self.set_message('success', 'Delegates removed') - -def assign_shepherd(user, internetdraft, shepherd): - if internetdraft.shepherd == shepherd: - return - - from ietf.doc.models import save_document_in_history, DocEvent, Document - - # saving the proxy object is a bit of a mess, so convert it to a - # proper document - doc = Document.objects.get(name=internetdraft.name) - - save_document_in_history(doc) - - doc.time = datetime.datetime.now() - doc.shepherd = shepherd - doc.save() - - e = DocEvent(type="changed_document") - e.time = doc.time - e.doc = doc - e.by = user.get_profile() - if not shepherd: - e.desc = u"Unassigned shepherd" - else: - e.desc = u"Changed shepherd to %s" % shepherd.plain_name() - e.save() - - # update proxy too - internetdraft.shepherd = shepherd - -class AddDelegateForm(RelatedWGForm): - - email = forms.EmailField() - form_type = forms.CharField(widget=forms.HiddenInput, initial='single') - - def __init__(self, *args, **kwargs): - self.shepherd = kwargs.pop('shepherd', False) - super(AddDelegateForm, self).__init__(*args, **kwargs) - self.next_form = self - - def get_next_form(self): - return self.next_form - - def get_person(self, email): - persons = PersonOrOrgInfo.objects.filter(emailaddress__address=email).filter( - Q(iesglogin__isnull=False)| - Q(legacywgpassword__isnull=False)| - Q(legacyliaisonuser__isnull=False)).distinct() - if not persons: - raise PersonOrOrgInfo.DoesNotExist - if len(persons) > 1: - raise PersonOrOrgInfo.MultipleObjectsReturned - return persons[0] - - def save(self): - email = self.cleaned_data.get('email') - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - try: - person = Person.objects.filter(email__address=email).exclude(user=None).distinct().get() - except Person.DoesNotExist: - self.next_form = NotExistDelegateForm(wg=self.wg, user=self.user, email=email, shepherd=self.shepherd) - self.next_form.set_message('doesnotexist', 'There is no user with this email allowed to login to the system') - return - except Person.MultipleObjectsReturned: - self.next_form = MultipleDelegateForm(wg=self.wg, user=self.user, email=email, shepherd=self.shepherd) - self.next_form.set_message('multiple', 'There are multiple users with this email in the system') - return - else: - try: - person = self.get_person(email) - except PersonOrOrgInfo.DoesNotExist: - self.next_form = NotExistDelegateForm(wg=self.wg, user=self.user, email=email, shepherd=self.shepherd) - self.next_form.set_message('doesnotexist', 'There is no user with this email allowed to login to the system') - return - except PersonOrOrgInfo.MultipleObjectsReturned: - self.next_form = MultipleDelegateForm(wg=self.wg, user=self.user, email=email, shepherd=self.shepherd) - self.next_form.set_message('multiple', 'There are multiple users with this email in the system') - return - if self.shepherd: - self.assign_shepherd(person) - else: - self.create_delegate(person) - - def assign_shepherd(self, person): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - assign_shepherd(self.user, self.shepherd, person) - else: - self.shepherd.shepherd = person - self.shepherd.save() - self.next_form = AddDelegateForm(wg=self.wg, user=self.user, shepherd=self.shepherd) - self.next_form.set_message('success', 'Shepherd assigned successfully') - - def create_delegate(self, person): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - created = False - e = Email.objects.get(address=self.cleaned_data.get('email')) - if not Role.objects.filter(name="delegate", group=self.wg, person=person, email=e): - created = True - save_group_in_history(Group.objects.get(pk=self.wg.pk)) - delegate, _ = Role.objects.get_or_create( - name=RoleName.objects.get(slug="delegate"), group=self.wg, person=e.person, email=e) - else: - (delegate, created) = WGDelegate.objects.get_or_create(wg=self.wg, - person=person) - if not created: - self.set_message('error', 'The email belongs to a person who is already a delegate') - else: - self.next_form = AddDelegateForm(wg=self.wg, user=self.user) - self.next_form.set_message('success', 'A new delegate has been added') - - -class MultipleDelegateForm(AddDelegateForm): - - email = forms.EmailField(widget=forms.HiddenInput) - form_type = forms.CharField(widget=forms.HiddenInput, initial='multiple') - persons = forms.ChoiceField(widget=forms.RadioSelect, help_text='Please select one person from the list') - submit_msg = 'Designate as delegate' - - def __init__(self, *args, **kwargs): - self.email = kwargs.pop('email', None) - super(MultipleDelegateForm, self).__init__(*args, **kwargs) - if not self.email: - self.email = self.data.get('email', None) - self.fields['email'].initial = self.email - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - self.fields['persons'].choices = [(i.pk, unicode(i)) for i in Person.objects.filter(email__address=self.email).exclude(user=None).distinct().order_by('name')] - else: - self.fields['persons'].choices = [(i.pk, unicode(i)) for i in PersonOrOrgInfo.objects.filter(emailaddress__address=self.email).filter( - Q(iesglogin__isnull=False)| - Q(legacywgpassword__isnull=False)| - Q(legacyliaisonuser__isnull=False)).distinct().order_by('first_name')] - - def save(self): - person_id = self.cleaned_data.get('persons') - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - person = Person.objects.get(pk=person_id) - else: - person = PersonOrOrgInfo.objects.get(pk=person_id) - if self.shepherd: - self.assign_shepherd(person) - else: - self.create_delegate(person) - - -class NotExistDelegateForm(MultipleDelegateForm): - - email = forms.EmailField(widget=forms.HiddenInput) - form_type = forms.CharField(widget=forms.HiddenInput, initial='notexist') - can_cancel = True - submit_msg = 'Send email to these addresses' - - def __init__(self, *args, **kwargs): - super(NotExistDelegateForm, self).__init__(*args, **kwargs) - self.email_list = [] - del(self.fields['persons']) - - def get_email_list(self): - if self.email_list: - return self.email_list - email_list = [self.email] - email_list.append('IETF Secretariat ') - email_list += ['%s <%s>' % i.person.email() for i in self.wg.wgchair_set.all() if i.person.email()] - self.email_list = email_list - return email_list - - def as_p(self): - email_list = self.get_email_list() - info = render_to_string('wgchairs/notexistdelegate.html', {'email_list': email_list, 'shepherd': self.shepherd}) - return info + super(NotExistDelegateForm, self).as_p() - - def send_email(self, to_email, template): - if self.shepherd: - subject = 'WG shepherd needs system credentials' - else: - subject = 'WG Delegate needs system credentials' - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - persons = Person.objects.filter(email__address=self.email).distinct() - else: - persons = PersonOrOrgInfo.objects.filter(emailaddress__address=self.email).distinct() - body = render_to_string(template, - {'chair': get_person_for_user(self.user), - 'delegate_email': self.email, - 'shepherd': self.shepherd, - 'delegate_persons': persons, - 'wg': self.wg, - }) - - send_mail_text(self.request, to_email, settings.DEFAULT_FROM_EMAIL, subject, body) - - def save(self): - self.next_form = AddDelegateForm(wg=self.wg, user=self.user) - if settings.DEBUG: - self.next_form.set_message('warning', 'Email was not sent cause tool is in DEBUG mode') - else: - # this is ugly... - email_list = self.get_email_list() - delegate = email_list[0] - secretariat = email_list[1] - wgchairs = email_list[2:] - self.send_email(delegate, 'wgchairs/notexistsdelegate_delegate_email.txt') - self.send_email(secretariat, 'wgchairs/notexistsdelegate_secretariat_email.txt') - self.send_email(wgchairs, 'wgchairs/notexistsdelegate_wgchairs_email.txt') - self.next_form.set_message('success', 'Email sent successfully') - - -def add_form_factory(request, wg, user, shepherd=False): - if request.method != 'POST' or request.POST.get('update_shepehrd'): - return AddDelegateForm(wg=wg, user=user, shepherd=shepherd) - - if request.POST.get('form_type', None) == 'multiple': - f = MultipleDelegateForm(wg=wg, user=user, data=request.POST.copy(), shepherd=shepherd) - elif request.POST.get('form_type', None) == 'notexist': - f = NotExistDelegateForm(wg=wg, user=user, data=request.POST.copy(), shepherd=shepherd) - elif request.POST.get('form_type', None) == 'single': - f = AddDelegateForm(wg=wg, user=user, data=request.POST.copy(), shepherd=shepherd) - else: - f = AddDelegateForm(wg=wg, user=user, shepherd=shepherd) - - f.request = request - return f - -class WriteUpEditForm(RelatedWGForm): - - writeup = forms.CharField(widget=forms.Textarea, required=False) - followup = forms.BooleanField(required=False) - comment = forms.CharField(widget=forms.Textarea, required=False) - - def __init__(self, *args, **kwargs): - self.doc = kwargs.pop('doc', None) - self.doc_writeup = self.doc.protowriteup_set.all() - if self.doc_writeup.count(): - self.doc_writeup = self.doc_writeup[0] - else: - self.doc_writeup = None - super(WriteUpEditForm, self).__init__(*args, **kwargs) - self.person = get_person_for_user(self.user) - - def get_writeup(self): - return self.data.get('writeup', self.doc_writeup and self.doc_writeup.writeup or '') - - def save(self): - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - e = WriteupDocEvent(type="changed_protocol_writeup") - e.doc = self.doc - e.by = self.person - e.desc = e.get_type_display() - e.text = self.cleaned_data['writeup'] - e.save() - from ietf.wgchairs.models import ProtoWriteUpProxy - self.doc_writeup = ProtoWriteUpProxy.objects.get(pk=e.pk) - else: - if not self.doc_writeup: - self.doc_writeup = ProtoWriteUp.objects.create( - person=self.person, - draft=self.doc, - writeup=self.cleaned_data['writeup']) - else: - self.doc_writeup.writeup = self.cleaned_data['writeup'] - self.doc_writeup.save() - - if self.data.get('modify_tag', False): - followup = self.cleaned_data.get('followup', False) - comment = self.cleaned_data.get('comment', False) - try: - shepherd = self.doc.shepherd - except PersonOrOrgInfo.DoesNotExist: - shepherd = None - if shepherd: - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - extra_notify = [shepherd.formatted_email()] - else: - extra_notify = ['%s <%s>' % shepherd.email()] - else: - extra_notify = [] - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - tags = DocTagName.objects.filter(slug="sheph-u") - else: - tags = [FOLLOWUP_TAG] - if followup: - update_tags(self.request, self.doc, comment, self.person, set_tags=tags, extra_notify=extra_notify) - else: - update_tags(self.request, self.doc, comment, self.person, reset_tags=tags, extra_notify=extra_notify) - return self.doc_writeup - - def is_valid(self): - if self.data.get('confirm', False) and self.data.get('modify_tag', False): - self.fields['comment'].required = True - else: - self.fields['comment'].required = False - return super(WriteUpEditForm, self).is_valid() diff --git a/ietf/wgchairs/migrations/.gitignore b/ietf/wgchairs/migrations/.gitignore deleted file mode 100644 index a74b07aee..000000000 --- a/ietf/wgchairs/migrations/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/*.pyc diff --git a/ietf/wgchairs/migrations/0001_initial.py b/ietf/wgchairs/migrations/0001_initial.py deleted file mode 100644 index 6aa9fb58f..000000000 --- a/ietf/wgchairs/migrations/0001_initial.py +++ /dev/null @@ -1,110 +0,0 @@ - -from south.db import db -from django.db import models -from ietf.wgchairs.models import * - -class Migration: - - def forwards(self, orm): - - # Adding model 'WGDelegate' - db.create_table('wgchairs_wgdelegate', ( - ('id', orm['wgchairs.WGDelegate:id']), - ('person', orm['wgchairs.WGDelegate:person']), - ('wg', orm['wgchairs.WGDelegate:wg']), - )) - db.send_create_signal('wgchairs', ['WGDelegate']) - - - - def backwards(self, orm): - - # Deleting model 'WGDelegate' - db.delete_table('wgchairs_wgdelegate') - - - - models = { - 'idtracker.acronym': { - 'Meta': {'db_table': "'acronym'"}, - 'acronym': ('django.db.models.fields.CharField', [], {'max_length': '12'}), - 'acronym_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name_key': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'idtracker.area': { - 'Meta': {'db_table': "'areas'"}, - 'area_acronym': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['idtracker.Acronym']", 'unique': 'True', 'primary_key': 'True'}), - 'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'concluded_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'extra_email_addresses': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'last_modified_date': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'blank': 'True'}), - 'start_date': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.AreaStatus']"}) - }, - 'idtracker.areadirector': { - 'Meta': {'db_table': "'area_directors'"}, - 'area': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Area']", 'null': 'True', 'db_column': "'area_acronym_id'"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}) - }, - 'idtracker.areastatus': { - 'Meta': {'db_table': "'area_status'"}, - 'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.ietfwg': { - 'Meta': {'db_table': "'groups_ietf'"}, - 'area_director': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.AreaDirector']", 'null': 'True'}), - 'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'concluded_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'dormant_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'email_address': ('django.db.models.fields.CharField', [], {'max_length': '60', 'blank': 'True'}), - 'email_archive': ('django.db.models.fields.CharField', [], {'max_length': '95', 'blank': 'True'}), - 'email_keyword': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'email_subscribe': ('django.db.models.fields.CharField', [], {'max_length': '120', 'blank': 'True'}), - 'group_acronym': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['idtracker.Acronym']", 'unique': 'True', 'primary_key': 'True'}), - 'group_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.WGType']"}), - 'last_modified_date': ('django.db.models.fields.DateField', [], {}), - 'meeting_scheduled': ('django.db.models.fields.CharField', [], {'max_length': '3', 'blank': 'True'}), - 'meeting_scheduled_old': ('django.db.models.fields.CharField', [], {'max_length': '3', 'blank': 'True'}), - 'proposed_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.WGStatus']"}) - }, - 'idtracker.personororginfo': { - 'Meta': {'db_table': "'person_or_org_info'"}, - 'address_type': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'created_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'date_created': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}), - 'date_modified': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'first_name_key': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'last_name_key': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'middle_initial': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'middle_initial_key': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'modified_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'name_prefix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'name_suffix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'person_or_org_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'record_type': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}) - }, - 'idtracker.wgstatus': { - 'Meta': {'db_table': "'g_status'"}, - 'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.wgtype': { - 'Meta': {'db_table': "'g_type'"}, - 'group_type_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'type': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'group_type'"}) - }, - 'wgchairs.wgdelegate': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}), - 'wg': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IETFWG']"}) - } - } - - complete_apps = ['wgchairs'] diff --git a/ietf/wgchairs/migrations/0002_add_writeup.py b/ietf/wgchairs/migrations/0002_add_writeup.py deleted file mode 100644 index e1754ed22..000000000 --- a/ietf/wgchairs/migrations/0002_add_writeup.py +++ /dev/null @@ -1,163 +0,0 @@ - -from south.db import db -from django.db import models -from ietf.wgchairs.models import * - -class Migration: - - def forwards(self, orm): - - # Adding model 'ProtoWriteUp' - db.create_table('wgchairs_protowriteup', ( - ('id', orm['wgchairs.protowriteup:id']), - ('person', orm['wgchairs.protowriteup:person']), - ('draft', orm['wgchairs.protowriteup:draft']), - ('date', orm['wgchairs.protowriteup:date']), - ('writeup', orm['wgchairs.protowriteup:writeup']), - )) - db.send_create_signal('wgchairs', ['ProtoWriteUp']) - - - - def backwards(self, orm): - - # Deleting model 'ProtoWriteUp' - db.delete_table('wgchairs_protowriteup') - - - - models = { - 'idtracker.acronym': { - 'Meta': {'db_table': "'acronym'"}, - 'acronym': ('django.db.models.fields.CharField', [], {'max_length': '12'}), - 'acronym_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name_key': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'idtracker.area': { - 'Meta': {'db_table': "'areas'"}, - 'area_acronym': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['idtracker.Acronym']", 'unique': 'True', 'primary_key': 'True'}), - 'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'concluded_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'extra_email_addresses': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'last_modified_date': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'blank': 'True'}), - 'start_date': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.AreaStatus']"}) - }, - 'idtracker.areadirector': { - 'Meta': {'db_table': "'area_directors'"}, - 'area': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Area']", 'null': 'True', 'db_column': "'area_acronym_id'"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}) - }, - 'idtracker.areastatus': { - 'Meta': {'db_table': "'area_status'"}, - 'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.idintendedstatus': { - 'Meta': {'db_table': "'id_intended_status'"}, - 'intended_status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'intended_status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.idstatus': { - 'Meta': {'db_table': "'id_status'"}, - 'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.ietfwg': { - 'Meta': {'db_table': "'groups_ietf'"}, - 'area_director': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.AreaDirector']", 'null': 'True'}), - 'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'concluded_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'dormant_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'email_address': ('django.db.models.fields.CharField', [], {'max_length': '60', 'blank': 'True'}), - 'email_archive': ('django.db.models.fields.CharField', [], {'max_length': '95', 'blank': 'True'}), - 'email_keyword': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'email_subscribe': ('django.db.models.fields.CharField', [], {'max_length': '120', 'blank': 'True'}), - 'group_acronym': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['idtracker.Acronym']", 'unique': 'True', 'primary_key': 'True'}), - 'group_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.WGType']"}), - 'last_modified_date': ('django.db.models.fields.DateField', [], {}), - 'meeting_scheduled': ('django.db.models.fields.CharField', [], {'max_length': '3', 'blank': 'True'}), - 'meeting_scheduled_old': ('django.db.models.fields.CharField', [], {'max_length': '3', 'blank': 'True'}), - 'proposed_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.WGStatus']"}) - }, - 'idtracker.internetdraft': { - 'Meta': {'db_table': "'internet_drafts'"}, - 'abstract': ('django.db.models.fields.TextField', [], {}), - 'b_approve_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'b_discussion_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'b_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'dunn_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True'}), - 'expired_tombstone': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'extension_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'file_type': ('django.db.models.fields.CharField', [], {'max_length': '20'}), - 'filename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), - 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Acronym']", 'db_column': "'group_acronym_id'"}), - 'id_document_key': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'id_document_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'intended_status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDIntendedStatus']"}), - 'last_modified_date': ('django.db.models.fields.DateField', [], {}), - 'lc_changes': ('django.db.models.fields.CharField', [], {'max_length': '3', 'null': 'True'}), - 'lc_expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'lc_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'local_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), - 'replaced_by': ('django.db.models.fields.related.ForeignKey', ["orm['idtracker.InternetDraft']"], {'related_name': "'replaces_set'", 'null': 'True', 'db_column': "'replaced_by'", 'blank': 'True'}), - 'review_by_rfc_editor': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'revision': ('django.db.models.fields.CharField', [], {'max_length': '2'}), - 'revision_date': ('django.db.models.fields.DateField', [], {}), - 'rfc_number': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), - 'shepherd': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'null': 'True', 'blank': 'True'}), - 'start_date': ('django.db.models.fields.DateField', [], {}), - 'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDStatus']"}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'id_document_name'"}), - 'txt_page_count': ('django.db.models.fields.IntegerField', [], {}), - 'wgreturn_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}) - }, - 'idtracker.personororginfo': { - 'Meta': {'db_table': "'person_or_org_info'"}, - 'address_type': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'created_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'date_created': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}), - 'date_modified': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'first_name_key': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'last_name_key': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), - 'middle_initial': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'middle_initial_key': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), - 'modified_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), - 'name_prefix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'name_suffix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - 'person_or_org_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'record_type': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}) - }, - 'idtracker.wgstatus': { - 'Meta': {'db_table': "'g_status'"}, - 'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), - 'status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'idtracker.wgtype': { - 'Meta': {'db_table': "'g_type'"}, - 'group_type_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'type': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'group_type'"}) - }, - 'wgchairs.protowriteup': { - 'date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now()'}), - 'draft': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.InternetDraft']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}), - 'writeup': ('django.db.models.fields.TextField', [], {}) - }, - 'wgchairs.wgdelegate': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}), - 'wg': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IETFWG']"}) - } - } - - complete_apps = ['wgchairs'] diff --git a/ietf/wgchairs/migrations/__init__.py b/ietf/wgchairs/migrations/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/ietf/wgchairs/models.py b/ietf/wgchairs/models.py deleted file mode 100644 index ea0a74c97..000000000 --- a/ietf/wgchairs/models.py +++ /dev/null @@ -1,87 +0,0 @@ -import datetime - -from django.db import models -from django.conf import settings - -from ietf.idtracker.models import (IETFWG, PersonOrOrgInfo, - InternetDraft) - - -class WGDelegate(models.Model): - person = models.ForeignKey( - PersonOrOrgInfo, - ) - - wg = models.ForeignKey(IETFWG, related_name="old_wgdelegate_set" if settings.USE_DB_REDESIGN_PROXY_CLASSES else None) - - def __unicode__(self): - return "%s" % self.person - - class Meta: - verbose_name = "WG Delegate" - -class ProtoWriteUp(models.Model): - person = models.ForeignKey( - PersonOrOrgInfo, - blank=False, - null=False, - ) - - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - from ietf.idtracker.models import InternetDraftOld as InternetDraft - - draft = models.ForeignKey( - InternetDraft, - blank=False, - null=False, - ) - - date = models.DateTimeField( - default=datetime.datetime.now(), - blank=False, - null=False, - ) - - writeup = models.TextField( - blank=False, - null=False, - ) - -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - from ietf.group.models import Role - class WGDelegateProxy(Role): - #person = models.ForeignKey(PersonOrOrgInfo) # same name - #wg = models.ForeignKey(IETFWG) - @property - def wg(self): - return self.group - - def __unicode__(self): - return u"%s" % self.person - - class Meta: - proxy = True - - from ietf.doc.models import WriteupDocEvent - class ProtoWriteUpProxy(WriteupDocEvent): - #person = models.ForeignKey(PersonOrOrgInfo, blank=False, null=False) - @property - def person(self): - return self.by - #draft = models.ForeignKey(InternetDraft, blank=False, null=False) - @property - def draft(self): - return self.doc - #date = models.DateTimeField(default=datetime.datetime.now(), blank=False, null=False) - @property - def date(self): - return self.time - #writeup = models.TextField(blank=False, null=False) - @property - def writeup(self): - return self.text - class Meta: - proxy = True - - #WGDelegateOld = WGDelegate - WGDelegate = WGDelegateProxy diff --git a/ietf/wgchairs/templatetags/.gitignore b/ietf/wgchairs/templatetags/.gitignore deleted file mode 100644 index a74b07aee..000000000 --- a/ietf/wgchairs/templatetags/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/*.pyc diff --git a/ietf/wgchairs/templatetags/__init__.py b/ietf/wgchairs/templatetags/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/ietf/wgchairs/templatetags/wgchairs_tags.py b/ietf/wgchairs/templatetags/wgchairs_tags.py deleted file mode 100644 index df51dafae..000000000 --- a/ietf/wgchairs/templatetags/wgchairs_tags.py +++ /dev/null @@ -1,47 +0,0 @@ -from django.conf import settings -from django import template - -from ietf.ietfworkflows.utils import get_state_for_draft -from ietf.wgchairs.accounts import (can_manage_workflow_in_group, - can_manage_delegates_in_group, - can_manage_shepherds_in_group) - - -register = template.Library() - - -@register.inclusion_tag('wgchairs/wgchairs_admin_options.html', takes_context=True) -def wgchairs_admin_options(context, wg): - request = context.get('request', None) - user = request and request.user - return {'user': user, - 'can_manage_delegates': can_manage_delegates_in_group(user, wg), - 'can_manage_workflow': can_manage_workflow_in_group(user, wg), - 'can_manage_shepherds': can_manage_shepherds_in_group(user, wg), - 'wg': wg, - 'selected': context.get('selected', None), - } - -@register.simple_tag -def writeup(doc): - writeup = doc.protowriteup_set.all() - if not writeup: - return '' - else: - return writeup[0].writeup - - -@register.simple_tag -def writeupdate(doc): - writeup = doc.protowriteup_set.all() - if not writeup: - return '' - else: - return writeup[0].date - - -@register.inclusion_tag('wgchairs/draft_state.html', takes_context=True) -def show_state(context, doc): - return {'doc': doc, - 'state': get_state_for_draft(doc), - } diff --git a/ietf/wgchairs/tests.py b/ietf/wgchairs/tests.py deleted file mode 100644 index 1eab843bc..000000000 --- a/ietf/wgchairs/tests.py +++ /dev/null @@ -1,217 +0,0 @@ -import datetime, os, shutil - -from django.conf import settings -from django.contrib.auth.models import User -from django.core.urlresolvers import reverse as urlreverse -from StringIO import StringIO -from pyquery import PyQuery - -from ietf.utils.test_utils import login_testing_unauthorized -from ietf.utils.test_data import make_test_data -from ietf.utils.mail import outbox -from ietf.utils import TestCase - -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - from ietf.person.models import Person, Email - from ietf.group.models import Group, GroupHistory, Role, GroupStateTransitions - from ietf.doc.models import Document, State, WriteupDocEvent - from ietf.name.models import DocTagName - -class ManageDelegatesTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] - - def test_delete_delegate(self): - make_test_data() - - url = urlreverse('manage_delegates', kwargs=dict(acronym="mars")) - login_testing_unauthorized(self, "secretary", url) - - delegates = Role.objects.filter(name="delegate", group__acronym="mars") - self.assertTrue(len(delegates) > 0) - - # get - r = self.client.get(url) - self.assertEquals(r.status_code, 200) - q = PyQuery(r.content) - self.assertEquals(len(q('form input[name=delete]')), len(delegates)) - - # delete - r = self.client.post(url, - dict(remove="1", - delete=[d.pk for d in delegates])) - self.assertEquals(r.status_code, 200) - q = PyQuery(r.content) - self.assertEquals(len(q('form input[name=delete]')), 0) - self.assertEquals(Role.objects.filter(name="delegate", group__acronym="mars").count(), 0) - - def test_add_not_existing_delegate(self): - make_test_data() - - url = urlreverse('manage_delegates', kwargs=dict(acronym="mars")) - login_testing_unauthorized(self, "secretary", url) - - # get - r = self.client.get(url) - self.assertEquals(r.status_code, 200) - q = PyQuery(r.content) - self.assertEquals(len(q('form input[name=email]')), 1) - - # add non-existing - r = self.client.post(url, - dict(email="unknown@example.com", - form_type="single")) - self.assertEquals(r.status_code, 200) - self.assertTrue("unknown@example.com" in r.content) - q = PyQuery(r.content) - self.assertEquals(len(q('form input[type=submit][value*="Send email"]')), 1) - - # we get back a warning and offer to send email, do that - mailbox_before = len(outbox) - r = self.client.post(url, - dict(email="unknown@example.com", - form_type="notexist")) - self.assertEquals(r.status_code, 200) - self.assertTrue("Email sent" in r.content) - self.assertEquals(len(outbox), mailbox_before + 3) - - def test_add_delegate(self): - make_test_data() - - url = urlreverse('manage_delegates', kwargs=dict(acronym="mars")) - login_testing_unauthorized(self, "secretary", url) - - # get - r = self.client.get(url) - self.assertEquals(r.status_code, 200) - q = PyQuery(r.content) - self.assertEquals(len(q('form input[name=email]')), 1) - - # add existing person - history_before = GroupHistory.objects.filter(acronym="mars").count() - r = self.client.post(url, - dict(email="plain@example.com", - form_type="single")) - self.assertEquals(r.status_code, 200) - q = PyQuery(r.content) - self.assertTrue("new delegate" in r.content) - self.assertTrue(Email.objects.get(address="plain@example.com").person.plain_name() in r.content) - self.assertEquals(Role.objects.filter(name="delegate", group__acronym="mars", email__address="plain@example.com").count(), 1) - self.assertEquals(history_before + 1, GroupHistory.objects.filter(acronym="mars").count()) - - -class ManageShepherdsTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] - - def test_manage_shepherds(self): - make_test_data() - - url = urlreverse('manage_shepherds', kwargs=dict(acronym="mars")) - login_testing_unauthorized(self, "secretary", url) - - # setup test documents - group = Group.objects.get(acronym="mars") - - from ietf.doc.models import Document - common = dict(group=group, - ad=Person.objects.get(user__username="ad"), - type_id="draft") - Document.objects.create(name="test-shepherd-no", - title="No shepherd", - shepherd=None, - **common) - Document.objects.create(name="test-shepherd-me", - title="Shepherd me", - shepherd=Person.objects.get(user__username="secretary"), - **common) - Document.objects.create(name="test-shepherd-other", title="Shepherd other", - shepherd=Person.objects.get(user__username="plain"), - **common) - for d in Document.objects.filter(name__startswith="test-shepherd"): - d.set_state(State.objects.get(used=True, type="draft", slug="active")) - - # get and make sure they are divided correctly - r = self.client.get(url) - self.assertEquals(r.status_code, 200) - q = PyQuery(r.content) - self.assertEquals(len(q('div#noshepherd a:contains("No shepherd")')), 1) - self.assertEquals(len(q('div#mydocs a:contains("Shepherd me")')), 1) - self.assertEquals(len(q('div#othershepherds a:contains("Shepherd other")')), 1) - - -class ManageWorkflowTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] - - def test_manage_workflows(self): - make_test_data() - - group = Group.objects.get(acronym="mars") - - url = urlreverse('manage_workflow', kwargs=dict(acronym=group.acronym)) - login_testing_unauthorized(self, "secretary", url) - - state = State.objects.get(used=True, type="draft-stream-ietf", slug="wg-lc") - self.assertTrue(state not in group.unused_states.all()) - - # get - r = self.client.get(url) - self.assertEquals(r.status_code, 200) - q = PyQuery(r.content) - self.assertEquals(len(q("form.set-state").find("input[name=state][value='%s']" % state.pk).parents("form").find("input[name=active][value='0']")), 1) - - # deactivate state - r = self.client.post(url, - dict(action="setstateactive", - state=state.pk, - active="0")) - self.assertEquals(r.status_code, 200) - q = PyQuery(r.content) - self.assertEquals(len(q("form.set-state").find("input[name=state][value='%s']" % state.pk).parents("form").find("input[name=active][value='1']")), 1) - group = Group.objects.get(acronym=group.acronym) - self.assertTrue(state in group.unused_states.all()) - - # change next states - state = State.objects.get(used=True, type="draft-stream-ietf", slug="wg-doc") - next_states = State.objects.filter(used=True, type=b"draft-stream-ietf", slug__in=["parked", "dead", "wait-wgw", 'sub-pub']).values_list('pk', flat=True) - r = self.client.post(url, - dict(action="setnextstates", - state=state.pk, - next_states=next_states)) - self.assertEquals(r.status_code, 200) - q = PyQuery(r.content) - self.assertEquals(len(q("form.set-next-states").find("input[name=state][value='%s']" % state.pk).parents('form').find("input[name=next_states][checked=checked]")), len(next_states)) - transitions = GroupStateTransitions.objects.filter(group=group, state=state) - self.assertEquals(len(transitions), 1) - self.assertEquals(set(transitions[0].next_states.values_list("pk", flat=True)), set(next_states)) - - # change them back to default - next_states = state.next_states.values_list("pk", flat=True) - r = self.client.post(url, - dict(action="setnextstates", - state=state.pk, - next_states=next_states)) - self.assertEquals(r.status_code, 200) - q = PyQuery(r.content) - transitions = GroupStateTransitions.objects.filter(group=group, state=state) - self.assertEquals(len(transitions), 0) - - # deactivate tag - tag = DocTagName.objects.get(slug="w-expert") - r = self.client.post(url, - dict(action="settagactive", - tag=tag.pk, - active="0")) - self.assertEquals(r.status_code, 200) - q = PyQuery(r.content) - self.assertEquals(len(q('form').find('input[name=tag][value="%s"]' % tag.pk).parents("form").find("input[name=active]")), 1) - group = Group.objects.get(acronym=group.acronym) - self.assertTrue(tag in group.unused_tags.all()) - -if not settings.USE_DB_REDESIGN_PROXY_CLASSES: - # the above tests only work with the new schema - del ManageDelegatesTestCase - del ManageShepherdsTestCase - del ManageWorkflowTestCase - del ManageWriteupCase diff --git a/ietf/wgchairs/urls.py b/ietf/wgchairs/urls.py deleted file mode 100644 index d8cadb8ee..000000000 --- a/ietf/wgchairs/urls.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright The IETF Trust 2008, All Rights Reserved - -from django.conf.urls.defaults import patterns, url - -urlpatterns = patterns('ietf.wgchairs.views', - url(r'^workflows/$', 'manage_workflow', name='manage_workflow'), - url(r'^delegates/$', 'manage_delegates', name='manage_delegates'), - url(r'^shepherds/$', 'wg_shepherd_documents', name='manage_shepherds'), -) diff --git a/ietf/wgchairs/views.py b/ietf/wgchairs/views.py deleted file mode 100644 index 3bcd6e026..000000000 --- a/ietf/wgchairs/views.py +++ /dev/null @@ -1,200 +0,0 @@ -from django.conf import settings -from ietf.idtracker.models import IETFWG, InternetDraft -from django.shortcuts import get_object_or_404, render_to_response -from django.template import RequestContext -from django.http import HttpResponseForbidden, Http404 - -from ietf.wgchairs.forms import (RemoveDelegateForm, add_form_factory, - workflow_form_factory, TransitionFormSet, - WriteUpEditForm, assign_shepherd) -from ietf.wgchairs.accounts import (can_manage_delegates_in_group, get_person_for_user, - can_manage_shepherds_in_group, - can_manage_workflow_in_group, - can_manage_shepherd_of_a_document, - can_manage_writeup_of_a_document, - can_manage_writeup_of_a_document_no_state, - ) -from ietf.ietfworkflows.constants import REQUIRED_STATES -from ietf.ietfworkflows.utils import (get_workflow_for_wg, - get_default_workflow_for_wg, - get_state_by_name, - get_annotation_tags_for_draft, - get_state_for_draft, WAITING_WRITEUP, - FOLLOWUP_TAG) -from ietf.name.models import DocTagName -from ietf.doc.models import State -from ietf.doc.utils import get_tags_for_stream_id - -def manage_delegates(request, acronym): - wg = get_object_or_404(IETFWG, group_acronym__acronym=acronym, group_type=1) - user = request.user - if not can_manage_delegates_in_group(user, wg): - return HttpResponseForbidden('You have no permission to access this view') - delegates = wg.wgdelegate_set.all() - add_form = add_form_factory(request, wg, user) - if request.method == 'POST': - if request.POST.get('remove', None): - form = RemoveDelegateForm(wg=wg, data=request.POST.copy()) - if form.is_valid(): - form.save() - elif add_form.is_valid(): - add_form.save() - add_form = add_form.get_next_form() - max_delegates = getattr(settings, 'MAX_WG_DELEGATES', 3) - return render_to_response('wgchairs/manage_delegates.html', - {'wg': wg, - 'delegates': delegates, - 'selected': 'manage_delegates', - 'can_add': delegates.count() < max_delegates, - 'max_delegates': max_delegates, - 'add_form': add_form, - }, RequestContext(request)) - - -def manage_workflow(request, acronym): - wg = get_object_or_404(IETFWG, group_acronym__acronym=acronym, group_type=1) - user = request.user - if not can_manage_workflow_in_group(user, wg): - return HttpResponseForbidden("You don't have permission to access this view") - workflow = get_workflow_for_wg(wg) - default_workflow = get_default_workflow_for_wg() - formset = None - if request.method == 'POST': - form = workflow_form_factory(request, wg=wg, user=user) - if form.is_valid(): - form.save() - elif isinstance(form, TransitionFormSet): - formset = form - tags = workflow.selected_tags.all() - default_tags = default_workflow.annotation_tags.all() - states = workflow.selected_states.all().order_by('statedescription__order') - default_states = default_workflow.states.all().order_by('statedescription__order') - for i in default_states: - if states.filter(name=i.name).count() == 1: - i.used = True - if i.name in REQUIRED_STATES: - i.freeze = True - for i in default_tags: - if tags.filter(name=i.name).count() == 1: - i.used = True - if not formset: - formset = TransitionFormSet(queryset=workflow.transitions.all(), user=user, wg=wg) - - return render_to_response('wgchairs/manage_workflow.html', - {'wg': wg, - 'workflow': workflow, - 'default_workflow': default_workflow, - 'states': states, - 'tags': tags, - 'default_states': default_states, - 'default_tags': default_tags, - 'formset': formset, - 'selected': 'manage_workflow', - }, RequestContext(request)) - -def manage_workflowREDESIGN(request, acronym): - from ietf.doc.models import State - from ietf.group.models import GroupStateTransitions - - MANDATORY_STATES = ('c-adopt', 'wg-doc', 'sub-pub') - - wg = get_object_or_404(IETFWG, group_acronym__acronym=acronym, group_type=1) - user = request.user - if not can_manage_workflow_in_group(user, wg): - return HttpResponseForbidden("You don't have permission to access this view") - - if request.method == 'POST': - action = request.POST.get("action") - if action == "setstateactive": - active = request.POST.get("active") == "1" - try: - state = State.objects.exclude(slug__in=MANDATORY_STATES).get(pk=request.POST.get("state")) - except State.DoesNotExist: - return HttpResponse("Invalid state %s" % request.POST.get("state")) - - if active: - wg.unused_states.remove(state) - else: - wg.unused_states.add(state) - - if action == "setnextstates": - try: - state = State.objects.get(pk=request.POST.get("state")) - except State.DoesNotExist: - return HttpResponse("Invalid state %s" % request.POST.get("state")) - - next_states = State.objects.filter(used=True, type='draft-stream-ietf', pk__in=request.POST.getlist("next_states")) - unused = wg.unused_states.all() - if set(next_states.exclude(pk__in=unused)) == set(state.next_states.exclude(pk__in=unused)): - # just use the default - wg.groupstatetransitions_set.filter(state=state).delete() - else: - transitions, _ = GroupStateTransitions.objects.get_or_create(group=wg, state=state) - transitions.next_states = next_states - - if action == "settagactive": - active = request.POST.get("active") == "1" - try: - tag = DocTagName.objects.get(pk=request.POST.get("tag")) - except DocTagName.DoesNotExist: - return HttpResponse("Invalid tag %s" % request.POST.get("tag")) - - if active: - wg.unused_tags.remove(tag) - else: - wg.unused_tags.add(tag) - - - # put some info for the template on tags and states - unused_tags = wg.unused_tags.all().values_list('slug', flat=True) - tags = DocTagName.objects.filter(slug__in=get_tags_for_stream_id("ietf")) - for t in tags: - t.used = t.slug not in unused_tags - - unused_states = wg.unused_states.all().values_list('slug', flat=True) - states = State.objects.filter(used=True, type="draft-stream-ietf") - transitions = dict((o.state, o) for o in wg.groupstatetransitions_set.all()) - for s in states: - s.used = s.slug not in unused_states - s.mandatory = s.slug in MANDATORY_STATES - - default_n = s.next_states.all() - if s in transitions: - n = transitions[s].next_states.all() - else: - n = default_n - - s.next_states_checkboxes = [(x in n, x in default_n, x) for x in states] - s.used_next_states = [x for x in n if x.slug not in unused_states] - - return render_to_response('wgchairs/manage_workflowREDESIGN.html', - {'wg': wg, - 'states': states, - 'tags': tags, - 'selected': 'manage_workflow', - }, RequestContext(request)) - - -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - manage_workflow = manage_workflowREDESIGN - -def wg_shepherd_documents(request, acronym): - wg = get_object_or_404(IETFWG, group_acronym__acronym=acronym, group_type=1) - user = request.user - if not can_manage_shepherds_in_group(user, wg): - return HttpResponseForbidden('You have no permission to access this view') - current_person = get_person_for_user(user) - - base_qs = InternetDraft.objects.filter(group=wg, states__type="draft", states__slug="active").select_related("status").order_by('title') - documents_no_shepherd = base_qs.filter(shepherd=None) - documents_my = base_qs.filter(shepherd=current_person) - documents_other = base_qs.exclude(shepherd=None).exclude(shepherd__pk__in=[current_person.pk, 0]) - context = { - 'no_shepherd': documents_no_shepherd, - 'my_documents': documents_my, - 'other_shepherds': documents_other, - 'selected': 'manage_shepherds', - 'wg': wg, - } - return render_to_response('wgchairs/wg_shepherd_documents.html', context, RequestContext(request)) - diff --git a/ietf/wgcharter/feeds.py b/ietf/wgcharter/feeds.py index 5abf7708c..1dd8bbfff 100644 --- a/ietf/wgcharter/feeds.py +++ b/ietf/wgcharter/feeds.py @@ -26,7 +26,7 @@ class GroupChanges(Feed): def link(self, obj): if not obj: raise FeedDoesNotExist - return urlreverse('wg_charter', kwargs={'acronym': obj.acronym}) + return urlreverse('group_charter', kwargs={'acronym': obj.acronym}) def description(self, obj): return self.title(obj) @@ -44,7 +44,7 @@ class GroupChanges(Feed): if isinstance(obj, DocEvent): return urlreverse("doc_view", kwargs={'name': obj.doc_id }) elif isinstance(obj, GroupEvent): - return urlreverse('wg_charter', kwargs={'acronym': obj.group.acronym }) + return urlreverse('group_charter', kwargs={'acronym': obj.group.acronym }) def item_pubdate(self, obj): return obj.time diff --git a/ietf/wgcharter/mails.py b/ietf/wgcharter/mails.py index 29c603b4e..0f983a017 100644 --- a/ietf/wgcharter/mails.py +++ b/ietf/wgcharter/mails.py @@ -33,7 +33,7 @@ def email_secretariat(request, group, type, text): "wgcharter/email_secretariat.txt", dict(text=text, group=group, - group_url=settings.IDTRACKER_BASE_URL + urlreverse('wg_charter', kwargs=dict(acronym=group.acronym)), + group_url=settings.IDTRACKER_BASE_URL + urlreverse('group_charter', kwargs=dict(acronym=group.acronym)), charter_url=settings.IDTRACKER_BASE_URL + urlreverse('doc_view', kwargs=dict(name=group.charter.name)), ) ) diff --git a/ietf/wgcharter/tests.py b/ietf/wgcharter/tests.py index 56f639afb..7b55d9f91 100644 --- a/ietf/wgcharter/tests.py +++ b/ietf/wgcharter/tests.py @@ -21,10 +21,7 @@ from ietf.person.models import * from ietf.iesg.models import TelechatDate from ietf.wgcharter.utils import * -class EditCharterTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] - +class EditCharterTests(TestCase): def setUp(self): self.charter_dir = os.path.abspath("tmp-charter-dir") os.mkdir(self.charter_dir) @@ -198,10 +195,7 @@ class EditCharterTestCase(TestCase): self.assertEquals(f.read(), "Windows line\nMac line\nUnix line\n" + utf_8_snippet) -class ApproveCharterTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ['names'] - +class ApproveCharterTests(TestCase): def setUp(self): self.charter_dir = os.path.abspath("tmp-charter-dir") os.mkdir(self.charter_dir) diff --git a/ietf/wgcharter/views.py b/ietf/wgcharter/views.py index 37a9e389a..bd6697ead 100644 --- a/ietf/wgcharter/views.py +++ b/ietf/wgcharter/views.py @@ -4,7 +4,6 @@ from django.http import HttpResponse, HttpResponseRedirect, HttpResponseNotFound from django.shortcuts import render_to_response, get_object_or_404, redirect from django.template.loader import render_to_string from django.core.urlresolvers import reverse as urlreverse -from django.core.urlresolvers import reverse from django.template import RequestContext from django import forms from django.forms.util import ErrorList @@ -17,7 +16,7 @@ from django.contrib import messages from ietf.utils.mail import send_mail_preformatted from ietf.utils.textupload import get_cleaned_text_file_content from ietf.utils.history import find_history_active_at -from ietf.ietfauth.decorators import has_role, role_required +from ietf.ietfauth.utils import has_role, role_required from ietf.iesg.models import TelechatDate from ietf.doc.models import * from ietf.doc.utils import * @@ -319,7 +318,7 @@ def edit_ad(request, name): charter.time = e.time charter.save() - return HttpResponseRedirect(reverse('doc_view', kwargs={'name': charter.name})) + return redirect('doc_view', name=charter.name) else: init = { "ad" : charter.ad_id } form = AdForm(initial=init) diff --git a/ietf/wginfo/edit.py b/ietf/wginfo/edit.py index 89be89523..94dfb3950 100644 --- a/ietf/wginfo/edit.py +++ b/ietf/wginfo/edit.py @@ -1,9 +1,9 @@ # edit/create view for WGs -import re, os, string, datetime, shutil +import re, os, datetime, shutil from django.shortcuts import render_to_response, get_object_or_404, redirect -from django.core.urlresolvers import reverse +from django.http import HttpResponseForbidden from django.template import RequestContext from django import forms from django.utils import simplejson @@ -11,7 +11,7 @@ from django.utils.html import mark_safe import debug -from ietf.ietfauth.decorators import role_required, has_role +from ietf.ietfauth.utils import role_required, has_role from ietf.doc.models import * from ietf.name.models import * @@ -20,15 +20,18 @@ from ietf.group.models import * from ietf.group.utils import save_group_in_history from ietf.wgcharter.mails import email_secretariat from ietf.person.forms import EmailsField +from ietf.doc.utils import get_tags_for_stream_id +MAX_GROUP_DELEGATES = 3 class WGForm(forms.Form): - name = forms.CharField(max_length=255, label="WG Name", required=True) - acronym = forms.CharField(max_length=10, label="WG Acronym", required=True) - state = forms.ModelChoiceField(GroupStateName.objects.all(), label="WG State", required=True) - chairs = EmailsField(label="WG Chairs", required=False) - secretaries = EmailsField(label="WG Secretaries", required=False) - techadv = EmailsField(label="WG Technical Advisors", required=False) + name = forms.CharField(max_length=255, label="Name", required=True) + acronym = forms.CharField(max_length=10, label="Acronym", required=True) + state = forms.ModelChoiceField(GroupStateName.objects.all(), label="State", required=True) + chairs = EmailsField(label="Chairs", required=False) + secretaries = EmailsField(label="Secretaries", required=False) + techadv = EmailsField(label="Technical Advisors", required=False) + delegates = EmailsField(label="Delegates", required=False, help_text=mark_safe("Type in name to search for person
      Chairs can delegate the authority to update the state of group documents - max %s persons at a given time" % MAX_GROUP_DELEGATES)) ad = forms.ModelChoiceField(Person.objects.filter(role__name="ad", role__group__state="active").order_by('name'), label="Shepherding AD", empty_label="(None)", required=False) parent = forms.ModelChoiceField(Group.objects.filter(type="area", state="active").order_by('name'), label="IETF Area", empty_label="(None)", required=False) list_email = forms.CharField(max_length=64, required=False) @@ -100,6 +103,13 @@ class WGForm(forms.Form): def clean_urls(self): return [x.strip() for x in self.cleaned_data["urls"].splitlines() if x.strip()] + def clean_delegates(self): + if len(self.cleaned_data["delegates"]) > MAX_GROUP_DELEGATES: + raise forms.ValidationError("At most %s delegates can be appointed at the same time, please remove %s delegates." % ( + MAX_GROUP_DELEGATES, len(self.cleaned_data["delegates"]) - MAX_GROUP_DELEGATES)) + return self.cleaned_data["delegates"] + + def format_urls(urls, fs="\n"): res = [] for u in urls: @@ -224,7 +234,7 @@ def edit(request, acronym=None, action="edit"): shutil.copy(old, new) # update roles - for attr, slug, title in [('chairs', 'chair', "Chairs"), ('secretaries', 'secr', "Secretaries"), ('techadv', 'techadv', "Tech Advisors")]: + for attr, slug, title in [('chairs', 'chair', "Chairs"), ('secretaries', 'secr', "Secretaries"), ('techadv', 'techadv', "Tech Advisors"), ('delegates', 'delegate', "Delegates")]: new = clean[attr] old = Email.objects.filter(role__group=wg, role__name=slug).select_related("person") if set(new) != set(old): @@ -262,7 +272,7 @@ def edit(request, acronym=None, action="edit"): if action=="charter": return redirect('charter_submit', name=wg.charter.name, option="initcharter") - return redirect('wg_charter', acronym=wg.acronym) + return redirect('group_charter', acronym=wg.acronym) else: # form.is_valid() if not new_wg: from ietf.person.forms import json_emails @@ -272,6 +282,7 @@ def edit(request, acronym=None, action="edit"): chairs=Email.objects.filter(role__group=wg, role__name="chair"), secretaries=Email.objects.filter(role__group=wg, role__name="secr"), techadv=Email.objects.filter(role__group=wg, role__name="techadv"), + delegates=Email.objects.filter(role__group=wg, role__name="delegate"), ad=wg.ad_id if wg.ad else None, parent=wg.parent.id if wg.parent else None, list_email=wg.list_email if wg.list_email else None, @@ -316,7 +327,7 @@ def conclude(request, acronym): e.desc = "Requested closing group" e.save() - return redirect('wg_charter', acronym=wg.acronym) + return redirect('group_charter', acronym=wg.acronym) else: form = ConcludeForm() @@ -324,3 +335,89 @@ def conclude(request, acronym): dict(form=form, wg=wg), context_instance=RequestContext(request)) + + +def customize_workflow(request, acronym): + MANDATORY_STATES = ('c-adopt', 'wg-doc', 'sub-pub') + + group = get_object_or_404(Group, acronym=acronym, type="wg") + if not request.user.is_authenticated() or not (has_role(request.user, "Secretariat") or group.role_set.filter(name="chair", person__user=request.user)): + return HttpResponseForbidden("You don't have permission to access this view") + + if request.method == 'POST': + action = request.POST.get("action") + if action == "setstateactive": + active = request.POST.get("active") == "1" + try: + state = State.objects.exclude(slug__in=MANDATORY_STATES).get(pk=request.POST.get("state")) + except State.DoesNotExist: + return HttpResponse("Invalid state %s" % request.POST.get("state")) + + if active: + group.unused_states.remove(state) + else: + group.unused_states.add(state) + + # redirect so the back button works correctly, otherwise + # repeated POSTs fills up the history + return redirect("ietf.wginfo.edit.customize_workflow", acronym=group.acronym) + + if action == "setnextstates": + try: + state = State.objects.get(pk=request.POST.get("state")) + except State.DoesNotExist: + return HttpResponse("Invalid state %s" % request.POST.get("state")) + + next_states = State.objects.filter(used=True, type='draft-stream-ietf', pk__in=request.POST.getlist("next_states")) + unused = group.unused_states.all() + if set(next_states.exclude(pk__in=unused)) == set(state.next_states.exclude(pk__in=unused)): + # just use the default + group.groupstatetransitions_set.filter(state=state).delete() + else: + transitions, _ = GroupStateTransitions.objects.get_or_create(group=group, state=state) + transitions.next_states = next_states + + return redirect("ietf.wginfo.edit.customize_workflow", acronym=group.acronym) + + if action == "settagactive": + active = request.POST.get("active") == "1" + try: + tag = DocTagName.objects.get(pk=request.POST.get("tag")) + except DocTagName.DoesNotExist: + return HttpResponse("Invalid tag %s" % request.POST.get("tag")) + + if active: + group.unused_tags.remove(tag) + else: + group.unused_tags.add(tag) + + return redirect("ietf.wginfo.edit.customize_workflow", acronym=group.acronym) + + + # put some info for the template on tags and states + unused_tags = group.unused_tags.all().values_list('slug', flat=True) + tags = DocTagName.objects.filter(slug__in=get_tags_for_stream_id("ietf")) + for t in tags: + t.used = t.slug not in unused_tags + + unused_states = group.unused_states.all().values_list('slug', flat=True) + states = State.objects.filter(used=True, type="draft-stream-ietf") + transitions = dict((o.state, o) for o in group.groupstatetransitions_set.all()) + for s in states: + s.used = s.slug not in unused_states + s.mandatory = s.slug in MANDATORY_STATES + + default_n = s.next_states.all() + if s in transitions: + n = transitions[s].next_states.all() + else: + n = default_n + + s.next_states_checkboxes = [(x in n, x in default_n, x) for x in states] + s.used_next_states = [x for x in n if x.slug not in unused_states] + + return render_to_response('wginfo/customize_workflow.html', { + 'group': group, + 'states': states, + 'tags': tags, + }, RequestContext(request)) diff --git a/ietf/wginfo/mails.py b/ietf/wginfo/mails.py index 96b8bb6e8..02606d30e 100644 --- a/ietf/wginfo/mails.py +++ b/ietf/wginfo/mails.py @@ -16,7 +16,7 @@ def email_milestones_changed(request, group, changes): def wrap_up_email(to, text): text = wrap(strip_tags(text), 70) text += "\n\n" - text += u"URL: %s" % (settings.IDTRACKER_BASE_URL + urlreverse("wg_charter", kwargs=dict(acronym=group.acronym))) + text += u"URL: %s" % (settings.IDTRACKER_BASE_URL + urlreverse("group_charter", kwargs=dict(acronym=group.acronym))) send_mail_text(request, to, None, u"Milestones changed for %s %s" % (group.acronym, group.type.name), @@ -95,7 +95,7 @@ def email_milestones_due(group, early_warning_days): milestones=milestones, today=today, early_warning_days=early_warning_days, - url=settings.IDTRACKER_BASE_URL + urlreverse("wg_charter", kwargs=dict(acronym=group.acronym)) + url=settings.IDTRACKER_BASE_URL + urlreverse("group_charter", kwargs=dict(acronym=group.acronym)) )) def groups_needing_milestones_due_reminder(early_warning_days): @@ -120,7 +120,7 @@ def email_milestones_overdue(group): "wginfo/reminder_milestones_overdue.txt", dict(group=group, milestones=milestones, - url=settings.IDTRACKER_BASE_URL + urlreverse("wg_charter", kwargs=dict(acronym=group.acronym)) + url=settings.IDTRACKER_BASE_URL + urlreverse("group_charter", kwargs=dict(acronym=group.acronym)) )) def groups_needing_milestones_overdue_reminder(grace_period=30): diff --git a/ietf/wginfo/milestones.py b/ietf/wginfo/milestones.py index 3e7b3df64..31327caa9 100644 --- a/ietf/wginfo/milestones.py +++ b/ietf/wginfo/milestones.py @@ -3,7 +3,6 @@ import re, os, string, datetime, shutil, calendar from django.shortcuts import render_to_response, get_object_or_404, redirect -from django.core.urlresolvers import reverse from django.template import RequestContext from django import forms from django.http import HttpResponse, HttpResponseForbidden, HttpResponseBadRequest @@ -12,7 +11,7 @@ from django.utils.html import mark_safe, escape from django.utils.functional import lazy from django.core.urlresolvers import reverse as urlreverse -from ietf.ietfauth.decorators import role_required, has_role +from ietf.ietfauth.utils import role_required, has_role from ietf.doc.models import Document, DocEvent from ietf.doc.utils import get_chartering_type from ietf.group.models import * @@ -313,7 +312,7 @@ def edit_milestones(request, acronym, milestone_set="current"): if milestone_set == "charter": return redirect('doc_view', name=group.charter.canonical_name()) else: - return redirect('wg_charter', acronym=group.acronym) + return redirect('group_charter', acronym=group.acronym) else: for m in milestones: forms.append(MilestoneForm(instance=m, needs_review=needs_review)) diff --git a/ietf/wginfo/tests.py b/ietf/wginfo/tests.py index 4eaf80586..966ee201a 100644 --- a/ietf/wginfo/tests.py +++ b/ietf/wginfo/tests.py @@ -42,7 +42,6 @@ from ietf.utils import TestCase from pyquery import PyQuery import debug -from ietf.utils.test_utils import SimpleUrlTestCase from ietf.doc.models import * from ietf.group.models import * from ietf.group.utils import * @@ -50,42 +49,168 @@ from ietf.name.models import * from ietf.person.models import * from ietf.wginfo.mails import * +class GroupPagesTests(TestCase): + def setUp(self): + self.charter_dir = os.path.abspath("tmp-charter-dir") + os.mkdir(self.charter_dir) + settings.CHARTER_PATH = self.charter_dir -class WgInfoUrlTestCase(SimpleUrlTestCase): - def testUrls(self): - self.doTestUrls(__file__) + def tearDown(self): + shutil.rmtree(self.charter_dir) -class WgFileTestCase(unittest.TestCase): - def testFileExistence(self): - fpath = os.path.join(settings.IETFWG_DESCRIPTIONS_PATH, "tls.desc.txt") - if not os.path.exists(fpath): - print "\nERROR: charter files not found in "+settings.IETFWG_DESCRIPTIONS_PATH - print "They are needed for testing WG charter pages." - print "Download them to a local directory with:" - print "wget -nd -nc -np -r http://www.ietf.org/wg-descriptions/" - print "And set IETFWG_DESCRIPTIONS_PATH in settings_local.py\n" + def test_active_wgs(self): + draft = make_test_data() + group = draft.group -class WgOverviewTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ["names"] + url = urlreverse('ietf.wginfo.views.active_wgs') + r = self.client.get(url) + self.assertEquals(r.status_code, 200) + self.assertTrue(group.parent.name in r.content) + self.assertTrue(group.acronym in r.content) + self.assertTrue(group.name in r.content) + self.assertTrue(group.ad.plain_name() in r.content) - def test_overview(self): - make_test_data() + def test_wg_summaries(self): + draft = make_test_data() + group = draft.group - wg = Group.objects.get(acronym="mars") - wg.charter.set_state(State.objects.get(used=True, type="charter", slug="intrev")) + chair = Email.objects.filter(role__group=group, role__name="chair")[0] + + with open(os.path.join(self.charter_dir, "%s-%s.txt" % (group.charter.canonical_name(), group.charter.rev)), "w") as f: + f.write("This is a charter.") + + url = urlreverse('ietf.wginfo.views.wg_summary_area') + r = self.client.get(url) + self.assertEquals(r.status_code, 200) + self.assertTrue(group.parent.name in r.content) + self.assertTrue(group.acronym in r.content) + self.assertTrue(group.name in r.content) + self.assertTrue(chair.address in r.content) + + url = urlreverse('ietf.wginfo.views.wg_summary_acronym') + r = self.client.get(url) + self.assertEquals(r.status_code, 200) + self.assertTrue(group.acronym in r.content) + self.assertTrue(group.name in r.content) + self.assertTrue(chair.address in r.content) + + url = urlreverse('ietf.wginfo.views.wg_charters') + r = self.client.get(url) + self.assertEquals(r.status_code, 200) + self.assertTrue(group.acronym in r.content) + self.assertTrue(group.name in r.content) + self.assertTrue(group.ad.plain_name() in r.content) + self.assertTrue(chair.address in r.content) + self.assertTrue("This is a charter." in r.content) + + url = urlreverse('ietf.wginfo.views.wg_charters_by_acronym') + r = self.client.get(url) + self.assertEquals(r.status_code, 200) + self.assertTrue(group.acronym in r.content) + self.assertTrue(group.name in r.content) + self.assertTrue(group.ad.plain_name() in r.content) + self.assertTrue(chair.address in r.content) + self.assertTrue("This is a charter." in r.content) + + def test_chartering_wgs(self): + draft = make_test_data() + group = draft.group + group.charter.set_state(State.objects.get(used=True, type="charter", slug="intrev")) url = urlreverse('ietf.wginfo.views.chartering_wgs') r = self.client.get(url) self.assertEquals(r.status_code, 200) q = PyQuery(r.content) - self.assertEquals(len(q('table.ietf-doctable td.acronym a:contains("mars")')), 1) + self.assertEquals(len(q('table.ietf-doctable td.acronym a:contains("%s")' % group.acronym)), 1) + def test_bofs(self): + draft = make_test_data() + group = draft.group + group.state_id = "bof" + group.save() -class WgEditTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ["names"] + url = urlreverse('ietf.wginfo.views.bofs') + r = self.client.get(url) + self.assertEquals(r.status_code, 200) + q = PyQuery(r.content) + self.assertEquals(len(q('table.ietf-doctable td.acronym a:contains("%s")' % group.acronym)), 1) + + def test_group_documents(self): + draft = make_test_data() + group = draft.group + draft2 = Document.objects.create( + name="draft-somebody-mars-test", + time=datetime.datetime.now(), + type_id="draft", + title="Test By Somebody", + stream_id="ietf", + group=Group.objects.get(type="individ"), + abstract="Abstract.", + rev="01", + pages=2, + intended_std_level_id="ps", + shepherd=None, + ad=None, + expires=datetime.datetime.now() + datetime.timedelta(days=10), + notify="", + note="", + ) + + draft2.set_state(State.objects.get(used=True, type="draft", slug="active")) + DocAlias.objects.create( + document=draft2, + name=draft2.name, + ) + + url = urlreverse('ietf.wginfo.views.group_documents', kwargs=dict(acronym=group.acronym)) + r = self.client.get(url) + self.assertEquals(r.status_code, 200) + self.assertTrue(draft.name in r.content) + self.assertTrue(group.name in r.content) + self.assertTrue(group.acronym in r.content) + + self.assertTrue(draft2.name in r.content) + + def test_group_charter(self): + draft = make_test_data() + group = draft.group + + with open(os.path.join(self.charter_dir, "%s-%s.txt" % (group.charter.canonical_name(), group.charter.rev)), "w") as f: + f.write("This is a charter.") + + milestone = GroupMilestone.objects.create( + group=group, + state_id="active", + desc="Get Work Done", + due=datetime.date.today() + datetime.timedelta(days=100)) + milestone.docs.add(draft) + + url = urlreverse('ietf.wginfo.views.group_charter', kwargs=dict(acronym=group.acronym)) + r = self.client.get(url) + self.assertEquals(r.status_code, 200) + self.assertTrue(group.name in r.content) + self.assertTrue(group.acronym in r.content) + self.assertTrue("This is a charter." in r.content) + self.assertTrue(milestone.desc in r.content) + self.assertTrue(milestone.docs.all()[0].name in r.content) + + def test_history(self): + draft = make_test_data() + group = draft.group + + e = GroupEvent.objects.create( + group=group, + desc="Something happened.", + type="added_comment", + by=Person.objects.get(name="(System)")) + + url = urlreverse('ietf.wginfo.views.history', kwargs=dict(acronym=group.acronym)) + r = self.client.get(url) + self.assertEquals(r.status_code, 200) + self.assertTrue(e.desc in r.content) + +class GroupEditTests(TestCase): def setUp(self): self.charter_dir = os.path.abspath("tmp-charter-dir") os.mkdir(self.charter_dir) @@ -180,7 +305,7 @@ class WgEditTestCase(TestCase): make_test_data() group = Group.objects.get(acronym="mars") - url = urlreverse('wg_edit', kwargs=dict(acronym=group.acronym)) + url = urlreverse('group_edit', kwargs=dict(acronym=group.acronym)) login_testing_unauthorized(self, "secretary", url) # normal get @@ -225,6 +350,7 @@ class WgEditTestCase(TestCase): chairs="aread@ietf.org, ad1@ietf.org", secretaries="aread@ietf.org, ad1@ietf.org, ad2@ietf.org", techadv="aread@ietf.org", + delegates="ad2@ietf.org", list_email="mars@mail", list_subscribe="subscribe.mars", list_archive="archive.mars", @@ -245,6 +371,7 @@ class WgEditTestCase(TestCase): self.assertEquals(group.ad, ad) for k in ("chair", "secr", "techadv"): self.assertTrue(group.role_set.filter(name=k, email__address="aread@ietf.org")) + self.assertTrue(group.role_set.filter(name="delegate", email__address="ad2@ietf.org")) self.assertEquals(group.list_email, "mars@mail") self.assertEquals(group.list_subscribe, "subscribe.mars") self.assertEquals(group.list_archive, "archive.mars") @@ -281,10 +408,7 @@ class WgEditTestCase(TestCase): group = Group.objects.get(acronym=group.acronym) self.assertEquals(group.state_id, "active") -class MilestoneTestCase(TestCase): - # See ietf.utils.test_utils.TestCase for the use of perma_fixtures vs. fixtures - perma_fixtures = ["names"] - +class MilestoneTests(TestCase): def create_test_milestones(self): draft = make_test_data() @@ -688,3 +812,73 @@ class MilestoneTestCase(TestCase): self.assertTrue(group.acronym in outbox[-1]["Subject"]) self.assertTrue(m1.desc in unicode(outbox[-1])) self.assertTrue(m2.desc in unicode(outbox[-1])) + +class CustomizeWorkflowTests(TestCase): + def test_customize_workflow(self): + make_test_data() + + group = Group.objects.get(acronym="mars") + + url = urlreverse('ietf.wginfo.edit.customize_workflow', kwargs=dict(acronym=group.acronym)) + login_testing_unauthorized(self, "secretary", url) + + state = State.objects.get(used=True, type="draft-stream-ietf", slug="wg-lc") + self.assertTrue(state not in group.unused_states.all()) + + # get + r = self.client.get(url) + self.assertEquals(r.status_code, 200) + q = PyQuery(r.content) + self.assertEquals(len(q("form.set-state").find("input[name=state][value='%s']" % state.pk).parents("form").find("input[name=active][value='0']")), 1) + + # deactivate state + r = self.client.post(url, + dict(action="setstateactive", + state=state.pk, + active="0")) + self.assertEquals(r.status_code, 302) + r = self.client.get(url) + q = PyQuery(r.content) + self.assertEquals(len(q("form.set-state").find("input[name=state][value='%s']" % state.pk).parents("form").find("input[name=active][value='1']")), 1) + group = Group.objects.get(acronym=group.acronym) + self.assertTrue(state in group.unused_states.all()) + + # change next states + state = State.objects.get(used=True, type="draft-stream-ietf", slug="wg-doc") + next_states = State.objects.filter(used=True, type=b"draft-stream-ietf", slug__in=["parked", "dead", "wait-wgw", 'sub-pub']).values_list('pk', flat=True) + r = self.client.post(url, + dict(action="setnextstates", + state=state.pk, + next_states=next_states)) + self.assertEquals(r.status_code, 302) + r = self.client.get(url) + q = PyQuery(r.content) + self.assertEquals(len(q("form.set-next-states").find("input[name=state][value='%s']" % state.pk).parents('form').find("input[name=next_states][checked=checked]")), len(next_states)) + transitions = GroupStateTransitions.objects.filter(group=group, state=state) + self.assertEquals(len(transitions), 1) + self.assertEquals(set(transitions[0].next_states.values_list("pk", flat=True)), set(next_states)) + + # change them back to default + next_states = state.next_states.values_list("pk", flat=True) + r = self.client.post(url, + dict(action="setnextstates", + state=state.pk, + next_states=next_states)) + self.assertEquals(r.status_code, 302) + r = self.client.get(url) + q = PyQuery(r.content) + transitions = GroupStateTransitions.objects.filter(group=group, state=state) + self.assertEquals(len(transitions), 0) + + # deactivate tag + tag = DocTagName.objects.get(slug="w-expert") + r = self.client.post(url, + dict(action="settagactive", + tag=tag.pk, + active="0")) + self.assertEquals(r.status_code, 302) + r = self.client.get(url) + q = PyQuery(r.content) + self.assertEquals(len(q('form').find('input[name=tag][value="%s"]' % tag.pk).parents("form").find("input[name=active]")), 1) + group = Group.objects.get(acronym=group.acronym) + self.assertTrue(tag in group.unused_tags.all()) diff --git a/ietf/wginfo/testurl.list b/ietf/wginfo/testurl.list deleted file mode 100644 index 2cf38b30a..000000000 --- a/ietf/wginfo/testurl.list +++ /dev/null @@ -1,19 +0,0 @@ -200 /wg/ -404 /wg/nosuchgroup/ -200 /wg/tls/ -200 /wg/tls/charter/ -200 /wg/mobike/ # concluded -200 /wg/mobike/charter/ -200 /wg/catnip/ # concluded very long time ago -200 /wg/catnip/charter/ # concluded very long time ago -404 /wg/saag/ # not a WG -404 /wg/saag/charter/ # not a WG - -200 /wg/1wg-summary.txt -200 /wg/1wg-summary-by-acronym.txt -301 /wg/summary.txt -301 /wg/summary-by-area.txt -301 /wg/summary-by-acronym.txt -200,heavy /wg/1wg-charters.txt -200,heavy /wg/1wg-charters-by-acronym.txt - diff --git a/ietf/wginfo/urls.py b/ietf/wginfo/urls.py index 80651befd..b0106f144 100644 --- a/ietf/wginfo/urls.py +++ b/ietf/wginfo/urls.py @@ -6,7 +6,7 @@ from django.views.generic.simple import redirect_to urlpatterns = patterns('', - (r'^$', views.wg_dir), + (r'^$', views.active_wgs), (r'^summary.txt', redirect_to, { 'url':'/wg/1wg-summary.txt' }), (r'^summary-by-area.txt', redirect_to, { 'url':'/wg/1wg-summary.txt' }), (r'^summary-by-acronym.txt', redirect_to, { 'url':'/wg/1wg-summary-by-acronym.txt' }), @@ -18,17 +18,16 @@ urlpatterns = patterns('', (r'^bofs/$', views.bofs), (r'^chartering/create/$', edit.edit, {'action': "charter"}, "wg_create"), (r'^bofs/create/$', edit.edit, {'action': "create"}, "bof_create"), - (r'^(?P[a-zA-Z0-9-]+)/documents/txt/$', views.wg_documents_txt), - (r'^(?P[a-zA-Z0-9-]+)/$', views.wg_documents_html, None, "wg_docs"), - (r'^(?P[a-zA-Z0-9-]+)/charter/$', views.wg_charter, None, 'wg_charter'), + (r'^(?P[a-zA-Z0-9-]+)/documents/txt/$', views.group_documents_txt), + (r'^(?P[a-zA-Z0-9-]+)/$', views.group_documents, None, "wg_docs"), + (r'^(?P[a-zA-Z0-9-]+)/charter/$', views.group_charter, None, 'group_charter'), (r'^(?P[a-zA-Z0-9-]+)/init-charter/', edit.submit_initial_charter, None, "wg_init_charter"), (r'^(?P[a-zA-Z0-9-]+)/history/$', views.history), - (r'^(?P[a-zA-Z0-9-]+)/edit/$', edit.edit, {'action': "edit"}, "wg_edit"), + (r'^(?P[a-zA-Z0-9-]+)/edit/$', edit.edit, {'action': "edit"}, "group_edit"), (r'^(?P[a-zA-Z0-9-]+)/conclude/$', edit.conclude, None, "wg_conclude"), (r'^(?P[a-zA-Z0-9-]+)/milestones/$', milestones.edit_milestones, {'milestone_set': "current"}, "wg_edit_milestones"), (r'^(?P[a-zA-Z0-9-]+)/milestones/charter/$', milestones.edit_milestones, {'milestone_set': "charter"}, "wg_edit_charter_milestones"), (r'^(?P[a-zA-Z0-9-]+)/milestones/charter/reset/$', milestones.reset_charter_milestones, None, "wg_reset_charter_milestones"), (r'^(?P[a-zA-Z0-9-]+)/ajax/searchdocs/$', milestones.ajax_search_docs, None, "wg_ajax_search_docs"), - (r'^(?P[^/]+)/management/', include('ietf.wgchairs.urls')), - + (r'^(?P[a-zA-Z0-9-]+)/workflow/$', edit.customize_workflow), ) diff --git a/ietf/wginfo/views.py b/ietf/wginfo/views.py index 6caaf6f7d..5d5c12795 100644 --- a/ietf/wginfo/views.py +++ b/ietf/wginfo/views.py @@ -32,106 +32,126 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import itertools + from django.shortcuts import get_object_or_404, render_to_response -from django.template import RequestContext, loader +from django.template import RequestContext from django.http import HttpResponse from django.conf import settings from django.core.urlresolvers import reverse as urlreverse -from ietf.idtracker.models import Area, IETFWG + from ietf.doc.views_search import SearchForm, retrieve_search_results -from ietf.idrfc.idrfc_wrapper import IdRfcWrapper -from ietf.ipr.models import IprDetail -from ietf.group.models import Group -from ietf.doc.models import State +from ietf.group.models import Group, GroupURL, Role +from ietf.doc.models import State, DocAlias, RelatedDocument from ietf.doc.utils import get_chartering_type +from ietf.group.utils import get_charter_text +from ietf.doc.templatetags.ietf_filters import clean_whitespace +from ietf.ietfauth.utils import has_role +def roles(group, role_name): + return Role.objects.filter(group=group, name=role_name).select_related("email", "person") -def fill_in_charter_info(wg, include_drafts=False): - from ietf.person.models import Email - from ietf.doc.models import DocAlias, RelatedDocument +def fill_in_charter_info(group, include_drafts=False): + group.areadirector = group.ad.role_email("ad", group.parent) if group.ad else None + group.chairs = roles(group, "chair") + group.techadvisors = roles(group, "techadv") + group.editors = roles(group, "editor") + group.secretaries = roles(group, "secr") + milestone_state = "charter" if group.state_id == "proposed" else "active" + group.milestones = group.groupmilestone_set.filter(state=milestone_state).order_by('due') - wg.areadirector = wg.ad.role_email("ad", wg.parent) if wg.ad else None - wg.chairs = Email.objects.filter(role__group=wg, role__name="chair") - wg.techadvisors = Email.objects.filter(role__group=wg, role__name="techadv") - wg.editors = Email.objects.filter(role__group=wg, role__name="editor") - wg.secretaries = Email.objects.filter(role__group=wg, role__name="secr") - milestone_state = "charter" if wg.state_id == "proposed" else "active" - wg.milestones = wg.groupmilestone_set.filter(state=milestone_state).order_by('due') + if group.charter: + group.charter_text = get_charter_text(group) + else: + group.charter_text = u"Not chartered yet." if include_drafts: - aliases = DocAlias.objects.filter(document__type="draft", document__group=wg).select_related('document').order_by("name") - wg.drafts = [] - wg.rfcs = [] + aliases = DocAlias.objects.filter(document__type="draft", document__group=group).select_related('document').order_by("name") + group.drafts = [] + group.rfcs = [] for a in aliases: if a.name.startswith("draft"): - wg.drafts.append(a) + group.drafts.append(a) else: - wg.rfcs.append(a) + group.rfcs.append(a) a.rel = RelatedDocument.objects.filter(source=a.document).distinct() a.invrel = RelatedDocument.objects.filter(target=a).distinct() -def wg_summary_acronym(request): - areas = Area.active_areas() - wgs = IETFWG.objects.filter(status=IETFWG.ACTIVE) - return HttpResponse(loader.render_to_string('wginfo/1wg-summary-by-acronym.txt', {'area_list': areas, 'wg_list': wgs}),mimetype='text/plain; charset=UTF-8') +def extract_last_name(role): + return role.person.name_parts()[3] def wg_summary_area(request): - wgs = IETFWG.objects.filter(status='1',group_type='1',start_date__isnull=False).exclude(parent=None) - return HttpResponse(loader.render_to_string('wginfo/1wg-summary.txt', {'wg_list': wgs}),mimetype='text/plain; charset=UTF-8') - -def wg_charters(request): - wgs = IETFWG.objects.filter(status='1',group_type='1',start_date__isnull=False).exclude(parent=None) - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - for wg in wgs: - fill_in_charter_info(wg, include_drafts=True) - return HttpResponse(loader.render_to_string('wginfo/1wg-charters.txt', {'wg_list': wgs, 'USE_DB_REDESIGN_PROXY_CLASSES': settings.USE_DB_REDESIGN_PROXY_CLASSES}),mimetype='text/plain; charset=UTF-8') - -def wg_charters_by_acronym(request): - wgs = IETFWG.objects.filter(status='1',group_type='1',start_date__isnull=False) - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - for wg in wgs: - fill_in_charter_info(wg, include_drafts=True) - return HttpResponse(loader.render_to_string('wginfo/1wg-charters-by-acronym.txt', {'wg_list': wgs, 'USE_DB_REDESIGN_PROXY_CLASSES': settings.USE_DB_REDESIGN_PROXY_CLASSES}),mimetype='text/plain; charset=UTF-8') - -def wg_dir(request): - areas = Area.active_areas() - return render_to_response('wginfo/wg-dir.html', {'areas':areas}, RequestContext(request)) - -def wg_dirREDESIGN(request): - from ietf.group.models import Group, GroupURL - from ietf.person.models import Email - areas = Group.objects.filter(type="area", state="active").order_by("name") for area in areas: - area.ads = [] - for e in Email.objects.filter(role__group=area, role__name="ad").select_related("person"): - e.incoming = False - area.ads.append(e) + area.ads = sorted(roles(area, "ad"), key=extract_last_name) + area.groups = Group.objects.filter(parent=area, type="wg", state="active").order_by("acronym") + for group in area.groups: + group.chairs = sorted(roles(group, "chair"), key=extract_last_name) - for e in Email.objects.filter(role__group=area, role__name="pre-ad").select_related("person"): - e.incoming = True - area.ads.append(e) + areas = [a for a in areas if a.groups] - area.ads.sort(key=lambda e: (e.incoming, e.person.name_parts()[3])) - area.wgs = Group.objects.filter(parent=area, type="wg", state="active").order_by("acronym") + return render_to_response('wginfo/1wg-summary.txt', + { 'areas': areas }, + mimetype='text/plain; charset=UTF-8') + +def wg_summary_acronym(request): + areas = Group.objects.filter(type="area", state="active").order_by("name") + groups = Group.objects.filter(type="wg", state="active").order_by("acronym").select_related("parent") + for group in groups: + group.chairs = sorted(roles(group, "chair"), key=extract_last_name) + return render_to_response('wginfo/1wg-summary-by-acronym.txt', + { 'areas': areas, + 'groups': groups }, + mimetype='text/plain; charset=UTF-8') + +def wg_charters(request): + areas = Group.objects.filter(type="area", state="active").order_by("name") + for area in areas: + area.ads = sorted(roles(area, "ad"), key=extract_last_name) + area.groups = Group.objects.filter(parent=area, type="wg", state="active").order_by("name") + for group in area.groups: + fill_in_charter_info(group, include_drafts=True) + group.area = area + return render_to_response('wginfo/1wg-charters.txt', + { 'areas': areas }, + mimetype='text/plain; charset=UTF-8') + +def wg_charters_by_acronym(request): + areas = dict((a.id, a) for a in Group.objects.filter(type="area", state="active").order_by("name")) + + for area in areas.itervalues(): + area.ads = sorted(roles(area, "ad"), key=extract_last_name) + + groups = Group.objects.filter(type="wg", state="active").exclude(parent=None).order_by("acronym") + for group in groups: + fill_in_charter_info(group, include_drafts=True) + group.area = areas.get(group.parent_id) + return render_to_response('wginfo/1wg-charters-by-acronym.txt', + { 'groups': groups }, + mimetype='text/plain; charset=UTF-8') + +def active_wgs(request): + areas = Group.objects.filter(type="area", state="active").order_by("name") + for area in areas: + # dig out information for template + area.ads = (list(sorted(roles(area, "ad"), key=extract_last_name)) + + list(sorted(roles(area, "pre-ad"), key=extract_last_name))) + + area.groups = Group.objects.filter(parent=area, type="wg", state="active").order_by("acronym") area.urls = area.groupurl_set.all().order_by("name") - for wg in area.wgs: - wg.chairs = sorted(Email.objects.filter(role__group=wg, role__name="chair").select_related("person"), key=lambda e: e.person.name_parts()[3]) - - return render_to_response('wginfo/wg-dirREDESIGN.html', {'areas':areas}, RequestContext(request)) + for group in area.groups: + group.chairs = sorted(roles(group, "chair"), key=extract_last_name) -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - wg_dir = wg_dirREDESIGN + return render_to_response('wginfo/active_wgs.html', {'areas':areas}, RequestContext(request)) def bofs(request): groups = Group.objects.filter(type="wg", state="bof") - return render_to_response('wginfo/bofs.html',dict(groups=groups),RequestContext(request)) + return render_to_response('wginfo/bofs.html',dict(groups=groups), RequestContext(request)) def chartering_wgs(request): charter_states = State.objects.filter(used=True, type="charter").exclude(slug__in=("approved", "notrev")) groups = Group.objects.filter(type="wg", charter__states__in=charter_states).select_related("state", "charter") - for g in groups: g.chartering_type = get_chartering_type(g.charter) @@ -141,32 +161,56 @@ def chartering_wgs(request): RequestContext(request)) -def wg_documents(request, acronym): - wg = get_object_or_404(IETFWG, group_acronym__acronym=acronym, group_type=1) - concluded = wg.status_id in [ 2, 3, ] - proposed = (wg.status_id == 4) - form = SearchForm({'by':'group', 'group':str(wg.group_acronym.acronym), - 'rfcs':'on', 'activedrafts':'on'}) +def construct_group_menu_context(request, group, selected, others): + """Return context with info for the group menu filled in.""" + actions = [] + + is_chair = group.has_role(request.user, "chair") + is_ad_or_secretariat = has_role(request.user, ("Area Director", "Secretariat")) + + if group.state_id != "proposed" and (is_chair or is_ad_or_secretariat): + actions.append((u"Add or edit milestones", urlreverse("wg_edit_milestones", kwargs=dict(acronym=group.acronym)))) + + if group.state_id != "conclude" and is_ad_or_secretariat: + actions.append((u"Edit group", urlreverse("group_edit", kwargs=dict(acronym=group.acronym)))) + + if is_chair or is_ad_or_secretariat: + actions.append((u"Customize workflow", urlreverse("ietf.wginfo.edit.customize_workflow", kwargs=dict(acronym=group.acronym)))) + + if group.state_id in ("active", "dormant") and is_ad_or_secretariat: + actions.append((u"Request closing group", urlreverse("wg_conclude", kwargs=dict(acronym=group.acronym)))) + + d = { + "group": group, + "selected": selected, + "menu_actions": actions, + } + + d.update(others) + + return d + +def search_for_group_documents(group): + form = SearchForm({ 'by':'group', 'group': group.acronym or "", 'rfcs':'on', 'activedrafts': 'on' }) docs, meta = retrieve_search_results(form) # get the related docs - form_related = SearchForm({'by':'group', 'name':'-'+str(wg.group_acronym.acronym)+'-', 'activedrafts':'on'}) - docs_related, meta_related = retrieve_search_results(form_related) - docs_related_pruned = [] - for d in docs_related: + form_related = SearchForm({ 'by':'group', 'name': u'-%s-' % group.acronym, 'activedrafts': 'on' }) + raw_docs_related, meta_related = retrieve_search_results(form_related) + + docs_related = [] + for d in raw_docs_related: parts = d.name.split("-", 2); # canonical form draft--wg-etc - if len(parts) >= 3 and parts[1] != "ietf" and parts[2].startswith(wg.group_acronym.acronym + "-"): + if len(parts) >= 3 and parts[1] != "ietf" and parts[2].startswith(group.acronym + "-"): d.search_heading = "Related Internet-Draft" - docs_related_pruned.append(d) - - docs_related = docs_related_pruned + docs_related.append(d) # move call for WG adoption to related cleaned_docs = [] docs_related_names = set(d.name for d in docs_related) for d in docs: - if d.stream_id == "ietf" and d.get_state_slug("draft-stream-ietf") in [ "c-adopt", "wg-cand" ]: + if d.stream_id and d.get_state_slug("draft-stream-%s" % d.stream_id) in ("c-adopt", "wg-cand"): if d.name not in docs_related_names: d.search_heading = "Related Internet-Draft" docs_related.append(d) @@ -177,59 +221,68 @@ def wg_documents(request, acronym): docs_related.sort(key=lambda d: d.name) - return wg, concluded, proposed, docs, meta, docs_related, meta_related + return docs, meta, docs_related, meta_related -def wg_documents_txt(request, acronym): - wg, concluded, proposed, docs, meta, docs_related, meta_related = wg_documents(request, acronym) - return HttpResponse(loader.render_to_string('wginfo/wg_documents.txt', {'wg': wg, 'concluded':concluded, 'proposed':proposed, 'selected':'documents', 'docs':docs, 'meta':meta, 'docs_related':docs_related, 'meta_related':meta_related}),mimetype='text/plain; charset=UTF-8') +def group_documents(request, acronym): + group = get_object_or_404(Group, type="wg", acronym=acronym) -def wg_documents_html(request, acronym): - wg, concluded, proposed, docs, meta, docs_related, meta_related = wg_documents(request, acronym) - return render_to_response('wginfo/wg_documents.html', {'wg': wg, 'concluded':concluded, 'proposed':proposed, 'selected':'documents', 'docs':docs, 'meta':meta, 'docs_related':docs_related, 'meta_related':meta_related}, RequestContext(request)) + docs, meta, docs_related, meta_related = search_for_group_documents(group) -def wg_charter(request, acronym): - wg = get_object_or_404(IETFWG, group_acronym__acronym=acronym, group_type=1) - concluded = wg.status_id in [ 2, 3, ] - proposed = (wg.status_id == 4) + return render_to_response('wginfo/group_documents.html', + construct_group_menu_context(request, group, "documents", { + 'docs': docs, + 'meta': meta, + 'docs_related': docs_related, + 'meta_related': meta_related + }), RequestContext(request)) - fill_in_charter_info(wg) - actions = [] - if wg.state_id != "conclude": - actions.append(("Edit WG", urlreverse("wg_edit", kwargs=dict(acronym=wg.acronym)))) +def group_documents_txt(request, acronym): + """Return tabulator-separated rows with documents for group.""" + group = get_object_or_404(Group, type="wg", acronym=acronym) - e = wg.latest_event(type__in=("changed_state", "requested_close",)) - requested_close = wg.state_id != "conclude" and e and e.type == "requested_close" + docs, meta, docs_related, meta_related = search_for_group_documents(group) - if wg.state_id in ("active", "dormant"): - actions.append(("Request closing WG", urlreverse("wg_conclude", kwargs=dict(acronym=wg.acronym)))) + for d in docs: + d.prefix = d.get_state().name - context = get_wg_menu_context(wg, "charter") - context.update(dict( - actions=actions, - is_chair=request.user.is_authenticated() and wg.role_set.filter(name="chair", person__user=request.user), - milestones_in_review=wg.groupmilestone_set.filter(state="review"), - requested_close=requested_close, - )) + for d in docs_related: + d.prefix = u"Related %s" % d.get_state().name - return render_to_response('wginfo/wg_charter.html', - context, - RequestContext(request)) + rows = [] + for d in itertools.chain(docs, docs_related): + rfc_number = d.rfc_number() + if rfc_number != None: + name = rfc_number + else: + name = "%s-%s" % (d.name, d.rev) -def get_wg_menu_context(wg, selected): - # it would probably be better to refactor wginfo into rendering - # the menu separately instead of each view having to include the information + rows.append(u"\t".join((d.prefix, name, clean_whitespace(d.title)))) + + return HttpResponse(u"\n".join(rows), mimetype='text/plain; charset=UTF-8') + + +def group_charter(request, acronym): + group = get_object_or_404(Group, type="wg", acronym=acronym) + + fill_in_charter_info(group, include_drafts=False) + group.delegates = roles(group, "delegate") + + e = group.latest_event(type__in=("changed_state", "requested_close",)) + requested_close = group.state_id != "conclude" and e and e.type == "requested_close" + + return render_to_response('wginfo/group_charter.html', + construct_group_menu_context(request, group, "charter", { + "milestones_in_review": group.groupmilestone_set.filter(state="review"), + "requested_close": requested_close, + }), RequestContext(request)) - return dict(wg=wg, concluded=wg.state_id == "conclude", proposed=wg.state_id == "proposed", selected=selected) def history(request, acronym): - wg = get_object_or_404(Group, acronym=acronym) + group = get_object_or_404(Group, acronym=acronym) - events = wg.groupevent_set.all().select_related('by').order_by('-time', '-id') + events = group.groupevent_set.all().select_related('by').order_by('-time', '-id') - context = get_wg_menu_context(wg, "history") - context.update(dict(events=events, - )) - - wg.group_acronym = wg # hack for compatibility with old templates - - return render_to_response('wginfo/history.html', context, RequestContext(request)) + return render_to_response('wginfo/history.html', + construct_group_menu_context(request, group, "history", { + "events": events, + }), RequestContext(request)) diff --git a/permissions/.gitignore b/permissions/.gitignore deleted file mode 100644 index a74b07aee..000000000 --- a/permissions/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/*.pyc diff --git a/permissions/__init__.py b/permissions/__init__.py deleted file mode 100644 index b81c7766c..000000000 --- a/permissions/__init__.py +++ /dev/null @@ -1,148 +0,0 @@ -import permissions.utils - -class PermissionBase(object): - """Mix-in class for permissions. - """ - def grant_permission(self, role, permission): - """Grants passed permission to passed role. Returns True if the - permission was able to be added, otherwise False. - - **Parameters:** - - role - The role for which the permission should be granted. - - permission - The permission which should be granted. Either a permission - object or the codename of a permission. - """ - return permissions.utils.grant_permission(self, role, permission) - - def remove_permission(self, role, permission): - """Removes passed permission from passed role. Returns True if the - permission has been removed. - - **Parameters:** - - role - The role for which a permission should be removed. - - permission - The permission which should be removed. Either a permission object - or the codename of a permission. - """ - return permissions.utils.remove_permission(self, role, permission) - - def has_permission(self, user, permission, roles=[]): - """Returns True if the passed user has passed permission for this - instance. Otherwise False. - - **Parameters:** - - permission - The permission's codename which should be checked. Must be a - string with a valid codename. - - user - The user for which the permission should be checked. - - roles - If passed, these roles will be assigned to the user temporarily - before the permissions are checked. - """ - return permissions.utils.has_permission(self, user, permission, roles) - - def check_permission(self, user, permission, roles=[]): - """Raise Unauthorized if the the passed user hasn't passed permission - for this instance. - - **Parameters:** - - permission - The permission's codename which should be checked. Must be a - string with a valid codename. - - user - The user for which the permission should be checked. - - roles - If passed, these roles will be assigned to the user temporarily - before the permissions are checked. - """ - if not self.has_permission(user, permission, roles): - raise Unauthorized("User %s doesn't have permission %s for object %s" % (user, permission, obj.slug)) - - def add_inheritance_block(self, permission): - """Adds an inheritance block for the passed permission. - - **Parameters:** - - permission - The permission for which an inheritance block should be added. - Either a permission object or the codename of a permission. - """ - return permissions.utils.add_inheritance_block(self, permission) - - def remove_inheritance_block(self, permission): - """Removes a inheritance block for the passed permission. - - **Parameters:** - - permission - The permission for which an inheritance block should be removed. - Either a permission object or the codename of a permission. - """ - return permissions.utils.remove_inheritance_block(self, permission) - - def is_inherited(self, codename): - """Returns True if the passed permission is inherited. - - **Parameters:** - - codename - The permission which should be checked. Must be the codename of - the permission. - """ - return permissions.utils.is_inherited(self, codename) - - def add_role(self, principal, role): - """Adds a local role for the principal. - - **Parameters:** - - principal - The principal (user or group) which gets the role. - - role - The role which is assigned. - """ - return permissions.utils.add_local_role(self, principal, role) - - def get_roles(self, principal): - """Returns *direct* local roles for passed principal (user or group). - """ - return permissions.utils.get_local_roles(self, principal) - - def remove_role(self, principal, role): - """Adds a local role for the principal to the object. - - **Parameters:** - - principal - The principal (user or group) from which the role is removed. - - role - The role which is removed. - """ - return permissions.utils.remove_local_role(self, principal, role) - - def remove_roles(self, principal): - """Removes all local roles for the passed principal from the object. - - **Parameters:** - - principal - The principal (user or group) from which all local roles are - removed. - """ - return permissions.utils.remove_local_roles(self, principal) \ No newline at end of file diff --git a/permissions/backend.py b/permissions/backend.py deleted file mode 100644 index a0c2d8ec6..000000000 --- a/permissions/backend.py +++ /dev/null @@ -1,45 +0,0 @@ -# permissions imports -import permissions.utils - -class ObjectPermissionsBackend(object): - """Django backend for object permissions. Needs Django 1.2. - - - Use it together with the default ModelBackend like so:: - - AUTHENTICATION_BACKENDS = ( - 'django.contrib.auth.backends.ModelBackend', - 'permissions.backend.ObjectPermissionsBackend', - ) - - Then you can use it like: - - user.has_perm("view", your_object) - - """ - supports_object_permissions = True - supports_anonymous_user = True - - def authenticate(self, username, password): - return None - - def has_perm(self, user_obj, perm, obj=None): - """Checks whether the passed user has passed permission for passed - object (obj). - - This should be the primary method to check wether a user has a certain - permission. - - Parameters - ========== - - perm - The permission's codename which should be checked. - - user_obj - The user for which the permission should be checked. - - obj - The object for which the permission should be checked. - """ - return permissions.utils.has_permission(obj, user_obj, perm) \ No newline at end of file diff --git a/permissions/exceptions.py b/permissions/exceptions.py deleted file mode 100644 index 72c24a317..000000000 --- a/permissions/exceptions.py +++ /dev/null @@ -1,3 +0,0 @@ -class Unauthorized(Exception): - def __init__(self, str): - super(Unauthorized, self).__init__(str) \ No newline at end of file diff --git a/permissions/fixtures/initial.xml b/permissions/fixtures/initial.xml deleted file mode 100644 index 914abf8f1..000000000 --- a/permissions/fixtures/initial.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - View - view - - - Edit - edit - - - Delete - delete - - - Cut - cut - - - Copy - copy - - diff --git a/permissions/locale/de/LC_MESSAGES/django.mo b/permissions/locale/de/LC_MESSAGES/django.mo deleted file mode 100644 index 37b653476..000000000 Binary files a/permissions/locale/de/LC_MESSAGES/django.mo and /dev/null differ diff --git a/permissions/locale/de/LC_MESSAGES/django.po b/permissions/locale/de/LC_MESSAGES/django.po deleted file mode 100644 index 0a7e9e9cb..000000000 --- a/permissions/locale/de/LC_MESSAGES/django.po +++ /dev/null @@ -1,52 +0,0 @@ -# German translations for django-permissions -# Copyright (C) 2010 Kai Diefenbach -# This file is distributed under the same license as the PACKAGE package. -# Kai Diefenbach , 2010. -# -msgid "" -msgstr "" -"Project-Id-Version: 1.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2010-03-30 23:12+0200\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: models.py:154 -msgid "Name" -msgstr "Name" - -#: models.py:155 -msgid "Codename" -msgstr "Codename" - -#: models.py:156 -msgid "Content Types" -msgstr "Inhaltstypen" - -#: models.py:175 models.py:280 -msgid "Role" -msgstr "Rolle" - -#: models.py:176 models.py:216 -msgid "Permission" -msgstr "Recht" - -#: models.py:178 models.py:218 models.py:282 -msgid "Content type" -msgstr "Inhaltstyp" - -#: models.py:179 models.py:219 models.py:283 -msgid "Content id" -msgstr "Inhalts-ID" - -#: models.py:278 -msgid "User" -msgstr "Benutzer" - -#: models.py:279 -msgid "Group" -msgstr "Gruppe" diff --git a/permissions/migrations/.gitignore b/permissions/migrations/.gitignore deleted file mode 100644 index a74b07aee..000000000 --- a/permissions/migrations/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/*.pyc diff --git a/permissions/migrations/0001_initial.py b/permissions/migrations/0001_initial.py deleted file mode 100644 index 38e36b067..000000000 --- a/permissions/migrations/0001_initial.py +++ /dev/null @@ -1,154 +0,0 @@ - -from south.db import db -from django.db import models -from permissions.models import * - -class Migration: - - def forwards(self, orm): - - # Adding model 'Role' - db.create_table('permissions_role', ( - ('id', orm['permissions.Role:id']), - ('name', orm['permissions.Role:name']), - )) - db.send_create_signal('permissions', ['Role']) - - # Adding model 'ObjectPermissionInheritanceBlock' - db.create_table('permissions_objectpermissioninheritanceblock', ( - ('id', orm['permissions.ObjectPermissionInheritanceBlock:id']), - ('permission', orm['permissions.ObjectPermissionInheritanceBlock:permission']), - ('content_type', orm['permissions.ObjectPermissionInheritanceBlock:content_type']), - ('content_id', orm['permissions.ObjectPermissionInheritanceBlock:content_id']), - )) - db.send_create_signal('permissions', ['ObjectPermissionInheritanceBlock']) - - # Adding model 'ObjectPermission' - db.create_table('permissions_objectpermission', ( - ('id', orm['permissions.ObjectPermission:id']), - ('role', orm['permissions.ObjectPermission:role']), - ('permission', orm['permissions.ObjectPermission:permission']), - ('content_type', orm['permissions.ObjectPermission:content_type']), - ('content_id', orm['permissions.ObjectPermission:content_id']), - )) - db.send_create_signal('permissions', ['ObjectPermission']) - - # Adding model 'Permission' - db.create_table('permissions_permission', ( - ('id', orm['permissions.Permission:id']), - ('name', orm['permissions.Permission:name']), - ('codename', orm['permissions.Permission:codename']), - )) - db.send_create_signal('permissions', ['Permission']) - - # Adding model 'PrincipalRoleRelation' - db.create_table('permissions_principalrolerelation', ( - ('id', orm['permissions.PrincipalRoleRelation:id']), - ('user', orm['permissions.PrincipalRoleRelation:user']), - ('group', orm['permissions.PrincipalRoleRelation:group']), - ('role', orm['permissions.PrincipalRoleRelation:role']), - ('content_type', orm['permissions.PrincipalRoleRelation:content_type']), - ('content_id', orm['permissions.PrincipalRoleRelation:content_id']), - )) - db.send_create_signal('permissions', ['PrincipalRoleRelation']) - - # Adding ManyToManyField 'Permission.content_types' - db.create_table('permissions_permission_content_types', ( - ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), - ('permission', models.ForeignKey(orm.Permission, null=False)), - ('contenttype', models.ForeignKey(orm['contenttypes.ContentType'], null=False)) - )) - - - - def backwards(self, orm): - - # Deleting model 'Role' - db.delete_table('permissions_role') - - # Deleting model 'ObjectPermissionInheritanceBlock' - db.delete_table('permissions_objectpermissioninheritanceblock') - - # Deleting model 'ObjectPermission' - db.delete_table('permissions_objectpermission') - - # Deleting model 'Permission' - db.delete_table('permissions_permission') - - # Deleting model 'PrincipalRoleRelation' - db.delete_table('permissions_principalrolerelation') - - # Dropping ManyToManyField 'Permission.content_types' - db.delete_table('permissions_permission_content_types') - - - - models = { - 'auth.group': { - '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': "orm['auth.Permission']", 'blank': 'True'}) - }, - 'auth.permission': { - 'Meta': {'unique_together': "(('content_type', 'codename'),)"}, - 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'auth.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', [], {'to': "orm['auth.Group']", 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), - 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - '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', [], {'to': "orm['auth.Permission']", 'blank': 'True'}), - 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) - }, - 'contenttypes.contenttype': { - 'Meta': {'unique_together': "(('app_label', 'model'),)", 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - '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'}) - }, - 'permissions.objectpermission': { - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']"}), - 'role': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Role']", 'null': 'True', 'blank': 'True'}) - }, - 'permissions.objectpermissioninheritanceblock': { - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']"}) - }, - 'permissions.permission': { - 'codename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'content_types': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}) - }, - 'permissions.principalrolerelation': { - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}), - 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'role': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Role']"}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}) - }, - 'permissions.role': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}) - } - } - - complete_apps = ['permissions'] diff --git a/permissions/migrations/__init__.py b/permissions/migrations/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/permissions/models.py b/permissions/models.py deleted file mode 100644 index 478fbdf9d..000000000 --- a/permissions/models.py +++ /dev/null @@ -1,190 +0,0 @@ -# django imports -from django.db import models -from django.contrib.auth.models import User -from django.contrib.auth.models import Group -from django.contrib.contenttypes import generic -from django.contrib.contenttypes.models import ContentType -from django.utils.translation import ugettext_lazy as _ - -class Permission(models.Model): - """A permission which can be granted to users/groups and objects. - - **Attributes:** - - name - The unique name of the permission. This is displayed to users. - - codename - The unique codename of the permission. This is used internal to - identify a permission. - - content_types - The content types for which the permission is active. This can be - used to display only reasonable permissions for an object. - """ - name = models.CharField(_(u"Name"), max_length=100, unique=True) - codename = models.CharField(_(u"Codename"), max_length=100, unique=True) - content_types = models.ManyToManyField(ContentType, verbose_name=_(u"Content Types"), blank=True, null=True, related_name="content_types") - - def __unicode__(self): - return "%s (%s)" % (self.name, self.codename) - -class ObjectPermission(models.Model): - """Grants permission for specific user/group and object. - - **Attributes:** - - role - The role for which the permission is granted. - - permission - The permission which is granted. - - content - The object for which the permission is granted. - """ - role = models.ForeignKey("Role", verbose_name=_(u"Role"), blank=True, null=True) - permission = models.ForeignKey(Permission, verbose_name=_(u"Permission")) - - content_type = models.ForeignKey(ContentType, verbose_name=_(u"Content type")) - content_id = models.PositiveIntegerField(verbose_name=_(u"Content id")) - content = generic.GenericForeignKey(ct_field="content_type", fk_field="content_id") - - def __unicode__(self): - if self.role: - principal = self.role - else: - principal = self.user - - return "%s / %s / %s - %s" % (self.permission.name, principal, self.content_type, self.content_id) - - def get_principal(self): - """Returns the principal. - """ - return self.user or self.group - - def set_principal(self, principal): - """Sets the principal. - """ - if isinstance(principal, User): - self.user = principal - else: - self.group = principal - - principal = property(get_principal, set_principal) - -class ObjectPermissionInheritanceBlock(models.Model): - """Blocks the inheritance for specific permission and object. - - **Attributes:** - - permission - The permission for which inheritance is blocked. - - content - The object for which the inheritance is blocked. - """ - permission = models.ForeignKey(Permission, verbose_name=_(u"Permission")) - - content_type = models.ForeignKey(ContentType, verbose_name=_(u"Content type")) - content_id = models.PositiveIntegerField(verbose_name=_(u"Content id")) - content = generic.GenericForeignKey(ct_field="content_type", fk_field="content_id") - - def __unicode__(self): - return "%s / %s - %s" % (self.permission, self.content_type, self.content_id) - -class Role(models.Model): - """A role gets permissions to do something. Principals (users and groups) - can only get permissions via roles. - - **Attributes:** - - name - The unique name of the role - """ - name = models.CharField(max_length=100, unique=True) - - class Meta: - ordering = ("name", ) - - def __unicode__(self): - return self.name - - def add_principal(self, principal, content=None): - """Addes the given principal (user or group) ot the Role. - """ - if isinstance(principal, User): - PrincipalRoleRelation.objects.create(user=principal, role=self) - else: - PrincipalRoleRelation.objects.create(group=principal, role=self) - - def get_groups(self, content=None): - """Returns all groups which has this role assigned. If content is given - it returns also the local roles. - """ - if content: - ctype = ContentType.objects.get_for_model(content) - prrs = PrincipalRoleRelation.objects.filter(role=self, - content_id__in = (None, content.pk), - content_type__in = (None, ctype)).exclude(group=None) - else: - prrs = PrincipalRoleRelation.objects.filter(role=self, - content_id=None, content_type=None).exclude(group=None) - - return [prr.group for prr in prrs] - - def get_users(self, content=None): - """Returns all users which has this role assigned. If content is given - it returns also the local roles. - """ - if content: - ctype = ContentType.objects.get_for_model(content) - prrs = PrincipalRoleRelation.objects.filter(role=self, - content_id__in = (None, content.pk), - content_type__in = (None, ctype)).exclude(user=None) - else: - prrs = PrincipalRoleRelation.objects.filter(role=self, - content_id=None, content_type=None).exclude(user=None) - - return [prr.user for prr in prrs] - -class PrincipalRoleRelation(models.Model): - """A role given to a principal (user or group). If a content object is - given this is a local role, i.e. the principal has this role only for this - content object. Otherwise it is a global role, i.e. the principal has - this role generally. - - user - A user instance. Either a user xor a group needs to be given. - - group - A group instance. Either a user xor a group needs to be given. - - role - The role which is given to the principal for content. - - content - The content object which gets the local role (optional). - """ - user = models.ForeignKey(User, verbose_name=_(u"User"), blank=True, null=True) - group = models.ForeignKey(Group, verbose_name=_(u"Group"), blank=True, null=True) - role = models.ForeignKey(Role, verbose_name=_(u"Role")) - - content_type = models.ForeignKey(ContentType, verbose_name=_(u"Content type"), blank=True, null=True) - content_id = models.PositiveIntegerField(verbose_name=_(u"Content id"), blank=True, null=True) - content = generic.GenericForeignKey(ct_field="content_type", fk_field="content_id") - - def get_principal(self): - """Returns the principal. - """ - return self.user or self.group - - def set_principal(self, principal): - """Sets the principal. - """ - if isinstance(principal, User): - self.user = principal - else: - self.group = principal - - principal = property(get_principal, set_principal) diff --git a/permissions/templatetags/.gitignore b/permissions/templatetags/.gitignore deleted file mode 100644 index a74b07aee..000000000 --- a/permissions/templatetags/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/*.pyc diff --git a/permissions/templatetags/__init__.py b/permissions/templatetags/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/permissions/templatetags/permissions_tags.py b/permissions/templatetags/permissions_tags.py deleted file mode 100644 index 94116381f..000000000 --- a/permissions/templatetags/permissions_tags.py +++ /dev/null @@ -1,48 +0,0 @@ -# django imports -from django import template -from django.core.exceptions import ImproperlyConfigured -from django.contrib.auth.models import User, AnonymousUser - -import permissions.utils -register = template.Library() - -class PermissionComparisonNode(template.Node): - """Implements a node to provide an if current user has passed permission - for current object. - """ - @classmethod - def handle_token(cls, parser, token): - bits = token.contents.split() - if len(bits) != 2: - raise template.TemplateSyntaxError( - "'%s' tag takes one argument" % bits[0]) - end_tag = 'endifhasperm' - nodelist_true = parser.parse(('else', end_tag)) - token = parser.next_token() - if token.contents == 'else': # there is an 'else' clause in the tag - nodelist_false = parser.parse((end_tag,)) - parser.delete_first_token() - else: - nodelist_false = "" - - return cls(bits[1], nodelist_true, nodelist_false) - - def __init__(self, permission, nodelist_true, nodelist_false): - self.permission = permission - self.nodelist_true = nodelist_true - self.nodelist_false = nodelist_false - - def render(self, context): - obj = context.get("obj") - request = context.get("request") - if permissions.utils.has_permission(self.permission, request.user, obj): - return self.nodelist_true.render(context) - else: - return self.nodelist_false - -@register.tag -def ifhasperm(parser, token): - """This function provides functionality for the 'ifhasperm' template tag. - """ - return PermissionComparisonNode.handle_token(parser, token) - diff --git a/permissions/tests.py b/permissions/tests.py deleted file mode 100644 index 91bbf51bd..000000000 --- a/permissions/tests.py +++ /dev/null @@ -1,783 +0,0 @@ -# django imports -from django.contrib.flatpages.models import FlatPage -from django.contrib.auth.models import Group -from django.contrib.auth.models import User -from django.conf import settings -from django.core.urlresolvers import reverse -from django.test import TestCase -from django.test.client import Client - -# permissions imports -from permissions.models import Permission -from permissions.models import ObjectPermission -from permissions.models import ObjectPermissionInheritanceBlock -from permissions.models import Role - -import permissions.utils - -class BackendTestCase(TestCase): - """ - """ - def setUp(self): - """ - """ - settings.AUTHENTICATION_BACKENDS = ( - 'django.contrib.auth.backends.ModelBackend', - 'permissions.backend.ObjectPermissionsBackend', - ) - - self.role_1 = permissions.utils.register_role("Role 1") - self.user = User.objects.create(username="john") - self.page_1 = FlatPage.objects.create(url="/page-1/", title="Page 1") - self.view = permissions.utils.register_permission("View", "view") - - # Add user to role - self.role_1.add_principal(self.user) - - def test_has_perm(self): - """Tests has perm of the backend. - """ - result = self.user.has_perm(self.view, self.page_1) - self.assertEqual(result, False) - - # assign view permission to role 1 - permissions.utils.grant_permission(self.page_1, self.role_1, self.view) - - result = self.user.has_perm("view", self.page_1) - self.assertEqual(result, True) - -class RoleTestCase(TestCase): - """ - """ - def setUp(self): - """ - """ - self.role_1 = permissions.utils.register_role("Role 1") - self.role_2 = permissions.utils.register_role("Role 2") - - self.user = User.objects.create(username="john") - self.group = Group.objects.create(name="brights") - - self.user.groups.add(self.group) - - self.page_1 = FlatPage.objects.create(url="/page-1/", title="Page 1") - self.page_2 = FlatPage.objects.create(url="/page-1/", title="Page 2") - - def test_getter(self): - """ - """ - result = permissions.utils.get_group(self.group.id) - self.assertEqual(result, self.group) - - result = permissions.utils.get_group(42) - self.assertEqual(result, None) - - result = permissions.utils.get_role(self.role_1.id) - self.assertEqual(result, self.role_1) - - result = permissions.utils.get_role(42) - self.assertEqual(result, None) - - result = permissions.utils.get_user(self.user.id) - self.assertEqual(result, self.user) - - result = permissions.utils.get_user(42) - self.assertEqual(result, None) - - def test_global_roles_user(self): - """ - """ - # Add role 1 - result = permissions.utils.add_role(self.user, self.role_1) - self.assertEqual(result, True) - - # Add role 1 again - result = permissions.utils.add_role(self.user, self.role_1) - self.assertEqual(result, False) - - result = permissions.utils.get_roles(self.user) - self.assertEqual(result, [self.role_1]) - - # Add role 2 - result = permissions.utils.add_role(self.user, self.role_2) - self.assertEqual(result, True) - - result = permissions.utils.get_roles(self.user) - self.assertEqual(result, [self.role_1, self.role_2]) - - # Remove role 1 - result = permissions.utils.remove_role(self.user, self.role_1) - self.assertEqual(result, True) - - # Remove role 1 again - result = permissions.utils.remove_role(self.user, self.role_1) - self.assertEqual(result, False) - - result = permissions.utils.get_roles(self.user) - self.assertEqual(result, [self.role_2]) - - # Remove role 2 - result = permissions.utils.remove_role(self.user, self.role_2) - self.assertEqual(result, True) - - result = permissions.utils.get_roles(self.user) - self.assertEqual(result, []) - - def test_global_roles_group(self): - """ - """ - # Add role 1 - result = permissions.utils.add_role(self.group, self.role_1) - self.assertEqual(result, True) - - # Add role 1 again - result = permissions.utils.add_role(self.group, self.role_1) - self.assertEqual(result, False) - - result = permissions.utils.get_roles(self.group) - self.assertEqual(result, [self.role_1]) - - # Add role 2 - result = permissions.utils.add_role(self.group, self.role_2) - self.assertEqual(result, True) - - result = permissions.utils.get_roles(self.group) - self.assertEqual(result, [self.role_1, self.role_2]) - - # Remove role 1 - result = permissions.utils.remove_role(self.group, self.role_1) - self.assertEqual(result, True) - - # Remove role 1 again - result = permissions.utils.remove_role(self.group, self.role_1) - self.assertEqual(result, False) - - result = permissions.utils.get_roles(self.group) - self.assertEqual(result, [self.role_2]) - - # Remove role 2 - result = permissions.utils.remove_role(self.group, self.role_2) - self.assertEqual(result, True) - - result = permissions.utils.get_roles(self.group) - self.assertEqual(result, []) - - def test_remove_roles_user(self): - """ - """ - # Add role 1 - result = permissions.utils.add_role(self.user, self.role_1) - self.assertEqual(result, True) - - # Add role 2 - result = permissions.utils.add_role(self.user, self.role_2) - self.assertEqual(result, True) - - result = permissions.utils.get_roles(self.user) - self.assertEqual(result, [self.role_1, self.role_2]) - - # Remove roles - result = permissions.utils.remove_roles(self.user) - self.assertEqual(result, True) - - result = permissions.utils.get_roles(self.user) - self.assertEqual(result, []) - - # Remove roles - result = permissions.utils.remove_roles(self.user) - self.assertEqual(result, False) - - def test_remove_roles_group(self): - """ - """ - # Add role 1 - result = permissions.utils.add_role(self.group, self.role_1) - self.assertEqual(result, True) - - # Add role 2 - result = permissions.utils.add_role(self.group, self.role_2) - self.assertEqual(result, True) - - result = permissions.utils.get_roles(self.group) - self.assertEqual(result, [self.role_1, self.role_2]) - - # Remove roles - result = permissions.utils.remove_roles(self.group) - self.assertEqual(result, True) - - result = permissions.utils.get_roles(self.group) - self.assertEqual(result, []) - - # Remove roles - result = permissions.utils.remove_roles(self.group) - self.assertEqual(result, False) - - def test_local_role_user(self): - """ - """ - # Add local role to page 1 - result = permissions.utils.add_local_role(self.page_1, self.user, self.role_1) - self.assertEqual(result, True) - - # Again - result = permissions.utils.add_local_role(self.page_1, self.user, self.role_1) - self.assertEqual(result, False) - - result = permissions.utils.get_local_roles(self.page_1, self.user) - self.assertEqual(result, [self.role_1]) - - # Add local role 2 - result = permissions.utils.add_local_role(self.page_1, self.user, self.role_2) - self.assertEqual(result, True) - - result = permissions.utils.get_local_roles(self.page_1, self.user) - self.assertEqual(result, [self.role_1, self.role_2]) - - # Remove role 1 - result = permissions.utils.remove_local_role(self.page_1, self.user, self.role_1) - self.assertEqual(result, True) - - # Remove role 1 again - result = permissions.utils.remove_local_role(self.page_1, self.user, self.role_1) - self.assertEqual(result, False) - - result = permissions.utils.get_local_roles(self.page_1, self.user) - self.assertEqual(result, [self.role_2]) - - # Remove role 2 - result = permissions.utils.remove_local_role(self.page_1, self.user, self.role_2) - self.assertEqual(result, True) - - result = permissions.utils.get_local_roles(self.page_1, self.user) - self.assertEqual(result, []) - - def test_local_role_group(self): - """ - """ - # Add local role to page 1 - result = permissions.utils.add_local_role(self.page_1, self.group, self.role_1) - self.assertEqual(result, True) - - # Again - result = permissions.utils.add_local_role(self.page_1, self.group, self.role_1) - self.assertEqual(result, False) - - result = permissions.utils.get_local_roles(self.page_1, self.group) - self.assertEqual(result, [self.role_1]) - - # Add local role 2 - result = permissions.utils.add_local_role(self.page_1, self.group, self.role_2) - self.assertEqual(result, True) - - result = permissions.utils.get_local_roles(self.page_1, self.group) - self.assertEqual(result, [self.role_1, self.role_2]) - - # Remove role 1 - result = permissions.utils.remove_local_role(self.page_1, self.group, self.role_1) - self.assertEqual(result, True) - - # Remove role 1 again - result = permissions.utils.remove_local_role(self.page_1, self.group, self.role_1) - self.assertEqual(result, False) - - result = permissions.utils.get_local_roles(self.page_1, self.group) - self.assertEqual(result, [self.role_2]) - - # Remove role 2 - result = permissions.utils.remove_local_role(self.page_1, self.group, self.role_2) - self.assertEqual(result, True) - - result = permissions.utils.get_local_roles(self.page_1, self.group) - self.assertEqual(result, []) - - def test_remove_local_roles_user(self): - """ - """ - # Add local role to page 1 - result = permissions.utils.add_local_role(self.page_1, self.user, self.role_1) - self.assertEqual(result, True) - - # Add local role 2 - result = permissions.utils.add_local_role(self.page_1, self.user, self.role_2) - self.assertEqual(result, True) - - result = permissions.utils.get_local_roles(self.page_1, self.user) - self.assertEqual(result, [self.role_1, self.role_2]) - - # Remove all local roles - result = permissions.utils.remove_local_roles(self.page_1, self.user) - self.assertEqual(result, True) - - result = permissions.utils.get_local_roles(self.page_1, self.user) - self.assertEqual(result, []) - - # Remove all local roles again - result = permissions.utils.remove_local_roles(self.page_1, self.user) - self.assertEqual(result, False) - - def test_get_groups_1(self): - """Tests global roles for groups. - """ - result = self.role_1.get_groups() - self.assertEqual(len(result), 0) - - result = permissions.utils.add_role(self.group, self.role_1) - self.assertEqual(result, True) - - result = self.role_1.get_groups() - self.assertEqual(result[0].name, "brights") - - # Add another group - self.group_2 = Group.objects.create(name="atheists") - result = permissions.utils.add_role(self.group_2, self.role_1) - - result = self.role_1.get_groups() - self.assertEqual(result[0].name, "brights") - self.assertEqual(result[1].name, "atheists") - self.assertEqual(len(result), 2) - - # Add the role to an user - result = permissions.utils.add_role(self.user, self.role_1) - self.assertEqual(result, True) - - # This shouldn't have an effect on the result - result = self.role_1.get_groups() - self.assertEqual(result[0].name, "brights") - self.assertEqual(result[1].name, "atheists") - self.assertEqual(len(result), 2) - - def test_get_groups_2(self): - """Tests local roles for groups. - """ - result = self.role_1.get_groups(self.page_1) - self.assertEqual(len(result), 0) - - result = permissions.utils.add_local_role(self.page_1, self.group, self.role_1) - self.assertEqual(result, True) - - result = self.role_1.get_groups(self.page_1) - self.assertEqual(result[0].name, "brights") - - # Add another local group - self.group_2 = Group.objects.create(name="atheists") - result = permissions.utils.add_local_role(self.page_1, self.group_2, self.role_1) - - result = self.role_1.get_groups(self.page_1) - self.assertEqual(result[0].name, "brights") - self.assertEqual(result[1].name, "atheists") - - # A the global role to group - result = permissions.utils.add_role(self.group, self.role_1) - self.assertEqual(result, True) - - # Nontheless there are just two groups returned (and no duplicate) - result = self.role_1.get_groups(self.page_1) - self.assertEqual(result[0].name, "brights") - self.assertEqual(result[1].name, "atheists") - self.assertEqual(len(result), 2) - - # Andere there should one global role - result = self.role_1.get_groups() - self.assertEqual(result[0].name, "brights") - - # Add the role to an user - result = permissions.utils.add_local_role(self.page_1, self.user, self.role_1) - self.assertEqual(result, True) - - # This shouldn't have an effect on the result - result = self.role_1.get_groups(self.page_1) - self.assertEqual(result[0].name, "brights") - self.assertEqual(result[1].name, "atheists") - self.assertEqual(len(result), 2) - - def test_get_users_1(self): - """Tests global roles for users. - """ - result = self.role_1.get_users() - self.assertEqual(len(result), 0) - - result = permissions.utils.add_role(self.user, self.role_1) - self.assertEqual(result, True) - - result = self.role_1.get_users() - self.assertEqual(result[0].username, "john") - - # Add another role to an user - self.user_2 = User.objects.create(username="jane") - result = permissions.utils.add_role(self.user_2, self.role_1) - - result = self.role_1.get_users() - self.assertEqual(result[0].username, "john") - self.assertEqual(result[1].username, "jane") - self.assertEqual(len(result), 2) - - # Add the role to an user - result = permissions.utils.add_role(self.group, self.role_1) - self.assertEqual(result, True) - - # This shouldn't have an effect on the result - result = self.role_1.get_users() - self.assertEqual(result[0].username, "john") - self.assertEqual(result[1].username, "jane") - self.assertEqual(len(result), 2) - - def test_get_users_2(self): - """Tests local roles for users. - """ - result = self.role_1.get_users(self.page_1) - self.assertEqual(len(result), 0) - - result = permissions.utils.add_local_role(self.page_1, self.user, self.role_1) - self.assertEqual(result, True) - - result = self.role_1.get_users(self.page_1) - self.assertEqual(result[0].username, "john") - - # Add another local role to an user - self.user_2 = User.objects.create(username="jane") - result = permissions.utils.add_local_role(self.page_1, self.user_2, self.role_1) - - result = self.role_1.get_users(self.page_1) - self.assertEqual(result[0].username, "john") - self.assertEqual(result[1].username, "jane") - - # A the global role to user - result = permissions.utils.add_role(self.user, self.role_1) - self.assertEqual(result, True) - - # Nontheless there are just two users returned (and no duplicate) - result = self.role_1.get_users(self.page_1) - self.assertEqual(result[0].username, "john") - self.assertEqual(result[1].username, "jane") - self.assertEqual(len(result), 2) - - # Andere there should one user for the global role - result = self.role_1.get_users() - self.assertEqual(result[0].username, "john") - - # Add the role to an group - result = permissions.utils.add_local_role(self.page_1, self.group, self.role_1) - self.assertEqual(result, True) - - # This shouldn't have an effect on the result - result = self.role_1.get_users(self.page_1) - self.assertEqual(result[0].username, "john") - self.assertEqual(result[1].username, "jane") - self.assertEqual(len(result), 2) - -class PermissionTestCase(TestCase): - """ - """ - def setUp(self): - """ - """ - self.role_1 = permissions.utils.register_role("Role 1") - self.role_2 = permissions.utils.register_role("Role 2") - - self.user = User.objects.create(username="john") - permissions.utils.add_role(self.user, self.role_1) - self.user.save() - - self.page_1 = FlatPage.objects.create(url="/page-1/", title="Page 1") - self.page_2 = FlatPage.objects.create(url="/page-1/", title="Page 2") - - self.permission = permissions.utils.register_permission("View", "view") - - def test_add_permissions(self): - """ - """ - # Add per object - result = permissions.utils.grant_permission(self.page_1, self.role_1, self.permission) - self.assertEqual(result, True) - - # Add per codename - result = permissions.utils.grant_permission(self.page_1, self.role_1, "view") - self.assertEqual(result, True) - - # Add ermission which does not exist - result = permissions.utils.grant_permission(self.page_1, self.role_1, "hurz") - self.assertEqual(result, False) - - def test_remove_permission(self): - """ - """ - # Add - result = permissions.utils.grant_permission(self.page_1, self.role_1, "view") - self.assertEqual(result, True) - - # Remove - result = permissions.utils.remove_permission(self.page_1, self.role_1, "view") - self.assertEqual(result, True) - - # Remove again - result = permissions.utils.remove_permission(self.page_1, self.role_1, "view") - self.assertEqual(result, False) - - def test_has_permission_role(self): - """ - """ - result = permissions.utils.has_permission(self.page_1, self.user, "view") - self.assertEqual(result, False) - - result = permissions.utils.grant_permission(self.page_1, self.role_1, self.permission) - self.assertEqual(result, True) - - result = permissions.utils.has_permission(self.page_1, self.user, "view") - self.assertEqual(result, True) - - result = permissions.utils.remove_permission(self.page_1, self.role_1, "view") - self.assertEqual(result, True) - - result = permissions.utils.has_permission(self.page_1, self.user, "view") - self.assertEqual(result, False) - - def test_has_permission_owner(self): - """ - """ - creator = User.objects.create(username="jane") - - result = permissions.utils.has_permission(self.page_1, creator, "view") - self.assertEqual(result, False) - - owner = permissions.utils.register_role("Owner") - permissions.utils.grant_permission(self.page_1, owner, "view") - - result = permissions.utils.has_permission(self.page_1, creator, "view", [owner]) - self.assertEqual(result, True) - - def test_local_role(self): - """ - """ - result = permissions.utils.has_permission(self.page_1, self.user, "view") - self.assertEqual(result, False) - - permissions.utils.grant_permission(self.page_1, self.role_2, self.permission) - permissions.utils.add_local_role(self.page_1, self.user, self.role_2) - - result = permissions.utils.has_permission(self.page_1, self.user, "view") - self.assertEqual(result, True) - - def test_ineritance(self): - """ - """ - result = permissions.utils.is_inherited(self.page_1, "view") - self.assertEqual(result, True) - - # per permission - permissions.utils.add_inheritance_block(self.page_1, self.permission) - - result = permissions.utils.is_inherited(self.page_1, "view") - self.assertEqual(result, False) - - permissions.utils.remove_inheritance_block(self.page_1, self.permission) - - result = permissions.utils.is_inherited(self.page_1, "view") - self.assertEqual(result, True) - - # per codename - permissions.utils.add_inheritance_block(self.page_1, "view") - - result = permissions.utils.is_inherited(self.page_1, "view") - self.assertEqual(result, False) - - permissions.utils.remove_inheritance_block(self.page_1, "view") - - result = permissions.utils.is_inherited(self.page_1, "view") - self.assertEqual(result, True) - - def test_unicode(self): - """ - """ - # Permission - self.assertEqual(self.permission.__unicode__(), "View (view)") - - # ObjectPermission - permissions.utils.grant_permission(self.page_1, self.role_1, self.permission) - opr = ObjectPermission.objects.get(permission=self.permission, role=self.role_1) - self.assertEqual(opr.__unicode__(), "View / Role 1 / flat page - 1") - - # ObjectPermissionInheritanceBlock - permissions.utils.add_inheritance_block(self.page_1, self.permission) - opb = ObjectPermissionInheritanceBlock.objects.get(permission=self.permission) - - self.assertEqual(opb.__unicode__(), "View (view) / flat page - 1") - - def test_reset(self): - """ - """ - result = permissions.utils.grant_permission(self.page_1, self.role_1, "view") - self.assertEqual(result, True) - - result = permissions.utils.has_permission(self.page_1, self.user, "view") - self.assertEqual(result, True) - - permissions.utils.add_inheritance_block(self.page_1, "view") - - result = permissions.utils.is_inherited(self.page_1, "view") - self.assertEqual(result, False) - - permissions.utils.reset(self.page_1) - - result = permissions.utils.has_permission(self.page_1, self.user, "view") - self.assertEqual(result, False) - - result = permissions.utils.is_inherited(self.page_1, "view") - self.assertEqual(result, True) - - permissions.utils.reset(self.page_1) - -class RegistrationTestCase(TestCase): - """Tests the registration of different components. - """ - def test_group(self): - """Tests registering/unregistering of a group. - """ - # Register a group - result = permissions.utils.register_group("Brights") - self.failUnless(isinstance(result, Group)) - - # It's there - group = Group.objects.get(name="Brights") - self.assertEqual(group.name, "Brights") - - # Trying to register another group with same name - result = permissions.utils.register_group("Brights") - self.assertEqual(result, False) - - group = Group.objects.get(name="Brights") - self.assertEqual(group.name, "Brights") - - # Unregister the group - result = permissions.utils.unregister_group("Brights") - self.assertEqual(result, True) - - # It's not there anymore - self.assertRaises(Group.DoesNotExist, Group.objects.get, name="Brights") - - # Trying to unregister the group again - result = permissions.utils.unregister_group("Brights") - self.assertEqual(result, False) - - def test_role(self): - """Tests registering/unregistering of a role. - """ - # Register a role - result = permissions.utils.register_role("Editor") - self.failUnless(isinstance(result, Role)) - - # It's there - role = Role.objects.get(name="Editor") - self.assertEqual(role.name, "Editor") - - # Trying to register another role with same name - result = permissions.utils.register_role("Editor") - self.assertEqual(result, False) - - role = Role.objects.get(name="Editor") - self.assertEqual(role.name, "Editor") - - # Unregister the role - result = permissions.utils.unregister_role("Editor") - self.assertEqual(result, True) - - # It's not there anymore - self.assertRaises(Role.DoesNotExist, Role.objects.get, name="Editor") - - # Trying to unregister the role again - result = permissions.utils.unregister_role("Editor") - self.assertEqual(result, False) - - def test_permission(self): - """Tests registering/unregistering of a permission. - """ - # Register a permission - result = permissions.utils.register_permission("Change", "change") - self.failUnless(isinstance(result, Permission)) - - # Is it there? - p = Permission.objects.get(codename="change") - self.assertEqual(p.name, "Change") - - # Register a permission with the same codename - result = permissions.utils.register_permission("Change2", "change") - self.assertEqual(result, False) - - # Is it there? - p = Permission.objects.get(codename="change") - self.assertEqual(p.name, "Change") - - # Register a permission with the same name - result = permissions.utils.register_permission("Change", "change2") - self.assertEqual(result, False) - - # Is it there? - p = Permission.objects.get(codename="change") - self.assertEqual(p.name, "Change") - - # Unregister the permission - result = permissions.utils.unregister_permission("change") - self.assertEqual(result, True) - - # Is it not there anymore? - self.assertRaises(Permission.DoesNotExist, Permission.objects.get, codename="change") - - # Unregister the permission again - result = permissions.utils.unregister_permission("change") - self.assertEqual(result, False) - -# django imports -from django.core.handlers.wsgi import WSGIRequest -from django.contrib.auth.models import User -from django.contrib.sessions.backends.file import SessionStore -from django.test.client import Client - -# Taken from "http://www.djangosnippets.org/snippets/963/" -class RequestFactory(Client): - """ - Class that lets you create mock Request objects for use in testing. - - Usage: - - rf = RequestFactory() - get_request = rf.get('/hello/') - post_request = rf.post('/submit/', {'foo': 'bar'}) - - This class re-uses the django.test.client.Client interface, docs here: - http://www.djangoproject.com/documentation/testing/#the-test-client - - Once you have a request object you can pass it to any view function, - just as if that view had been hooked up using a URLconf. - - """ - def request(self, **request): - """ - Similar to parent class, but returns the request object as soon as it - has created it. - """ - environ = { - 'HTTP_COOKIE': self.cookies, - 'PATH_INFO': '/', - 'QUERY_STRING': '', - 'REQUEST_METHOD': 'GET', - 'SCRIPT_NAME': '', - 'SERVER_NAME': 'testserver', - 'SERVER_PORT': 80, - 'SERVER_PROTOCOL': 'HTTP/1.1', - } - environ.update(self.defaults) - environ.update(request) - return WSGIRequest(environ) - -def create_request(): - """ - """ - rf = RequestFactory() - request = rf.get('/') - request.session = SessionStore() - - user = User() - user.is_superuser = True - user.save() - request.user = user - - return request \ No newline at end of file diff --git a/permissions/utils.py b/permissions/utils.py deleted file mode 100644 index 06183e946..000000000 --- a/permissions/utils.py +++ /dev/null @@ -1,665 +0,0 @@ -# django imports -from django.db import IntegrityError -from django.db.models import Q -from django.db import connection -from django.contrib.auth.models import User -from django.contrib.auth.models import Group -from django.contrib.contenttypes.models import ContentType -from django.core.cache import cache -from django.core.exceptions import ObjectDoesNotExist - -# permissions imports -from permissions.exceptions import Unauthorized -from permissions.models import ObjectPermission -from permissions.models import ObjectPermissionInheritanceBlock -from permissions.models import Permission -from permissions.models import PrincipalRoleRelation -from permissions.models import Role - - -# Roles ###################################################################### - -def add_role(principal, role): - """Adds a global role to a principal. - - **Parameters:** - - principal - The principal (user or group) which gets the role added. - - role - The role which is assigned. - """ - if isinstance(principal, User): - try: - ppr = PrincipalRoleRelation.objects.get(user=principal, role=role, content_id=None, content_type=None) - except PrincipalRoleRelation.DoesNotExist: - PrincipalRoleRelation.objects.create(user=principal, role=role) - return True - else: - try: - ppr = PrincipalRoleRelation.objects.get(group=principal, role=role, content_id=None, content_type=None) - except PrincipalRoleRelation.DoesNotExist: - PrincipalRoleRelation.objects.create(group=principal, role=role) - return True - - return False - -def add_local_role(obj, principal, role): - """Adds a local role to a principal. - - **Parameters:** - - obj - The object for which the principal gets the role. - - principal - The principal (user or group) which gets the role. - - role - The role which is assigned. - """ - ctype = ContentType.objects.get_for_model(obj) - if isinstance(principal, User): - try: - ppr = PrincipalRoleRelation.objects.get(user=principal, role=role, content_id=obj.pk, content_type=ctype) - except PrincipalRoleRelation.DoesNotExist: - PrincipalRoleRelation.objects.create(user=principal, role=role, content=obj) - return True - else: - try: - ppr = PrincipalRoleRelation.objects.get(group=principal, role=role, content_id=obj.pk, content_type=ctype) - except PrincipalRoleRelation.DoesNotExist: - PrincipalRoleRelation.objects.create(group=principal, role=role, content=obj) - return True - - return False - -def remove_role(principal, role): - """Removes role from passed principal. - - **Parameters:** - - principal - The principal (user or group) from which the role is removed. - - role - The role which is removed. - """ - try: - if isinstance(principal, User): - ppr = PrincipalRoleRelation.objects.get( - user=principal, role=role, content_id=None, content_type=None) - else: - ppr = PrincipalRoleRelation.objects.get( - group=principal, role=role, content_id=None, content_type=None) - - except PrincipalRoleRelation.DoesNotExist: - return False - else: - ppr.delete() - - return True - -def remove_local_role(obj, principal, role): - """Removes role from passed object and principle. - - **Parameters:** - - obj - The object from which the role is removed. - - principal - The principal (user or group) from which the role is removed. - - role - The role which is removed. - """ - try: - ctype = ContentType.objects.get_for_model(obj) - - if isinstance(principal, User): - ppr = PrincipalRoleRelation.objects.get( - user=principal, role=role, content_id=obj.pk, content_type=ctype) - else: - ppr = PrincipalRoleRelation.objects.get( - group=principal, role=role, content_id=obj.pk, content_type=ctype) - - except PrincipalRoleRelation.DoesNotExist: - return False - else: - ppr.delete() - - return True - -def remove_roles(principal): - """Removes all roles passed principal (user or group). - - **Parameters:** - - principal - The principal (user or group) from which all roles are removed. - """ - if isinstance(principal, User): - ppr = PrincipalRoleRelation.objects.filter( - user=principal, content_id=None, content_type=None) - else: - ppr = PrincipalRoleRelation.objects.filter( - group=principal, content_id=None, content_type=None) - - if ppr: - ppr.delete() - return True - else: - return False - -def remove_local_roles(obj, principal): - """Removes all local roles from passed object and principal (user or - group). - - **Parameters:** - - obj - The object from which the roles are removed. - - principal - The principal (user or group) from which the roles are removed. - """ - ctype = ContentType.objects.get_for_model(obj) - - if isinstance(principal, User): - ppr = PrincipalRoleRelation.objects.filter( - user=principal, content_id=obj.pk, content_type=ctype) - else: - ppr = PrincipalRoleRelation.objects.filter( - group=principal, content_id=obj.pk, content_type=ctype) - - if ppr: - ppr.delete() - return True - else: - return False - -def get_roles(user, obj=None): - """Returns *all* roles of the passed user. - - This takes direct roles and roles via the user's groups into account. - - If an object is passed local roles will also added. Then all local roles - from all ancestors and all user's groups are also taken into account. - - This is the method to use if one want to know whether the passed user - has a role in general (for the passed object). - - **Parameters:** - - user - The user for which the roles are returned. - - obj - The object for which local roles will returned. - - """ - roles = [] - groups = user.groups.all() - groups_ids_str = ", ".join([str(g.id) for g in groups]) - - # Gobal roles for user and the user's groups - cursor = connection.cursor() - cursor.execute("""SELECT role_id - FROM permissions_principalrolerelation - WHERE (user_id=%s OR group_id IN (%s)) - AND content_id is Null""" % (user.id, groups_ids_str)) - - for row in cursor.fetchall(): - roles.append(row[0]) - - # Local roles for user and the user's groups and all ancestors of the - # passed object. - while obj: - ctype = ContentType.objects.get_for_model(obj) - cursor.execute("""SELECT role_id - FROM permissions_principalrolerelation - WHERE (user_id='%s' OR group_id IN (%s)) - AND content_id='%s' - AND content_type_id='%s'""" % (user.id, groups_ids_str, obj.pk, ctype.id)) - - for row in cursor.fetchall(): - roles.append(row[0]) - - try: - obj = obj.get_parent_for_permissions() - except AttributeError: - obj = None - - return roles - -def get_global_roles(principal): - """Returns *direct* global roles of passed principal (user or group). - """ - if isinstance(principal, User): - return [prr.role for prr in PrincipalRoleRelation.objects.filter( - user=principal, content_id=None, content_type=None)] - else: - if isinstance(principal, Group): - principal = (principal,) - return [prr.role for prr in PrincipalRoleRelation.objects.filter( - group__in=principal, content_id=None, content_type=None)] - -def get_local_roles(obj, principal): - """Returns *direct* local roles for passed principal and content object. - """ - ctype = ContentType.objects.get_for_model(obj) - - if isinstance(principal, User): - return [prr.role for prr in PrincipalRoleRelation.objects.filter( - user=principal, content_id=obj.pk, content_type=ctype)] - else: - return [prr.role for prr in PrincipalRoleRelation.objects.filter( - group=principal, content_id=obj.pk, content_type=ctype)] - -# Permissions ################################################################ - -def check_permission(obj, user, codename, roles=None): - """Checks whether passed user has passed permission for passed obj. - - **Parameters:** - - obj - The object for which the permission should be checked. - - codename - The permission's codename which should be checked. - - user - The user for which the permission should be checked. - - roles - If given these roles will be assigned to the user temporarily before - the permissions are checked. - """ - if not has_permission(obj, user, codename): - raise Unauthorized("User '%s' doesn't have permission '%s' for object '%s' (%s)" - % (user, codename, obj.slug, obj.__class__.__name__)) - -def grant_permission(obj, role, permission): - """Grants passed permission to passed role. Returns True if the permission - was able to be added, otherwise False. - - **Parameters:** - - obj - The content object for which the permission should be granted. - - role - The role for which the permission should be granted. - - permission - The permission which should be granted. Either a permission - object or the codename of a permission. - """ - if not isinstance(permission, Permission): - try: - permission = Permission.objects.get(codename = permission) - except Permission.DoesNotExist: - return False - - ct = ContentType.objects.get_for_model(obj) - try: - ObjectPermission.objects.get(role=role, content_type = ct, content_id=obj.pk, permission=permission) - except ObjectPermission.DoesNotExist: - ObjectPermission.objects.create(role=role, content=obj, permission=permission) - - return True - -def remove_permission(obj, role, permission): - """Removes passed permission from passed role and object. Returns True if - the permission has been removed. - - **Parameters:** - - obj - The content object for which a permission should be removed. - - role - The role for which a permission should be removed. - - permission - The permission which should be removed. Either a permission object - or the codename of a permission. - """ - if not isinstance(permission, Permission): - try: - permission = Permission.objects.get(codename = permission) - except Permission.DoesNotExist: - return False - - ct = ContentType.objects.get_for_model(obj) - - try: - op = ObjectPermission.objects.get(role=role, content_type = ct, content_id=obj.pk, permission = permission) - except ObjectPermission.DoesNotExist: - return False - - op.delete() - return True - -def has_permission(obj, user, codename, roles=None): - """Checks whether the passed user has passed permission for passed object. - - **Parameters:** - - obj - The object for which the permission should be checked. - - codename - The permission's codename which should be checked. - - request - The current request. - - roles - If given these roles will be assigned to the user temporarily before - the permissions are checked. - """ - cache_key = "%s-%s-%s" % (obj.content_type, obj.pk, codename) - result = _get_cached_permission(user, cache_key) - if result is not None: - return result - - if roles is None: - roles = [] - - if user.is_superuser: - return True - - if not user.is_anonymous(): - roles.extend(get_roles(user, obj)) - - ct = ContentType.objects.get_for_model(obj) - - result = False - while obj is not None: - p = ObjectPermission.objects.filter( - content_type=ct, content_id=obj.pk, role__in=roles, permission__codename = codename).values("id") - - if len(p) > 0: - result = True - break - - if is_inherited(obj, codename) == False: - result = False - break - - try: - obj = obj.get_parent_for_permissions() - ct = ContentType.objects.get_for_model(obj) - except AttributeError: - result = False - break - - _cache_permission(user, cache_key, result) - return result - -# Inheritance ################################################################ - -def add_inheritance_block(obj, permission): - """Adds an inheritance for the passed permission on the passed obj. - - **Parameters:** - - permission - The permission for which an inheritance block should be added. - Either a permission object or the codename of a permission. - obj - The content object for which an inheritance block should be added. - """ - if not isinstance(permission, Permission): - try: - permission = Permission.objects.get(codename = permission) - except Permission.DoesNotExist: - return False - - ct = ContentType.objects.get_for_model(obj) - try: - ObjectPermissionInheritanceBlock.objects.get(content_type = ct, content_id=obj.pk, permission=permission) - except ObjectPermissionInheritanceBlock.DoesNotExist: - try: - result = ObjectPermissionInheritanceBlock.objects.create(content=obj, permission=permission) - except IntegrityError: - return False - return True - -def remove_inheritance_block(obj, permission): - """Removes a inheritance block for the passed permission from the passed - object. - - **Parameters:** - - obj - The content object for which an inheritance block should be added. - - permission - The permission for which an inheritance block should be removed. - Either a permission object or the codename of a permission. - """ - if not isinstance(permission, Permission): - try: - permission = Permission.objects.get(codename = permission) - except Permission.DoesNotExist: - return False - - ct = ContentType.objects.get_for_model(obj) - try: - opi = ObjectPermissionInheritanceBlock.objects.get(content_type = ct, content_id=obj.pk, permission=permission) - except ObjectPermissionInheritanceBlock.DoesNotExist: - return False - - opi.delete() - return True - -def is_inherited(obj, codename): - """Returns True if the passed permission is inherited for passed object. - - **Parameters:** - - obj - The content object for which the permission should be checked. - - codename - The permission which should be checked. Must be the codename of - the permission. - """ - ct = ContentType.objects.get_for_model(obj) - try: - ObjectPermissionInheritanceBlock.objects.get( - content_type=ct, content_id=obj.pk, permission__codename = codename) - except ObjectDoesNotExist: - return True - else: - return False - -def get_group(id): - """Returns the group with passed id or None. - """ - try: - return Group.objects.get(pk=id) - except Group.DoesNotExist: - return None - -def get_role(id): - """Returns the role with passed id or None. - """ - try: - return Role.objects.get(pk=id) - except Role.DoesNotExist: - return None - -def get_user(id): - """Returns the user with passed id or None. - """ - try: - return User.objects.get(pk=id) - except User.DoesNotExist: - return None - -def has_group(user, group): - """Returns True if passed user has passed group. - """ - if isinstance(group, str): - group = Group.objects.get(name=group) - - return group in user.groups.all() - -def reset(obj): - """Resets all permissions and inheritance blocks of passed object. - """ - ctype = ContentType.objects.get_for_model(obj) - ObjectPermissionInheritanceBlock.objects.filter(content_id=obj.pk, content_type=ctype).delete() - ObjectPermission.objects.filter(content_id=obj.pk, content_type=ctype).delete() - -# Registering ################################################################ - -def register_permission(name, codename, ctypes=[]): - """Registers a permission to the framework. Returns the permission if the - registration was successfully, otherwise False. - - **Parameters:** - - name - The unique name of the permission. This is displayed to the - customer. - codename - The unique codename of the permission. This is used internally to - identify the permission. - content_types - The content type for which the permission is active. This can be - used to display only reasonable permissions for an object. This - must be a Django ContentType - """ - try: - p = Permission.objects.create(name=name, codename=codename) - - ctypes = [ContentType.objects.get_for_model(ctype) for ctype in ctypes] - if ctypes: - p.content_types = ctypes - p.save() - except IntegrityError: - return False - return p - -def unregister_permission(codename): - """Unregisters a permission from the framework - - **Parameters:** - - codename - The unique codename of the permission. - """ - try: - permission = Permission.objects.get(codename=codename) - except Permission.DoesNotExist: - return False - permission.delete() - return True - -def register_role(name): - """Registers a role with passed name to the framework. Returns the new - role if the registration was successfully, otherwise False. - - **Parameters:** - - name - The unique role name. - """ - try: - role = Role.objects.create(name=name) - except IntegrityError: - return False - return role - -def unregister_role(name): - """Unregisters the role with passed name. - - **Parameters:** - - name - The unique role name. - """ - try: - role = Role.objects.get(name=name) - except Role.DoesNotExist: - return False - - role.delete() - return True - -def register_group(name): - """Registers a group with passed name to the framework. Returns the new - group if the registration was successfully, otherwise False. - - Actually this creates just a default Django Group. - - **Parameters:** - - name - The unique group name. - """ - try: - group = Group.objects.create(name=name) - except IntegrityError: - return False - return group - -def unregister_group(name): - """Unregisters the group with passed name. Returns True if the - unregistration was succesfull otherwise False. - - Actually this deletes just a default Django Group. - - **Parameters:** - - name - The unique role name. - """ - try: - group = Group.objects.get(name=name) - except Group.DoesNotExist: - return False - - group.delete() - return True - -def _cache_permission(user, cache_key, data): - """Stores the passed data on the passed user object. - - **Parameters:** - - user - The user on which the data is stored. - - cache_key - The key under which the data is stored. - - data - The data which is stored. - """ - if not getattr(user, "permissions", None): - user.permissions = {} - user.permissions[cache_key] = data - -def _get_cached_permission(user, cache_key): - """Returns the stored data from passed user object for passed cache_key. - - **Parameters:** - - user - The user from which the data is retrieved. - - cache_key - The key under which the data is stored. - - """ - permissions = getattr(user, "permissions", None) - if permissions: - return user.permissions.get(cache_key, None) diff --git a/static/css/base2.css b/static/css/base2.css index 53cec6094..520c1efb1 100644 --- a/static/css/base2.css +++ b/static/css/base2.css @@ -76,6 +76,7 @@ a img { border: 0; } .ietf-navset .selected { font-weight:bold; padding: 0 3px; } .ietf-navset a, .ietf-navset a:visited { color: white; padding:0 3px; } +.ietf-navset .actions { margin-top: 0.5em; font-style: italic; font-size: 90%; } .ietf-ballot .left { background: #edf5ff; width:160px; padding-left: 10px; } .ietf-ballot .right { padding-left: 15px; padding-right:15px; width:610px;padding-top:0px;} @@ -187,7 +188,7 @@ form table .help { .color2 { color: #00ffff; } .bgcolor1 { background-color: #ffb000; } .bgcolor2 { background-color: #00ffff; } -.square { width: 0.8ex; height: 0.8ex; margin: 0; padding: 0; display: inline-block; position: relative; top: 0.8ex; text-align: top;} +.square { width: 0.8ex; height: 0.8ex; margin: 0; padding: 0; display: inline-block; position: relative; top: 0.8ex; } .big { font-size: 109.5%; margin: 0; padding: 0; } .large { font-size: 120%; margin: 0; padding: 0; } .huge { font-size: 144%; margin: 0; padding: 0; } @@ -237,6 +238,8 @@ li.error { margin: 0.5em; background-color: #f44; } font-family: Arial, sans-serif; } +.errorlist a { color: #fff; } + .group-documents .search-results { margin-top: 1.5em; } table.milestones td.due { vertical-align: top; width: 80px; } @@ -374,6 +377,24 @@ span.fieldRequired { background-color: #ffcc66; } +.state-help-icon { + display: inline-block; + margin-left: 0.2em; + padding: 0 0.2em; + font-weight: bold; + font-style: normal; + font-size: 90%; + color: #999; + background-color: #ddd; + text-decoration: none; +} + +.state-help-icon:hover { + color: #eee; + background-color: #bbb; + transition-duration: 0.2s; +} + /* js styles */ .js-info { background-color: #FFDD88; diff --git a/static/css/liaisons.css b/static/css/liaisons.css index c68075d6e..522620357 100644 --- a/static/css/liaisons.css +++ b/static/css/liaisons.css @@ -96,30 +96,17 @@ span.fieldRequired { background-color: #ffdd88; } -th.orderField a { +th.sort a { text-decoration: none; color: white; - display: block; + padding-right: 20px; + background: url(/images/sort-header-clear.png) no-repeat right center; } -th.orderFieldReversed a { - background: #2647A0 url(/images/arrow-down.gif) no-repeat left center; - padding-left: 20px; +th.sorted a { + background: url(/images/sort-header-filled.png) no-repeat right center; } -th.orderFieldActive a { - background: #2647A0 url(/images/arrow-up.gif) no-repeat left center; - padding-left: 20px; -} - -.noActionTaken, -.actionTaken { - border: 1px solid green; - padding: 2px 5px; - background-color: #ccffbb; -} - -.noActionTaken { - border: 1px solid red; - background-color: #ffccbb; -} +.noActionTaken, .actionTaken { padding: 2px 5px; } +.actionTaken { border: 1px solid green; background-color: #ccffbb; } +.noActionTaken { border: 1px solid red; background-color: #ffccbb; } diff --git a/static/css/submit.css b/static/css/submit.css new file mode 100644 index 000000000..052987d8c --- /dev/null +++ b/static/css/submit.css @@ -0,0 +1,32 @@ +.ietf-navset { + background:#214197 url(/images/yui/sprite.png) repeat-x left -1400px; + color:white; + border:1px solid black; + padding:4px; +} +.ietf-navset .selected { font-weight:bold; padding: 0 3px; } +.ietf-navset a, .ietf-navset a:visited { color: white; padding:0 3px; } +.cutoff-warning { border: 1px dashed red; background-color: #ffeeaa; padding: 1em 2em; margin: 1em 0px; } +.problem-reports-footer { font-style: italic; margin-top: 2em; } + +div.metadata-errors { border: 1px solid red; background-color: #ffeebb; padding: 5px 10px; margin: 1em 0px; max-width: 50em; } +div.info-message-error { border: 1px solid red; background-color: #ffeebb; padding: 5px 10px; margin: 1em 0px; color: red; } +div.info-message-warning { border: 1px solid orange; background-color: #ffffaa; padding: 5px 10px; margin: 1em 0px; color: black; } +div.info-message-success { border: 1px solid green; background-color: #eeffbb; padding: 5px 10px; margin: 1em 0px; color: green; } + +table.metadata-table th { white-space: nowrap; font-weight: bold; } +table.metadata-table th, table.metadata-table td { text-align: left; background: #ddddff; padding: 5px 10px; } +table.metadata-table th.author { text-align: right; } +table.metadata-table tr { vertical-align: top; } +table.metadata-table tr.error td, table.metadata-table tr.error th { background-color: #ffaaaa; } +table.metadata-table div.error-msg { color: red; } +table.metadata-table td.author-button-help { max-width: 40em; } +table.metadata-table input.name, table.metadata-table input.email { width: 25em; } + +pre.twopages { margin: 0px; } + +.idnits-popup .content, +.twopages-popup .content { background-color: #fff; width: 55em; height: 30em; overflow: auto; padding: 1em; } +a.idnits-trigger, a.twopages-trigger, a.idnits-trigger:visited, a.twopages-trigger:visited { color: #000; } + +table.history { max-width: 50em; } diff --git a/static/js/draft-submit.js b/static/js/draft-submit.js index fa9917143..0d51b657a 100644 --- a/static/js/draft-submit.js +++ b/static/js/draft-submit.js @@ -1,12 +1,60 @@ -$(function (){ +jQuery(function (){ // fill in submitter info when an author button is clicked - $("input[type=button]").click(function () { - var name = $(this).data("name"); - if (name == null) // backwards compatibility - return; - var email = $(this).data("email"); + jQuery("input[type=button].author").click(function () { + var name = jQuery(this).data("name"); + var email = jQuery(this).data("email"); - $(this).parents("form").find("input[name=name]").val(name || ""); - $(this).parents("form").find("input[name=email]").val(email || ""); + jQuery(this).parents("form").find("input[name=submitter-name]").val(name || ""); + jQuery(this).parents("form").find("input[name=submitter-email]").val(email || ""); + }); + + jQuery("form").submit(function() { + if (this.submittedAlready) + return false; + else { + this.submittedAlready = true; + return true; + } + }); + + jQuery("form#cancel-submission").submit(function () { + return confirm("Cancel this submission?"); + }); + + jQuery(".idnits-trigger").click(function (e) { + e.preventDefault(); + var popup = jQuery(".idnits-popup").clone().show(); + showModalBox(popup); + }); + + jQuery(".twopages-trigger").click(function (e) { + e.preventDefault(); + var popup = jQuery(".twopages-popup").clone().show(); + showModalBox(popup); + }); + + jQuery("form .add-author").click(function (e) { + e.preventDefault(); + + var table = jQuery("table.authors tbody"); + var row = table.find("tr.empty").clone(); + + row.removeClass("empty"); + var prefixInput = row.find('input[name=authors-prefix]'); + + // figure out a prefix + var i = 0, prefix; + do { + ++i; + prefix = prefixInput.val() + i; + } + while (table.find('input[name=authors-prefix][value="' + prefix +'"]').length > 0); + + prefixInput.val(prefix); + row.find('input').not(prefixInput).each(function () { + this.name = prefix + "-" + this.name; + }); + + table.append(row); }); }); diff --git a/static/js/iesg-discusses.js b/static/js/iesg-discusses.js new file mode 100644 index 000000000..f3b98e151 --- /dev/null +++ b/static/js/iesg-discusses.js @@ -0,0 +1,33 @@ +jQuery(function () { + var radioButtons = jQuery('input[name="discusses"]'); + + var url = window.location.hash.replace("#", ""); + if (url == "byme" || url == "forme") + radioButtons.filter("[value=" + url + "]").click(); + + function updateDisplayedRows() { + var rows = jQuery(".discuss-row"); + + var val = radioButtons.filter(":checked").val(); + + if (val == "all") { + rows.show(); + if (window.location.hash) + window.location.hash = ""; + } + else if (val == "forme" || val == "byme") { + console.log(rows.filter("." + val)) + rows.filter("." + val).show(); + rows.not("." + val).hide(); + window.location.hash = val; + } + + // odd/even are swapped because the jQuery filter is 0-indexed + rows.filter(":visible").filter(":even").removeClass("even").addClass("odd"); + rows.filter(":visible").filter(":odd").removeClass("odd").addClass("even"); + } + + radioButtons.click(updateDisplayedRows); + + updateDisplayedRows(); +}); diff --git a/static/js/liaisons.js b/static/js/liaisons.js index 0a6ebbb46..f6fbd4be4 100644 --- a/static/js/liaisons.js +++ b/static/js/liaisons.js @@ -1,448 +1,438 @@ -(function ($) { - $.fn.AttachmentWidget = function() { - return this.each(function () { - var button = $(this); - var fieldset = $(this).parents('.fieldset'); - var config = {}; - var count = 0; +jQuery(function () { + function setupAttachmentWidget() { + var button = jQuery(this); + var fieldset = jQuery(this).parents('.fieldset'); + var config = {}; + var count = 0; - var readConfig = function() { - var disabledLabel = fieldset.find('.attachDisabledLabel'); + var readConfig = function() { + var disabledLabel = fieldset.find('.attachDisabledLabel'); - if (disabledLabel.length) { - config.disabledLabel = disabledLabel.html(); - var required = '' - fieldset.find('.attachRequiredField').each(function(index, field) { - required += '#' + $(field).html() + ','; - }); - var fields = fieldset.find(required); - config.basefields = fields; - } - - config.showOn = $('#' + fieldset.find('.showAttachsOn').html()); - config.showOnDisplay = config.showOn.find('.attachedFiles'); - count = config.showOnDisplay.find('.initialAttach').length; - config.showOnEmpty = config.showOn.find('.showAttachmentsEmpty').html(); - config.enabledLabel = fieldset.find('.attachEnabledLabel').html(); - }; - - var setState = function() { - var enabled = true; - config.fields.each(function() { - if (!$(this).val()) { - enabled = false; - return; - } + if (disabledLabel.length) { + config.disabledLabel = disabledLabel.html(); + var required = ''; + fieldset.find('.attachRequiredField').each(function(index, field) { + required += '#' + jQuery(field).html() + ','; }); - if (enabled) { - button.removeAttr('disabled').removeClass('disabledAddAttachment'); - button.val(config.enabledLabel); - } else { - button.attr('disabled', 'disabled').addClass('disabledAddAttachment'); - button.val(config.disabledLabel); - } - }; - - var cloneFields = function() { - var html = '
      '; - if (count) { - html = config.showOnDisplay.html() + html; - } - config.fields.each(function() { - var field = $(this); - var container= $(this).parents('.field'); - if (container.find(':file').length) { - html += ' (' + field.val() + ')'; - } else { - html += ' ' + field.val(); - } - html += ''; - container.hide(); - }); - html += ' Remove'; - html += '
      '; - config.showOnDisplay.html(html); - count += 1; - initFileInput(); - }; - - var doAttach = function() { - cloneFields(); - setState(); - }; - - var removeAttachment = function() { - var link = $(this); - var attach = $(this).parent('.attachedFileInfo'); - var fields = attach.find('.removeField'); - fields.each(function() { - $('#' + $(this).html()).remove(); - }); - attach.remove(); - if (!config.showOnDisplay.html()) { - config.showOnDisplay.html(config.showOnEmpty); - count = 0; - } - return false; - }; - - var initTriggers = function() { - config.showOnDisplay.find('a.removeAttach').live('click', removeAttachment); - button.click(doAttach); - }; - - var initFileInput = function() { - var fieldids = '' - config.basefields.each(function(i) { - var field = $(this); - var oldcontainer= $(this).parents('.field'); - var newcontainer= oldcontainer.clone(); - var newfield = newcontainer.find('#' + field.attr('id')); - newfield.attr('name', newfield.attr('name') + '_' + count); - newfield.attr('id', newfield.attr('id') + '_' + count); - newcontainer.attr('id', 'container_id_' + newfield.attr('name')); - oldcontainer.after(newcontainer); - oldcontainer.hide(); - newcontainer.show(); - fieldids += '#' + newfield.attr('id') + ',' - }); - config.fields = $(fieldids); - config.fields.change(setState); - config.fields.keyup(setState); - }; - - var initWidget = function() { - readConfig(); - initFileInput(); - initTriggers(); - setState(); - }; - - initWidget(); - }); - }; - - $.fn.LiaisonForm = function() { - return this.each(function () { - var form = $(this); - var organization = form.find('#id_organization'); - var from = form.find('#id_from_field'); - var poc = form.find('#id_to_poc'); - var cc = form.find('#id_cc1'); - var reply = form.find('#id_replyto'); - var purpose = form.find('#id_purpose'); - var other_purpose = form.find('#id_purpose_text'); - var deadline = form.find('#id_deadline_date'); - var submission_date = form.find('#id_submitted_date'); - var other_organization = form.find('#id_other_organization'); - var approval = form.find('#id_approved'); - var cancel = form.find('#id_cancel'); - var cancel_dialog = form.find('#cancel-dialog'); - var config = {}; - var related_trigger = form.find('#id_related_to'); - var related_url = form.find('#id_related_to').parent().find('.listURL').text(); - var related_dialog = form.find('#related-dialog'); - var unrelate_trigger = form.find('#id_no_related_to'); - - var readConfig = function() { - var confcontainer = form.find('.formconfig'); - config.info_update_url = confcontainer.find('.info_update_url').text(); - }; - - var render_mails_into = function(container, person_list, as_html) { - var html=''; - - $.each(person_list, function(index, person) { - if (as_html) { - html += person[0] + ' <'+person[1]+'>
      '; - } else { - html += person[0] + ' <'+person[1]+'>\n'; - } - }); - container.html(html); - }; - - var toggleApproval = function(needed) { - if (!approval.length) { - return; - } - if (needed) { - approval.removeAttr('disabled'); - approval.removeAttr('checked'); - } else { - approval.attr('checked','checked'); - approval.attr('disabled','disabled'); - } - }; - - var checkPostOnly = function(post_only) { - if (post_only) { - $("input[name=send]").hide(); - } else { - $("input[name=send]").show(); - } - }; - - var updateReplyTo = function() { - var select = form.find('select[name=from_fake_user]'); - var option = select.find('option:selected'); - reply.val(option.attr('title')); - updateFrom(); + var fields = fieldset.find(required); + config.basefields = fields; } - var userSelect = function(user_list) { - if (!user_list || !user_list.length) { + config.showOn = jQuery('#' + fieldset.find('.showAttachsOn').html()); + config.showOnDisplay = config.showOn.find('.attachedFiles'); + count = config.showOnDisplay.find('.initialAttach').length; + config.showOnEmpty = config.showOn.find('.showAttachmentsEmpty').html(); + config.enabledLabel = fieldset.find('.attachEnabledLabel').html(); + }; + + var setState = function() { + var enabled = true; + config.fields.each(function() { + if (!jQuery(this).val()) { + enabled = false; return; } - var link = form.find('a.from_mailto'); - var select = form.find('select[name=from_fake_user]'); - var options = ''; - link.hide(); - $.each(user_list, function(index, person) { - options += ''; - }); - select.remove(); - link.after('') - form.find('select[name=from_fake_user]').change(updateReplyTo); - updateReplyTo(); - }; + }); + if (enabled) { + button.removeAttr('disabled').removeClass('disabledAddAttachment'); + button.val(config.enabledLabel); + } else { + button.attr('disabled', 'disabled').addClass('disabledAddAttachment'); + button.val(config.disabledLabel); + } + }; - var updateInfo = function(first_time, sender) { - var entity = organization; - var to_entity = from; - if (!entity.is('select') || !to_entity.is('select')) { - return false; + var cloneFields = function() { + var html = '
      '; + if (count) { + html = config.showOnDisplay.html() + html; + } + config.fields.each(function() { + var field = jQuery(this); + var container= jQuery(this).parents('.field'); + if (container.find(':file').length) { + html += ' (' + field.val() + ')'; + } else { + html += ' ' + field.val(); } - var url = config.info_update_url; - $.ajax({ - url: url, - type: 'GET', - cache: false, - async: true, - dataType: 'json', - data: {to_entity_id: organization.val(), - from_entity_id: to_entity.val()}, - success: function(response){ - if (!response.error) { - if (!first_time || !cc.text()) { - render_mails_into(cc, response.cc, false); - } - render_mails_into(poc, response.poc, true); - toggleApproval(response.needs_approval); - checkPostOnly(response.post_only); - if (sender == 'from') { - userSelect(response.full_list); - } + html += ''; + container.hide(); + }); + html += ' Remove'; + html += '
      '; + config.showOnDisplay.html(html); + count += 1; + initFileInput(); + }; + + var doAttach = function() { + cloneFields(); + setState(); + }; + + var removeAttachment = function() { + var link = jQuery(this); + var attach = jQuery(this).parent('.attachedFileInfo'); + var fields = attach.find('.removeField'); + fields.each(function() { + jQuery('#' + jQuery(this).html()).remove(); + }); + attach.remove(); + if (!config.showOnDisplay.html()) { + config.showOnDisplay.html(config.showOnEmpty); + count = 0; + } + return false; + }; + + var initTriggers = function() { + config.showOnDisplay.find('a.removeAttach').live('click', removeAttachment); + button.click(doAttach); + }; + + var initFileInput = function() { + var fieldids = []; + config.basefields.each(function(i) { + var field = jQuery(this); + var oldcontainer= jQuery(this).parents('.field'); + var newcontainer= oldcontainer.clone(); + var newfield = newcontainer.find('#' + field.attr('id')); + newfield.attr('name', newfield.attr('name') + '_' + count); + newfield.attr('id', newfield.attr('id') + '_' + count); + newcontainer.attr('id', 'container_id_' + newfield.attr('name')); + oldcontainer.after(newcontainer); + oldcontainer.hide(); + newcontainer.show(); + fieldids.push('#' + newfield.attr('id')); + }); + config.fields = jQuery(fieldids.join(",")); + config.fields.change(setState); + config.fields.keyup(setState); + }; + + var initWidget = function() { + readConfig(); + initFileInput(); + initTriggers(); + setState(); + }; + + initWidget(); + } + + jQuery('form.liaisonform').each(function() { + var form = jQuery(this); + var organization = form.find('#id_organization'); + var from = form.find('#id_from_field'); + var poc = form.find('#id_to_poc'); + var cc = form.find('#id_cc1'); + var reply = form.find('#id_replyto'); + var purpose = form.find('#id_purpose'); + var other_purpose = form.find('#id_purpose_text'); + var deadline = form.find('#id_deadline_date'); + var submission_date = form.find('#id_submitted_date'); + var other_organization = form.find('#id_other_organization'); + var approval = form.find('#id_approved'); + var cancel = form.find('#id_cancel'); + var cancel_dialog = form.find('#cancel-dialog'); + var config = {}; + var related_trigger = form.find('#id_related_to'); + var related_url = form.find('#id_related_to').parent().find('.listURL').text(); + var related_dialog = form.find('#related-dialog'); + var unrelate_trigger = form.find('#id_no_related_to'); + + var readConfig = function() { + var confcontainer = form.find('.formconfig'); + config.info_update_url = confcontainer.find('.info_update_url').text(); + }; + + var render_mails_into = function(container, person_list, as_html) { + var html=''; + + jQuery.each(person_list, function(index, person) { + if (as_html) { + html += person[0] + ' <'+person[1]+'>
      '; + } else { + html += person[0] + ' <'+person[1]+'>\n'; + } + }); + container.html(html); + }; + + var toggleApproval = function(needed) { + if (!approval.length) { + return; + } + if (needed) { + approval.removeAttr('disabled'); + approval.removeAttr('checked'); + } else { + approval.attr('checked','checked'); + approval.attr('disabled','disabled'); + } + }; + + var checkPostOnly = function(post_only) { + if (post_only) { + jQuery("input[name=send]").hide(); + } else { + jQuery("input[name=send]").show(); + } + }; + + var updateReplyTo = function() { + var select = form.find('select[name=from_fake_user]'); + var option = select.find('option:selected'); + reply.val(option.attr('title')); + updateFrom(); + }; + + var userSelect = function(user_list) { + if (!user_list || !user_list.length) { + return; + } + var link = form.find('a.from_mailto'); + var select = form.find('select[name=from_fake_user]'); + var options = ''; + link.hide(); + jQuery.each(user_list, function(index, person) { + options += ''; + }); + select.remove(); + link.after(''); + form.find('select[name=from_fake_user]').change(updateReplyTo); + updateReplyTo(); + }; + + var updateInfo = function(first_time, sender) { + var entity = organization; + var to_entity = from; + if (!entity.is('select') || !to_entity.is('select')) { + return false; + } + var url = config.info_update_url; + jQuery.ajax({ + url: url, + type: 'GET', + cache: false, + async: true, + dataType: 'json', + data: {to_entity_id: organization.val(), + from_entity_id: to_entity.val()}, + success: function(response){ + if (!response.error) { + if (!first_time || !cc.text()) { + render_mails_into(cc, response.cc, false); + } + render_mails_into(poc, response.poc, true); + toggleApproval(response.needs_approval); + checkPostOnly(response.post_only); + if (sender == 'from') { + userSelect(response.full_list); } } - }); - return false; - }; - - var updateFrom = function() { - var reply_to = reply.val(); - form.find('a.from_mailto').attr('href', 'mailto:' + reply_to); - }; - - var updatePurpose = function() { - var datecontainer = deadline.parents('.field'); - var othercontainer = other_purpose.parents('.field'); - var selected_id = purpose.val(); - var deadline_required = datecontainer.find('.fieldRequired'); - - if (selected_id == '1' || selected_id == '2' || selected_id == '5') { - datecontainer.show(); - } else { - datecontainer.hide(); - deadline.val(''); } + }); + return false; + }; - if (selected_id == '5') { - othercontainer.show(); - deadline_required.hide(); - } else { - othercontainer.hide(); - other_purpose.val(''); - deadline_required.show(); - } - }; + var updateFrom = function() { + var reply_to = reply.val(); + form.find('a.from_mailto').attr('href', 'mailto:' + reply_to); + }; - var checkOtherSDO = function() { - var entity = organization.val(); - if (entity=='othersdo') { - other_organization.parents('.field').show(); - } else { - other_organization.parents('.field').hide(); - } - }; + var updatePurpose = function() { + var datecontainer = deadline.parents('.field'); + var othercontainer = other_purpose.parents('.field'); + var selected_id = purpose.val(); + var deadline_required = datecontainer.find('.fieldRequired'); - var cancelForm = function() { - cancel_dialog.dialog("open"); - }; + if (selected_id == '1' || selected_id == '2' || selected_id == '5') { + datecontainer.show(); + } else { + datecontainer.hide(); + deadline.val(''); + } - var getRelatedLink = function() { - link = $(this).text();; - pk = $(this).nextAll('.liaisonPK').text(); - widget = related_trigger.parent(); - widget.find('.relatedLiaisonWidgetTitle').text(link); - widget.find('.relatedLiaisonWidgetValue').val(pk); - widget.find('.noRelated').hide(); - unrelate_trigger.show(); - related_dialog.dialog('close'); - return false; - }; + if (selected_id == '5') { + othercontainer.show(); + deadline_required.hide(); + } else { + othercontainer.hide(); + other_purpose.val(''); + deadline_required.show(); + } + }; - var selectNoRelated = function() { - widget = $(this).parent(); - widget.find('.relatedLiaisonWidgetTitle').text(''); - widget.find('.noRelated').show(); - widget.find('.relatedLiaisonWidgetValue').val(''); - $(this).hide(); - return false; - }; + var checkOtherSDO = function() { + var entity = organization.val(); + if (entity=='othersdo') { + other_organization.parents('.field').show(); + } else { + other_organization.parents('.field').hide(); + } + }; - var selectRelated = function() { - trigger = $(this); - widget = $(this).parent(); - url = widget.find('.listURL').text(); - title = widget.find('.relatedLiaisonWidgetTitle'); - related_dialog.html(''); - related_dialog.dialog('open'); - $.ajax({ - url: url, - type: 'GET', - cache: false, - async: true, - dataType: 'html', - success: function(response){ - related_dialog.html(response); - related_dialog.find('th a').click(function() { - widget.find('.listURL').text(related_url + $(this).attr('href')); - trigger.click(); - return false; - }); - related_dialog.find('td a').click(getRelatedLink); - } - }); - return false; - }; + var cancelForm = function() { + cancel_dialog.dialog("open"); + }; - var checkFrom = function(first_time) { - var reduce_options = form.find('.reducedToOptions'); - if (!reduce_options.length) { - updateInfo(first_time, 'from'); - return; - } - var to_select = organization; - var from_entity = from.val(); - if (!reduce_options.find('.full_power_on_' + from_entity).length) { - to_select.find('optgroup').eq(1).hide(); - to_select.find('option').each(function() { - if (!reduce_options.find('.reduced_to_set_' + $(this).val()).length) { - $(this).hide(); - } else { - $(this).show(); - } + var getRelatedLink = function() { + var link = jQuery(this).text();; + var pk = jQuery(this).nextAll('.liaisonPK').text(); + var widget = related_trigger.parent(); + widget.find('.relatedLiaisonWidgetTitle').text(link); + widget.find('.relatedLiaisonWidgetValue').val(pk); + widget.find('.noRelated').hide(); + unrelate_trigger.show(); + related_dialog.dialog('close'); + return false; + }; + + var selectNoRelated = function() { + var widget = jQuery(this).parent(); + widget.find('.relatedLiaisonWidgetTitle').text(''); + widget.find('.noRelated').show(); + widget.find('.relatedLiaisonWidgetValue').val(''); + jQuery(this).hide(); + return false; + }; + + var selectRelated = function() { + var trigger = jQuery(this); + var widget = jQuery(this).parent(); + var url = widget.find('.listURL').text(); + var title = widget.find('.relatedLiaisonWidgetTitle'); + related_dialog.html(''); + related_dialog.dialog('open'); + jQuery.ajax({ + url: url, + type: 'GET', + cache: false, + async: true, + dataType: 'html', + success: function(response){ + related_dialog.html(response); + related_dialog.find('th a').click(function() { + widget.find('.listURL').text(related_url + jQuery(this).attr('href')); + trigger.click(); + return false; }); - if (!to_select.find('option:selected').is(':visible')) { - to_select.find('option:selected').removeAttr('selected'); - } - } else { - to_select.find('optgroup').show(); - to_select.find('option').show(); + related_dialog.find('td a').click(getRelatedLink); } + }); + return false; + }; + + var checkFrom = function(first_time) { + var reduce_options = form.find('.reducedToOptions'); + if (!reduce_options.length) { updateInfo(first_time, 'from'); - }; - - var checkSubmissionDate = function() { - var date_str = submission_date.val(); - if (date_str) { - var sdate = new Date(date_str); - var today = new Date(); - if (Math.abs(today-sdate) > 2592000000) { // 2592000000 = 30 days in milliseconds - return confirm('Submission date ' + date_str + ' differ more than 30 days.\n\nDo you want to continue and post this liaison using that submission date?\n'); + return; + } + var to_select = organization; + var from_entity = from.val(); + if (!reduce_options.find('.full_power_on_' + from_entity).length) { + to_select.find('optgroup').eq(1).hide(); + to_select.find('option').each(function() { + if (!reduce_options.find('.reduced_to_set_' + jQuery(this).val()).length) { + jQuery(this).hide(); + } else { + jQuery(this).show(); } + }); + if (!to_select.find('option:selected').is(':visible')) { + to_select.find('option:selected').removeAttr('selected'); } - }; + } else { + to_select.find('optgroup').show(); + to_select.find('option').show(); + } + updateInfo(first_time, 'from'); + }; - var initTriggers = function() { - organization.change(function() {updateInfo(false, 'to');}); - organization.change(checkOtherSDO); - from.change(function() {checkFrom(false);}); - reply.keyup(updateFrom); - purpose.change(updatePurpose); - cancel.click(cancelForm); - related_trigger.click(selectRelated); - unrelate_trigger.click(selectNoRelated); - form.submit(checkSubmissionDate); - }; + var checkSubmissionDate = function() { + var date_str = submission_date.val(); + if (date_str) { + var sdate = new Date(date_str); + var today = new Date(); + if (Math.abs(today-sdate) > 2592000000) { // 2592000000 = 30 days in milliseconds + return confirm('Submission date ' + date_str + ' differ more than 30 days.\n\nDo you want to continue and post this liaison using that submission date?\n'); + } + } + }; - var updateOnInit = function() { - updateFrom(); - checkFrom(true); - updatePurpose(); - checkOtherSDO(); - }; + var initTriggers = function() { + organization.change(function() {updateInfo(false, 'to');}); + organization.change(checkOtherSDO); + from.change(function() {checkFrom(false);}); + reply.keyup(updateFrom); + purpose.change(updatePurpose); + cancel.click(cancelForm); + related_trigger.click(selectRelated); + unrelate_trigger.click(selectNoRelated); + form.submit(checkSubmissionDate); + }; - var initDatePicker = function() { - deadline.datepicker({ - dateFormat: $.datepicker.ATOM, - changeYear: true - }); - submission_date.datepicker({ - dateFormat: $.datepicker.ATOM, - changeYear: true - }); - }; + var updateOnInit = function() { + updateFrom(); + checkFrom(true); + updatePurpose(); + checkOtherSDO(); + }; - var initAttachments = function() { - form.find('.addAttachmentWidget').AttachmentWidget(); - }; + var initDatePicker = function() { + deadline.datepicker({ + dateFormat: jQuery.datepicker.ATOM, + changeYear: true + }); + submission_date.datepicker({ + dateFormat: jQuery.datepicker.ATOM, + changeYear: true + }); + }; - var initDialogs = function() { - cancel_dialog.dialog({ - resizable: false, - height:200, - modal: true, - autoOpen: false, - buttons: { - Ok: function() { - window.location='..'; - $( this ).dialog( "close" ); - }, - Cancel: function() { - $( this ).dialog( "close" ); - } - } - }); + var initAttachments = function() { + form.find('.addAttachmentWidget').each(setupAttachmentWidget); + }; - related_dialog.dialog({ - height: 400, - width: 800, - draggable: true, - modal: true, - autoOpen: false - }); - }; + var initDialogs = function() { + cancel_dialog.dialog({ + resizable: false, + height:200, + modal: true, + autoOpen: false, + buttons: { + "Ok": function() { + window.location='..'; + jQuery( this ).dialog( "close" ); + }, + "Cancel": function() { + jQuery( this ).dialog( "close" ); + } + } + }); - var initForm = function() { - readConfig(); - initTriggers(); - updateOnInit(); - initDatePicker(); - initAttachments(); - initDialogs(); - }; + related_dialog.dialog({ + height: 400, + width: 800, + draggable: true, + modal: true, + autoOpen: false + }); + }; - initForm(); - }); + var initForm = function() { + readConfig(); + initTriggers(); + updateOnInit(); + initDatePicker(); + initAttachments(); + initDialogs(); + }; - }; - - $(document).ready(function () { - $('form.liaisonform').LiaisonForm(); + initForm(); }); - -})(jQuery); +}); diff --git a/static/secretariat/css/custom.css b/static/secretariat/css/custom.css index 0205d85ff..07be32d83 100644 --- a/static/secretariat/css/custom.css +++ b/static/secretariat/css/custom.css @@ -661,6 +661,10 @@ ul.session-buttons { list-style-type: circle; } +#telechat-sidebar ul.doc-list { + margin-bottom: 0.8em; +} + ul.doc-list li { list-style-type: circle; } @@ -685,6 +689,18 @@ ul.doc-list li { font-size: 110%; } +#telechat-sidebar li.level3 + li.level2 { + margin-top: 1em; +} + +#telechat-sidebar li.level3 + li.level1 { + margin-top: 1.5em; +} + +#telechat-sidebar li div { + font-style: italic; +} + #telechat-positions-table td { text-align: center; } diff --git a/workflows/.gitignore b/workflows/.gitignore deleted file mode 100644 index a74b07aee..000000000 --- a/workflows/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/*.pyc diff --git a/workflows/__init__.py b/workflows/__init__.py deleted file mode 100644 index 271167dbe..000000000 --- a/workflows/__init__.py +++ /dev/null @@ -1,61 +0,0 @@ -# workflows imports -import workflows.utils - -class WorkflowBase(object): - """Mixin class to make objects workflow aware. - """ - def get_workflow(self): - """Returns the current workflow of the object. - """ - return workflows.utils.get_workflow(self) - - def remove_workflow(self): - """Removes the workflow from the object. After this function has been - called the object has no *own* workflow anymore (it might have one via - its content type). - - """ - return workflows.utils.remove_workflow_from_object(self) - - def set_workflow(self, workflow): - """Sets the passed workflow to the object. This will set the local - workflow for the object. - - If the object has already the given workflow nothing happens. - Otherwise the object gets the passed workflow and the state is set to - the workflow's initial state. - - **Parameters:** - - workflow - The workflow which should be set to the object. Can be a Workflow - instance or a string with the workflow name. - obj - The object which gets the passed workflow. - """ - return workflows.utils.set_workflow_for_object(workflow) - - def get_state(self): - """Returns the current workflow state of the object. - """ - return workflows.utils.get_state(self) - - def set_state(self, state): - """Sets the workflow state of the object. - """ - return workflows.utils.set_state(self, state) - - def set_initial_state(self): - """Sets the initial state of the current workflow to the object. - """ - return self.set_state(self.get_workflow().initial_state) - - def get_allowed_transitions(self, user): - """Returns allowed transitions for the current state. - """ - return workflows.utils.get_allowed_transitions(self, user) - - def do_transition(self, transition, user): - """Processes the passed transition (if allowed). - """ - return workflows.utils.do_transition(self, transition, user) \ No newline at end of file diff --git a/workflows/locale/de/LC_MESSAGES/django.mo b/workflows/locale/de/LC_MESSAGES/django.mo deleted file mode 100644 index e4512512f..000000000 Binary files a/workflows/locale/de/LC_MESSAGES/django.mo and /dev/null differ diff --git a/workflows/locale/de/LC_MESSAGES/django.po b/workflows/locale/de/LC_MESSAGES/django.po deleted file mode 100644 index 2b97ddef5..000000000 --- a/workflows/locale/de/LC_MESSAGES/django.po +++ /dev/null @@ -1,60 +0,0 @@ -# German translations for django-workflows -# Copyright (C) 2010 Kai Diefenbach -# This file is distributed under the same license as the PACKAGE package. -# Kai Diefenbach , 2010. -# -msgid "" -msgstr "" -"Project-Id-Version: 1.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2010-04-02 09:16+0200\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: models.py:98 models.py:199 models.py:237 -msgid "Name" -msgstr "Name" - -#: models.py:200 models.py:238 models.py:285 models.py:307 -msgid "Workflow" -msgstr "Arbeitsablauf" - -#: models.py:201 -msgid "Transitions" -msgstr "Übergänge" - -#: models.py:239 -msgid "Destination" -msgstr "Ziel" - -#: models.py:240 -msgid "Condition" -msgstr "Kondition" - -#: models.py:241 models.py:350 models.py:373 -msgid "Permission" -msgstr "Recht" - -#: models.py:258 models.py:282 -msgid "Content type" -msgstr "Inhaltstyp" - -#: models.py:259 models.py:283 -msgid "Content id" -msgstr "Inhalts-ID" - -#: models.py:261 models.py:349 models.py:372 -msgid "State" -msgstr "Status" - -#: models.py:306 -msgid "Content Type" -msgstr "Inhaltstyp" - -#: models.py:374 -msgid "Role" -msgstr "Rolle" diff --git a/workflows/migrations/.gitignore b/workflows/migrations/.gitignore deleted file mode 100644 index a74b07aee..000000000 --- a/workflows/migrations/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/*.pyc diff --git a/workflows/migrations/0001_initial.py b/workflows/migrations/0001_initial.py deleted file mode 100644 index d12f59ff3..000000000 --- a/workflows/migrations/0001_initial.py +++ /dev/null @@ -1,225 +0,0 @@ - -from south.db import db -from django.db import models -from workflows.models import * - -class Migration: - - def forwards(self, orm): - - # Adding model 'Workflow' - db.create_table('workflows_workflow', ( - ('id', orm['workflows.Workflow:id']), - ('name', orm['workflows.Workflow:name']), - ('initial_state', orm['workflows.Workflow:initial_state']), - )) - db.send_create_signal('workflows', ['Workflow']) - - # Adding model 'StatePermissionRelation' - db.create_table('workflows_statepermissionrelation', ( - ('id', orm['workflows.StatePermissionRelation:id']), - ('state', orm['workflows.StatePermissionRelation:state']), - ('permission', orm['workflows.StatePermissionRelation:permission']), - ('role', orm['workflows.StatePermissionRelation:role']), - )) - db.send_create_signal('workflows', ['StatePermissionRelation']) - - # Adding model 'StateInheritanceBlock' - db.create_table('workflows_stateinheritanceblock', ( - ('id', orm['workflows.StateInheritanceBlock:id']), - ('state', orm['workflows.StateInheritanceBlock:state']), - ('permission', orm['workflows.StateInheritanceBlock:permission']), - )) - db.send_create_signal('workflows', ['StateInheritanceBlock']) - - # Adding model 'WorkflowModelRelation' - db.create_table('workflows_workflowmodelrelation', ( - ('id', orm['workflows.WorkflowModelRelation:id']), - ('content_type', orm['workflows.WorkflowModelRelation:content_type']), - ('workflow', orm['workflows.WorkflowModelRelation:workflow']), - )) - db.send_create_signal('workflows', ['WorkflowModelRelation']) - - # Adding model 'WorkflowPermissionRelation' - db.create_table('workflows_workflowpermissionrelation', ( - ('id', orm['workflows.WorkflowPermissionRelation:id']), - ('workflow', orm['workflows.WorkflowPermissionRelation:workflow']), - ('permission', orm['workflows.WorkflowPermissionRelation:permission']), - )) - db.send_create_signal('workflows', ['WorkflowPermissionRelation']) - - # Adding model 'State' - db.create_table('workflows_state', ( - ('id', orm['workflows.State:id']), - ('name', orm['workflows.State:name']), - ('workflow', orm['workflows.State:workflow']), - )) - db.send_create_signal('workflows', ['State']) - - # Adding model 'Transition' - db.create_table('workflows_transition', ( - ('id', orm['workflows.Transition:id']), - ('name', orm['workflows.Transition:name']), - ('workflow', orm['workflows.Transition:workflow']), - ('destination', orm['workflows.Transition:destination']), - ('condition', orm['workflows.Transition:condition']), - ('permission', orm['workflows.Transition:permission']), - )) - db.send_create_signal('workflows', ['Transition']) - - # Adding model 'WorkflowObjectRelation' - db.create_table('workflows_workflowobjectrelation', ( - ('id', orm['workflows.WorkflowObjectRelation:id']), - ('content_type', orm['workflows.WorkflowObjectRelation:content_type']), - ('content_id', orm['workflows.WorkflowObjectRelation:content_id']), - ('workflow', orm['workflows.WorkflowObjectRelation:workflow']), - )) - db.send_create_signal('workflows', ['WorkflowObjectRelation']) - - # Adding model 'StateObjectRelation' - db.create_table('workflows_stateobjectrelation', ( - ('id', orm['workflows.StateObjectRelation:id']), - ('content_type', orm['workflows.StateObjectRelation:content_type']), - ('content_id', orm['workflows.StateObjectRelation:content_id']), - ('state', orm['workflows.StateObjectRelation:state']), - )) - db.send_create_signal('workflows', ['StateObjectRelation']) - - # Adding ManyToManyField 'State.transitions' - db.create_table('workflows_state_transitions', ( - ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), - ('state', models.ForeignKey(orm.State, null=False)), - ('transition', models.ForeignKey(orm.Transition, null=False)) - )) - - # Creating unique_together for [content_type, content_id] on WorkflowObjectRelation. - db.create_unique('workflows_workflowobjectrelation', ['content_type_id', 'content_id']) - - # Creating unique_together for [content_type, content_id, state] on StateObjectRelation. - db.create_unique('workflows_stateobjectrelation', ['content_type_id', 'content_id', 'state_id']) - - # Creating unique_together for [workflow, permission] on WorkflowPermissionRelation. - db.create_unique('workflows_workflowpermissionrelation', ['workflow_id', 'permission_id']) - - - - def backwards(self, orm): - - # Deleting unique_together for [workflow, permission] on WorkflowPermissionRelation. - db.delete_unique('workflows_workflowpermissionrelation', ['workflow_id', 'permission_id']) - - # Deleting unique_together for [content_type, content_id, state] on StateObjectRelation. - db.delete_unique('workflows_stateobjectrelation', ['content_type_id', 'content_id', 'state_id']) - - # Deleting unique_together for [content_type, content_id] on WorkflowObjectRelation. - db.delete_unique('workflows_workflowobjectrelation', ['content_type_id', 'content_id']) - - # Deleting model 'Workflow' - db.delete_table('workflows_workflow') - - # Deleting model 'StatePermissionRelation' - db.delete_table('workflows_statepermissionrelation') - - # Deleting model 'StateInheritanceBlock' - db.delete_table('workflows_stateinheritanceblock') - - # Deleting model 'WorkflowModelRelation' - db.delete_table('workflows_workflowmodelrelation') - - # Deleting model 'WorkflowPermissionRelation' - db.delete_table('workflows_workflowpermissionrelation') - - # Deleting model 'State' - db.delete_table('workflows_state') - - # Deleting model 'Transition' - db.delete_table('workflows_transition') - - # Deleting model 'WorkflowObjectRelation' - db.delete_table('workflows_workflowobjectrelation') - - # Deleting model 'StateObjectRelation' - db.delete_table('workflows_stateobjectrelation') - - # Dropping ManyToManyField 'State.transitions' - db.delete_table('workflows_state_transitions') - - - - models = { - 'contenttypes.contenttype': { - 'Meta': {'unique_together': "(('app_label', 'model'),)", 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - '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'}) - }, - 'permissions.permission': { - 'codename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'content_types': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}) - }, - 'permissions.role': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}) - }, - 'workflows.state': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'transitions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['workflows.Transition']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'states'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.stateinheritanceblock': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']"}), - 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) - }, - 'workflows.stateobjectrelation': { - 'Meta': {'unique_together': "(('content_type', 'content_id', 'state'),)"}, - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'state_object'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) - }, - 'workflows.statepermissionrelation': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']"}), - 'role': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Role']"}), - 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) - }, - 'workflows.transition': { - 'condition': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), - 'destination': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'destination_state'", 'null': 'True', 'to': "orm['workflows.State']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.workflow': { - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'initial_state': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_state'", 'null': 'True', 'to': "orm['workflows.State']"}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['permissions.Permission']", 'symmetrical': 'False'}) - }, - 'workflows.workflowmodelrelation': { - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']", 'unique': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'wmrs'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.workflowobjectrelation': { - 'Meta': {'unique_together': "(('content_type', 'content_id'),)"}, - 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_object'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'wors'", 'to': "orm['workflows.Workflow']"}) - }, - 'workflows.workflowpermissionrelation': { - 'Meta': {'unique_together': "(('workflow', 'permission'),)"}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'permission': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'permissions'", 'to': "orm['permissions.Permission']"}), - 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.Workflow']"}) - } - } - - complete_apps = ['workflows'] diff --git a/workflows/migrations/__init__.py b/workflows/migrations/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/workflows/models.py b/workflows/models.py deleted file mode 100644 index d7b5ac68d..000000000 --- a/workflows/models.py +++ /dev/null @@ -1,357 +0,0 @@ -from django.db import models - -# django imports -from django.contrib.contenttypes import generic -from django.contrib.contenttypes.models import ContentType -from django.utils.translation import ugettext_lazy as _ - -# permissions imports -import permissions.utils -from permissions.models import Permission -from permissions.models import Role - -class Workflow(models.Model): - """A workflow consists of a sequence of connected (through transitions) - states. It can be assigned to a model and / or model instances. If a - model instance has a workflow it takes precendence over the model's - workflow. - - **Attributes:** - - model - The model the workflow belongs to. Can be any - - content - The object the workflow belongs to. - - name - The unique name of the workflow. - - states - The states of the workflow. - - initial_state - The initial state the model / content gets if created. - - """ - name = models.CharField(_(u"Name"), max_length=100, unique=True) - initial_state = models.ForeignKey("State", related_name="workflow_state", blank=True, null=True) - permissions = models.ManyToManyField(Permission, symmetrical=False, through="WorkflowPermissionRelation") - - def __unicode__(self): - return self.name - - def get_initial_state(self): - """Returns the initial state of the workflow. Takes the first one if - no state has been defined. - """ - if self.initial_state: - return self.initial_state - else: - try: - return self.states.all()[0] - except IndexError: - return None - - def get_objects(self): - """Returns all objects which have this workflow assigned. Globally - (via the object's content type) or locally (via the object itself). - """ - import workflows.utils - objs = [] - - # Get all objects whose content type has this workflow - for wmr in WorkflowModelRelation.objects.filter(workflow=self): - ctype = wmr.content_type - # We have also to check whether the global workflow is not - # overwritten. - for obj in ctype.model_class().objects.all(): - if workflows.utils.get_workflow(obj) == self: - objs.append(obj) - - # Get all objects whose local workflow this workflow - for wor in WorkflowObjectRelation.objects.filter(workflow=self): - if wor.content not in objs: - objs.append(wor.content) - - return objs - - def set_to(self, ctype_or_obj): - """Sets the workflow to passed content type or object. See the specific - methods for more information. - - **Parameters:** - - ctype_or_obj - The content type or the object to which the workflow should be set. - Can be either a ContentType instance or any Django model instance. - """ - if isinstance(ctype_or_obj, ContentType): - return self.set_to_model(ctype_or_obj) - else: - return self.set_to_object(ctype_or_obj) - - def set_to_model(self, ctype): - """Sets the workflow to the passed content type. If the content - type has already an assigned workflow the workflow is overwritten. - - **Parameters:** - - ctype - The content type which gets the workflow. Can be any Django model - instance. - """ - try: - wor = WorkflowModelRelation.objects.get(content_type=ctype) - except WorkflowModelRelation.DoesNotExist: - WorkflowModelRelation.objects.create(content_type=ctype, workflow=self) - else: - wor.workflow = self - wor.save() - - def set_to_object(self, obj): - """Sets the workflow to the passed object. - - If the object has already the given workflow nothing happens. Otherwise - the workflow is set to the objectthe state is set to the workflow's - initial state. - - **Parameters:** - - obj - The object which gets the workflow. - """ - import workflows.utils - - ctype = ContentType.objects.get_for_model(obj) - try: - wor = WorkflowObjectRelation.objects.get(content_type=ctype, content_id=obj.pk) - except WorkflowObjectRelation.DoesNotExist: - WorkflowObjectRelation.objects.create(content = obj, workflow=self) - workflows.utils.set_state(obj, self.initial_state) - else: - if wor.workflow != self: - wor.workflow = self - wor.save() - workflows.utils.set_state(self.initial_state) - -class State(models.Model): - """A certain state within workflow. - - **Attributes:** - - name - The unique name of the state within the workflow. - - workflow - The workflow to which the state belongs. - - transitions - The transitions of a workflow state. - - """ - name = models.CharField(_(u"Name"), max_length=100) - workflow = models.ForeignKey(Workflow, verbose_name=_(u"Workflow"), related_name="states") - transitions = models.ManyToManyField("Transition", verbose_name=_(u"Transitions"), blank=True, null=True, related_name="states") - - class Meta: - ordering = ("name", ) - - def __unicode__(self): - return "%s (%s)" % (self.name, self.workflow.name) - - def get_allowed_transitions(self, obj, user): - """Returns all allowed transitions for passed object and user. - """ - transitions = [] - for transition in self.transitions.all(): - permission = transition.permission - if permission is None: - transitions.append(transition) - else: - # First we try to get the objects specific has_permission - # method (in case the object inherits from the PermissionBase - # class). - try: - if obj.has_permission(user, permission.codename): - transitions.append(transition) - except AttributeError: - if permissions.utils.has_permission(obj, user, permission.codename): - transitions.append(transition) - return transitions - -class Transition(models.Model): - """A transition from a source to a destination state. The transition can - be used from several source states. - - **Attributes:** - - name - The unique name of the transition within a workflow. - - workflow - The workflow to which the transition belongs. Must be a Workflow - instance. - - destination - The state after a transition has been processed. Must be a State - instance. - - condition - The condition when the transition is available. Can be any python - expression. - - permission - The necessary permission to process the transition. Must be a - Permission instance. - - """ - name = models.CharField(_(u"Name"), max_length=100) - workflow = models.ForeignKey(Workflow, verbose_name=_(u"Workflow"), related_name="transitions") - destination = models.ForeignKey(State, verbose_name=_(u"Destination"), null=True, blank=True, related_name="destination_state") - condition = models.CharField(_(u"Condition"), blank=True, max_length=100) - permission = models.ForeignKey(Permission, verbose_name=_(u"Permission"), blank=True, null=True) - - def __unicode__(self): - return self.name - -class StateObjectRelation(models.Model): - """Stores the workflow state of an object. - - Provides a way to give any object a workflow state without changing the - object's model. - - **Attributes:** - - content - The object for which the state is stored. This can be any instance of - a Django model. - - state - The state of content. This must be a State instance. - """ - content_type = models.ForeignKey(ContentType, verbose_name=_(u"Content type"), related_name="state_object", blank=True, null=True) - content_id = models.PositiveIntegerField(_(u"Content id"), blank=True, null=True) - content = generic.GenericForeignKey(ct_field="content_type", fk_field="content_id") - state = models.ForeignKey(State, verbose_name = _(u"State")) - - def __unicode__(self): - return "%s %s - %s" % (self.content_type.name, self.content_id, self.state.name) - - class Meta: - unique_together = ("content_type", "content_id", "state") - -class WorkflowObjectRelation(models.Model): - """Stores an workflow of an object. - - Provides a way to give any object a workflow without changing the object's - model. - - **Attributes:** - - content - The object for which the workflow is stored. This can be any instance of - a Django model. - - workflow - The workflow which is assigned to an object. This needs to be a workflow - instance. - """ - content_type = models.ForeignKey(ContentType, verbose_name=_(u"Content type"), related_name="workflow_object", blank=True, null=True) - content_id = models.PositiveIntegerField(_(u"Content id"), blank=True, null=True) - content = generic.GenericForeignKey(ct_field="content_type", fk_field="content_id") - workflow = models.ForeignKey(Workflow, verbose_name=_(u"Workflow"), related_name="wors") - - class Meta: - unique_together = ("content_type", "content_id") - - def __unicode__(self): - return "%s %s - %s" % (self.content_type.name, self.content_id, self.workflow.name) - -class WorkflowModelRelation(models.Model): - """Stores an workflow for a model (ContentType). - - Provides a way to give any object a workflow without changing the model. - - **Attributes:** - - Content Type - The content type for which the workflow is stored. This can be any - instance of a Django model. - - workflow - The workflow which is assigned to an object. This needs to be a - workflow instance. - """ - content_type = models.ForeignKey(ContentType, verbose_name=_(u"Content Type"), unique=True) - workflow = models.ForeignKey(Workflow, verbose_name=_(u"Workflow"), related_name="wmrs") - - def __unicode__(self): - return "%s - %s" % (self.content_type.name, self.workflow.name) - -# Permissions relation ####################################################### - -class WorkflowPermissionRelation(models.Model): - """Stores the permissions for which a workflow is responsible. - - **Attributes:** - - workflow - The workflow which is responsible for the permissions. Needs to be a - Workflow instance. - - permission - The permission for which the workflow is responsible. Needs to be a - Permission instance. - """ - workflow = models.ForeignKey(Workflow) - permission = models.ForeignKey(Permission, related_name="permissions") - - class Meta: - unique_together = ("workflow", "permission") - - def __unicode__(self): - return "%s %s" % (self.workflow.name, self.permission.name) - -class StateInheritanceBlock(models.Model): - """Stores inheritance block for state and permission. - - **Attributes:** - - state - The state for which the inheritance is blocked. Needs to be a State - instance. - - permission - The permission for which the instance is blocked. Needs to be a - Permission instance. - """ - state = models.ForeignKey(State, verbose_name=_(u"State")) - permission = models.ForeignKey(Permission, verbose_name=_(u"Permission")) - - def __unicode__(self): - return "%s %s" % (self.state.name, self.permission.name) - -class StatePermissionRelation(models.Model): - """Stores granted permission for state and role. - - **Attributes:** - - state - The state for which the role has the permission. Needs to be a State - instance. - - permission - The permission for which the workflow is responsible. Needs to be a - Permission instance. - - role - The role for which the state has the permission. Needs to be a lfc - Role instance. - """ - state = models.ForeignKey(State, verbose_name=_(u"State")) - permission = models.ForeignKey(Permission, verbose_name=_(u"Permission")) - role = models.ForeignKey(Role, verbose_name=_(u"Role")) - - def __unicode__(self): - return "%s %s %s" % (self.state.name, self.role.name, self.permission.name) diff --git a/workflows/templates/workflows/transitions.html b/workflows/templates/workflows/transitions.html deleted file mode 100644 index 635cbba02..000000000 --- a/workflows/templates/workflows/transitions.html +++ /dev/null @@ -1,10 +0,0 @@ -{% load i18n %} - - diff --git a/workflows/templatetags/.gitignore b/workflows/templatetags/.gitignore deleted file mode 100644 index a74b07aee..000000000 --- a/workflows/templatetags/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/*.pyc diff --git a/workflows/templatetags/__init__.py b/workflows/templatetags/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/workflows/templatetags/workflows_tags.py b/workflows/templatetags/workflows_tags.py deleted file mode 100644 index e95357a32..000000000 --- a/workflows/templatetags/workflows_tags.py +++ /dev/null @@ -1,18 +0,0 @@ -# django imports -from django import template - -# workflows imports -import workflows.utils - -register = template.Library() - -@register.inclusion_tag('workflows/transitions.html', takes_context=True) -def transitions(context, obj): - """ - """ - request = context.get("request") - - return { - "transitions" : workflows.utils.get_allowed_transitions(obj, request.user), - "state" : workflows.utils.get_state(obj), - } diff --git a/workflows/tests.py b/workflows/tests.py deleted file mode 100644 index 2fda0ad4b..000000000 --- a/workflows/tests.py +++ /dev/null @@ -1,600 +0,0 @@ -# django imports -from django.contrib.contenttypes.models import ContentType -from django.contrib.flatpages.models import FlatPage -from django.test import TestCase -from django.contrib.auth.models import User -from django.contrib.sessions.backends.file import SessionStore -from django.core.handlers.wsgi import WSGIRequest -from django.test.client import Client - -# workflows import -import permissions.utils -import workflows.utils -from workflows.models import State -from workflows.models import StateInheritanceBlock -from workflows.models import StatePermissionRelation -from workflows.models import StateObjectRelation -from workflows.models import Transition -from workflows.models import Workflow -from workflows.models import WorkflowModelRelation -from workflows.models import WorkflowObjectRelation -from workflows.models import WorkflowPermissionRelation - -class WorkflowTestCase(TestCase): - """Tests a simple workflow without permissions. - """ - def setUp(self): - """ - """ - create_workflow(self) - - def test_get_states(self): - """ - """ - states = self.w.states.all() - self.assertEqual(states[0], self.private) - self.assertEqual(states[1], self.public) - - def test_unicode(self): - """ - """ - self.assertEqual(self.w.__unicode__(), u"Standard") - -class PermissionsTestCase(TestCase): - """Tests a simple workflow with permissions. - """ - def setUp(self): - """ - """ - create_workflow(self) - - # Register roles - self.anonymous = permissions.utils.register_role("Anonymous") - self.owner = permissions.utils.register_role("Owner") - - self.user = User.objects.create(username="john") - permissions.utils.add_role(self.user, self.owner) - - # Example content type - self.page_1 = FlatPage.objects.create(url="/page-1/", title="Page 1") - - # Registers permissions - self.view = permissions.utils.register_permission("View", "view") - self.edit = permissions.utils.register_permission("Edit", "edit") - - # Add all permissions which are managed by the workflow - wpr = WorkflowPermissionRelation.objects.create(workflow=self.w, permission=self.view) - wpr = WorkflowPermissionRelation.objects.create(workflow=self.w, permission=self.edit) - - # Add permissions for single states - spr = StatePermissionRelation.objects.create(state=self.public, permission=self.view, role=self.owner) - spr = StatePermissionRelation.objects.create(state=self.private, permission=self.view, role=self.owner) - spr = StatePermissionRelation.objects.create(state=self.private, permission=self.edit, role=self.owner) - - # Add inheritance block for single states - sib = StateInheritanceBlock.objects.create(state=self.private, permission=self.view) - sib = StateInheritanceBlock.objects.create(state=self.private, permission=self.edit) - sib = StateInheritanceBlock.objects.create(state=self.public, permission=self.edit) - - workflows.utils.set_workflow(self.page_1, self.w) - - def test_set_state(self): - """ - """ - # Permissions - result = permissions.utils.has_permission(self.page_1, self.user, "edit") - self.assertEqual(result, True) - - result = permissions.utils.has_permission(self.page_1, self.user, "view") - self.assertEqual(result, True) - - # Inheritance - result = permissions.utils.is_inherited(self.page_1, "view") - self.assertEqual(result, False) - - result = permissions.utils.is_inherited(self.page_1, "edit") - self.assertEqual(result, False) - - # Change state - workflows.utils.set_state(self.page_1, self.public) - - # Permissions - result = permissions.utils.has_permission(self.page_1, self.user, "edit") - self.assertEqual(result, False) - - result = permissions.utils.has_permission(self.page_1, self.user, "view") - self.assertEqual(result, True) - - # Inheritance - result = permissions.utils.is_inherited(self.page_1, "view") - self.assertEqual(result, True) - - result = permissions.utils.is_inherited(self.page_1, "edit") - self.assertEqual(result, False) - - def test_set_initial_state(self): - """ - """ - state = workflows.utils.get_state(self.page_1) - self.assertEqual(state.name, self.private.name) - - workflows.utils.do_transition(self.page_1, self.make_public, self.user) - state = workflows.utils.get_state(self.page_1) - self.assertEqual(state.name, self.public.name) - - workflows.utils.set_initial_state(self.page_1) - state = workflows.utils.get_state(self.page_1) - self.assertEqual(state.name, self.private.name) - - def test_do_transition(self): - """ - """ - state = workflows.utils.get_state(self.page_1) - self.assertEqual(state.name, self.private.name) - - # by transition - workflows.utils.do_transition(self.page_1, self.make_public, self.user) - - state = workflows.utils.get_state(self.page_1) - self.assertEqual(state.name, self.public.name) - - # by name - workflows.utils.do_transition(self.page_1, "Make private", self.user) - - state = workflows.utils.get_state(self.page_1) - self.assertEqual(state.name, self.private.name) - - # name which does not exist - result = workflows.utils.do_transition(self.page_1, "Make pending", self.user) - self.assertEqual(result, False) - - wrong = Transition.objects.create(name="Wrong", workflow=self.w, destination = self.public) - - # name which does not exist - result = workflows.utils.do_transition(self.page_1, wrong, self.user) - self.assertEqual(result, False) - -class UtilsTestCase(TestCase): - """Tests various methods of the utils module. - """ - def setUp(self): - """ - """ - create_workflow(self) - self.user = User.objects.create() - - def test_workflow(self): - """ - """ - workflows.utils.set_workflow(self.user, self.w) - result = workflows.utils.get_workflow(self.user) - self.assertEqual(result, self.w) - - def test_state(self): - """ - """ - result = workflows.utils.get_state(self.user) - self.assertEqual(result, None) - - workflows.utils.set_workflow(self.user, self.w) - result = workflows.utils.get_state(self.user) - self.assertEqual(result, self.w.initial_state) - - def test_set_workflow_1(self): - """Set worklow by object - """ - ctype = ContentType.objects.get_for_model(self.user) - - result = workflows.utils.get_workflow(self.user) - self.assertEqual(result, None) - - wp = Workflow.objects.create(name="Portal") - - # Set for model - workflows.utils.set_workflow_for_model(ctype, wp) - - result = workflows.utils.get_workflow_for_model(ctype) - self.assertEqual(result, wp) - - result = workflows.utils.get_workflow(self.user) - self.assertEqual(result, wp) - - # Set for object - workflows.utils.set_workflow_for_object(self.user, self.w) - result = workflows.utils.get_workflow(self.user) - self.assertEqual(result, self.w) - - # The model still have wp - result = workflows.utils.get_workflow_for_model(ctype) - self.assertEqual(result, wp) - - def test_set_workflow_2(self): - """Set worklow by name - """ - ctype = ContentType.objects.get_for_model(self.user) - - result = workflows.utils.get_workflow(self.user) - self.assertEqual(result, None) - - wp = Workflow.objects.create(name="Portal") - - # Set for model - workflows.utils.set_workflow_for_model(ctype, "Portal") - - result = workflows.utils.get_workflow_for_model(ctype) - self.assertEqual(result, wp) - - result = workflows.utils.get_workflow(self.user) - self.assertEqual(result, wp) - - # Set for object - workflows.utils.set_workflow_for_object(self.user, "Standard") - result = workflows.utils.get_workflow(self.user) - self.assertEqual(result, self.w) - - # The model still have wp - result = workflows.utils.get_workflow_for_model(ctype) - self.assertEqual(result, wp) - - # Workflow which does not exist - result = workflows.utils.set_workflow_for_model(ctype, "Wrong") - self.assertEqual(result, False) - - result = workflows.utils.set_workflow_for_object(self.user, "Wrong") - self.assertEqual(result, False) - - def test_get_objects_for_workflow_1(self): - """Workflow is added to object. - """ - result = workflows.utils.get_objects_for_workflow(self.w) - self.assertEqual(result, []) - - workflows.utils.set_workflow(self.user, self.w) - result = workflows.utils.get_objects_for_workflow(self.w) - self.assertEqual(result, [self.user]) - - def test_get_objects_for_workflow_2(self): - """Workflow is added to content type. - """ - result = workflows.utils.get_objects_for_workflow(self.w) - self.assertEqual(result, []) - - ctype = ContentType.objects.get_for_model(self.user) - workflows.utils.set_workflow(ctype, self.w) - result = workflows.utils.get_objects_for_workflow(self.w) - self.assertEqual(result, [self.user]) - - def test_get_objects_for_workflow_3(self): - """Workflow is added to content type and object. - """ - result = workflows.utils.get_objects_for_workflow(self.w) - self.assertEqual(result, []) - - workflows.utils.set_workflow(self.user, self.w) - result = workflows.utils.get_objects_for_workflow(self.w) - self.assertEqual(result, [self.user]) - - ctype = ContentType.objects.get_for_model(self.user) - workflows.utils.set_workflow(ctype, self.w) - result = workflows.utils.get_objects_for_workflow(self.w) - self.assertEqual(result, [self.user]) - - def test_get_objects_for_workflow_4(self): - """Get workflow by name - """ - result = workflows.utils.get_objects_for_workflow("Standard") - self.assertEqual(result, []) - - workflows.utils.set_workflow(self.user, self.w) - result = workflows.utils.get_objects_for_workflow("Standard") - self.assertEqual(result, [self.user]) - - # Workflow which does not exist - result = workflows.utils.get_objects_for_workflow("Wrong") - self.assertEqual(result, []) - - def test_remove_workflow_from_model(self): - """ - """ - ctype = ContentType.objects.get_for_model(self.user) - - result = workflows.utils.get_workflow(ctype) - self.assertEqual(result, None) - - workflows.utils.set_workflow_for_model(ctype, self.w) - - result = workflows.utils.get_workflow_for_model(ctype) - self.assertEqual(result, self.w) - - result = workflows.utils.get_workflow(self.user) - self.assertEqual(result, self.w) - - workflows.utils.remove_workflow_from_model(ctype) - - result = workflows.utils.get_workflow_for_model(ctype) - self.assertEqual(result, None) - - result = workflows.utils.get_workflow_for_object(self.user) - self.assertEqual(result, None) - - def test_remove_workflow_from_object(self): - """ - """ - result = workflows.utils.get_workflow(self.user) - self.assertEqual(result, None) - - workflows.utils.set_workflow_for_object(self.user, self.w) - - result = workflows.utils.get_workflow(self.user) - self.assertEqual(result, self.w) - - result = workflows.utils.remove_workflow_from_object(self.user) - self.assertEqual(result, None) - - def test_remove_workflow_1(self): - """Removes workflow from model - """ - ctype = ContentType.objects.get_for_model(self.user) - - result = workflows.utils.get_workflow(ctype) - self.assertEqual(result, None) - - workflows.utils.set_workflow_for_model(ctype, self.w) - - result = workflows.utils.get_workflow_for_model(ctype) - self.assertEqual(result, self.w) - - result = workflows.utils.get_workflow(self.user) - self.assertEqual(result, self.w) - - workflows.utils.remove_workflow(ctype) - - result = workflows.utils.get_workflow_for_model(ctype) - self.assertEqual(result, None) - - result = workflows.utils.get_workflow_for_object(self.user) - self.assertEqual(result, None) - - def test_remove_workflow_2(self): - """Removes workflow from object - """ - result = workflows.utils.get_workflow(self.user) - self.assertEqual(result, None) - - workflows.utils.set_workflow_for_object(self.user, self.w) - - result = workflows.utils.get_workflow(self.user) - self.assertEqual(result, self.w) - - result = workflows.utils.remove_workflow(self.user) - self.assertEqual(result, None) - - def test_get_allowed_transitions(self): - """Tests get_allowed_transitions method - """ - page_1 = FlatPage.objects.create(url="/page-1/", title="Page 1") - role_1 = permissions.utils.register_role("Role 1") - permissions.utils.add_role(self.user, role_1) - - view = permissions.utils.register_permission("Publish", "publish") - - transitions = self.private.get_allowed_transitions(page_1, self.user) - self.assertEqual(len(transitions), 1) - - # protect the transition with a permission - self.make_public.permission = view - self.make_public.save() - - # user has no transition - transitions = self.private.get_allowed_transitions(page_1, self.user) - self.assertEqual(len(transitions), 0) - - # grant permission - permissions.utils.grant_permission(page_1, role_1, view) - - # user has transition again - transitions = self.private.get_allowed_transitions(page_1, self.user) - self.assertEqual(len(transitions), 1) - - def test_get_workflow_for_object(self): - """ - """ - result = workflows.utils.get_workflow(self.user) - self.assertEqual(result, None) - - # Set workflow for a user - workflows.utils.set_workflow_for_object(self.user, self.w) - - # Get workflow for the user - result = workflows.utils.get_workflow_for_object(self.user) - self.assertEqual(result, self.w) - - # Set workflow for a FlatPage - page_1 = FlatPage.objects.create(url="/page-1/", title="Page 1") - workflows.utils.set_workflow_for_object(page_1, self.w) - - result = workflows.utils.get_workflow_for_object(self.user) - self.assertEqual(result, self.w) - - result = workflows.utils.get_workflow_for_object(page_1) - self.assertEqual(result, self.w) - -class StateTestCase(TestCase): - """Tests the State model - """ - def setUp(self): - """ - """ - create_workflow(self) - self.user = User.objects.create() - self.role_1 = permissions.utils.register_role("Role 1") - permissions.utils.add_role(self.user, self.role_1) - self.page_1 = FlatPage.objects.create(url="/page-1/", title="Page 1") - - def test_unicode(self): - """ - """ - self.assertEqual(self.private.__unicode__(), u"Private (Standard)") - - def test_transitions(self): - """ - """ - transitions = self.public.transitions.all() - self.assertEqual(len(transitions), 1) - self.assertEqual(transitions[0], self.make_private) - - transitions = self.private.transitions.all() - self.assertEqual(len(transitions), 1) - self.assertEqual(transitions[0], self.make_public) - - def test_get_transitions(self): - """ - """ - transitions = self.private.get_allowed_transitions(self.page_1, self.user) - self.assertEqual(len(transitions), 1) - self.assertEqual(transitions[0], self.make_public) - - transitions = self.public.get_allowed_transitions(self.page_1, self.user) - self.assertEqual(len(transitions), 1) - self.assertEqual(transitions[0], self.make_private) - - def test_get_allowed_transitions(self): - """ - """ - self.view = permissions.utils.register_permission("Publish", "publish") - transitions = self.private.get_allowed_transitions(self.page_1, self.user) - self.assertEqual(len(transitions), 1) - - # protect the transition with a permission - self.make_public.permission = self.view - self.make_public.save() - - # user has no transition - transitions = self.private.get_allowed_transitions(self.page_1, self.user) - self.assertEqual(len(transitions), 0) - - # grant permission - permissions.utils.grant_permission(self.page_1, self.role_1, self.view) - - # user has transition again - transitions = self.private.get_allowed_transitions(self.page_1, self.user) - self.assertEqual(len(transitions), 1) - -class TransitionTestCase(TestCase): - """Tests the Transition model - """ - def setUp(self): - """ - """ - create_workflow(self) - - def test_unicode(self): - """ - """ - self.assertEqual(self.make_private.__unicode__(), u"Make private") - -class RelationsTestCase(TestCase): - """Tests various Relations models. - """ - def setUp(self): - """ - """ - create_workflow(self) - self.page_1 = FlatPage.objects.create(url="/page-1/", title="Page 1") - - def test_unicode(self): - """ - """ - # WorkflowObjectRelation - workflows.utils.set_workflow(self.page_1, self.w) - wor = WorkflowObjectRelation.objects.filter()[0] - self.assertEqual(wor.__unicode__(), "flat page 1 - Standard") - - # StateObjectRelation - workflows.utils.set_state(self.page_1, self.public) - sor = StateObjectRelation.objects.filter()[0] - self.assertEqual(sor.__unicode__(), "flat page 1 - Public") - - # WorkflowModelRelation - ctype = ContentType.objects.get_for_model(self.page_1) - workflows.utils.set_workflow(ctype, self.w) - wmr = WorkflowModelRelation.objects.filter()[0] - self.assertEqual(wmr.__unicode__(), "flat page - Standard") - - # WorkflowPermissionRelation - self.view = permissions.utils.register_permission("View", "view") - wpr = WorkflowPermissionRelation.objects.create(workflow=self.w, permission=self.view) - self.assertEqual(wpr.__unicode__(), "Standard View") - - # StatePermissionRelation - self.owner = permissions.utils.register_role("Owner") - spr = StatePermissionRelation.objects.create(state=self.public, permission=self.view, role=self.owner) - self.assertEqual(spr.__unicode__(), "Public Owner View") - -# Helpers #################################################################### - -def create_workflow(self): - self.w = Workflow.objects.create(name="Standard") - - self.private = State.objects.create(name="Private", workflow= self.w) - self.public = State.objects.create(name="Public", workflow= self.w) - - self.make_public = Transition.objects.create(name="Make public", workflow=self.w, destination = self.public) - self.make_private = Transition.objects.create(name="Make private", workflow=self.w, destination = self.private) - - self.private.transitions.add(self.make_public) - self.public.transitions.add(self.make_private) - - self.w.initial_state = self.private - self.w.save() - -# Taken from "http://www.djangosnippets.org/snippets/963/" -class RequestFactory(Client): - """ - Class that lets you create mock Request objects for use in testing. - - Usage: - - rf = RequestFactory() - get_request = rf.get('/hello/') - post_request = rf.post('/submit/', {'foo': 'bar'}) - - This class re-uses the django.test.client.Client interface, docs here: - http://www.djangoproject.com/documentation/testing/#the-test-client - - Once you have a request object you can pass it to any view function, - just as if that view had been hooked up using a URLconf. - - """ - def request(self, **request): - """ - Similar to parent class, but returns the request object as soon as it - has created it. - """ - environ = { - 'HTTP_COOKIE': self.cookies, - 'PATH_INFO': '/', - 'QUERY_STRING': '', - 'REQUEST_METHOD': 'GET', - 'SCRIPT_NAME': '', - 'SERVER_NAME': 'testserver', - 'SERVER_PORT': 80, - 'SERVER_PROTOCOL': 'HTTP/1.1', - } - environ.update(self.defaults) - environ.update(request) - return WSGIRequest(environ) - -def create_request(): - """ - """ - rf = RequestFactory() - request = rf.get('/') - request.session = SessionStore() - - user = User() - user.is_superuser = True - user.save() - request.user = user - - return request diff --git a/workflows/urls.py b/workflows/urls.py deleted file mode 100644 index 949c2346c..000000000 --- a/workflows/urls.py +++ /dev/null @@ -1,7 +0,0 @@ -from django.conf.urls.defaults import * - -# URL patterns for django-workflows - -urlpatterns = patterns('django-workflows.views', - # Add url patterns here -) diff --git a/workflows/utils.py b/workflows/utils.py deleted file mode 100644 index ef2d32596..000000000 --- a/workflows/utils.py +++ /dev/null @@ -1,351 +0,0 @@ -# django imports -from django.contrib.contenttypes.models import ContentType - -# workflows imports -from permissions.models import ObjectPermission -from permissions.models import ObjectPermissionInheritanceBlock -from workflows.models import StateInheritanceBlock -from workflows.models import StateObjectRelation -from workflows.models import StatePermissionRelation -from workflows.models import Transition -from workflows.models import Workflow -from workflows.models import WorkflowModelRelation -from workflows.models import WorkflowObjectRelation -from workflows.models import WorkflowPermissionRelation - -# permissions imports -import permissions.utils - -def get_objects_for_workflow(workflow): - """Returns all objects which have passed workflow. - - **Parameters:** - - workflow - The workflow for which the objects are returned. Can be a Workflow - instance or a string with the workflow name. - """ - if not isinstance(workflow, Workflow): - try: - workflow = Workflow.objects.get(name=workflow) - except Workflow.DoesNotExist: - return [] - - return workflow.get_objects() - -def remove_workflow(ctype_or_obj): - """Removes the workflow from the passed content type or object. After this - function has been called the content type or object has no workflow - anymore. - - If ctype_or_obj is an object the workflow is removed from the object not - from the belonging content type. - - If ctype_or_obj is an content type the workflow is removed from the - content type not from instances of the content type (if they have an own - workflow) - - ctype_or_obj - The content type or the object to which the passed workflow should be - set. Can be either a ContentType instance or any LFC Django model - instance. - """ - if isinstance(ctype_or_obj, ContentType): - remove_workflow_from_model(ctype_or_obj) - else: - remove_workflow_from_object(ctype_or_obj) - -def remove_workflow_from_model(ctype): - """Removes the workflow from passed content type. After this function has - been called the content type has no workflow anymore (the instances might - have own ones). - - ctype - The content type from which the passed workflow should be removed. - Must be a ContentType instance. - """ - # First delete all states, inheritance blocks and permissions from ctype's - # instances which have passed workflow. - workflow = get_workflow_for_model(ctype) - for obj in get_objects_for_workflow(workflow): - try: - ctype = ContentType.objects.get_for_model(obj) - sor = StateObjectRelation.objects.get(content_id=obj.pk, content_type=ctype) - except StateObjectRelation.DoesNotExist: - pass - else: - sor.delete() - - # Reset all permissions - permissions.utils.reset(obj) - - try: - wmr = WorkflowModelRelation.objects.get(content_type=ctype) - except WorkflowModelRelation.DoesNotExist: - pass - else: - wmr.delete() - -def remove_workflow_from_object(obj): - """Removes the workflow from the passed object. After this function has - been called the object has no *own* workflow anymore (it might have one - via its content type). - - obj - The object from which the passed workflow should be set. Must be a - Django Model instance. - """ - try: - wor = WorkflowObjectRelation.objects.get(content_type=obj) - except WorkflowObjectRelation.DoesNotExist: - pass - else: - wor.delete() - - # Reset all permissions - permissions.utils.reset(obj) - - # Set initial of object's content types workflow (if there is one) - set_initial_state(obj) - -def set_workflow(ctype_or_obj, workflow): - """Sets the workflow for passed content type or object. See the specific - methods for more information. - - **Parameters:** - - workflow - The workflow which should be set to the object or model. - - ctype_or_obj - The content type or the object to which the passed workflow should be - set. Can be either a ContentType instance or any Django model - instance. - """ - return workflow.set_to(ctype_or_obj) - -def set_workflow_for_object(obj, workflow): - """Sets the passed workflow to the passed object. - - If the object has already the given workflow nothing happens. Otherwise - the object gets the passed workflow and the state is set to the workflow's - initial state. - - **Parameters:** - - workflow - The workflow which should be set to the object. Can be a Workflow - instance or a string with the workflow name. - - obj - The object which gets the passed workflow. - """ - if isinstance(workflow, Workflow) == False: - try: - workflow = Workflow.objects.get(name=workflow) - except Workflow.DoesNotExist: - return False - - workflow.set_to_object(obj) - -def set_workflow_for_model(ctype, workflow): - """Sets the passed workflow to the passed content type. If the content - type has already an assigned workflow the workflow is overwritten. - - The objects which had the old workflow must updated explicitely. - - **Parameters:** - - workflow - The workflow which should be set to passend content type. Must be a - Workflow instance. - - ctype - The content type to which the passed workflow should be assigned. Can - be any Django model instance - """ - if isinstance(workflow, Workflow) == False: - try: - workflow = Workflow.objects.get(name=workflow) - except Workflow.DoesNotExist: - return False - - workflow.set_to_model(ctype) - -def get_workflow(obj): - """Returns the workflow for the passed object. It takes it either from - the passed object or - if the object doesn't have a workflow - from the - passed object's ContentType. - - **Parameters:** - - object - The object for which the workflow should be returend. Can be any - Django model instance. - """ - workflow = get_workflow_for_object(obj) - if workflow is not None: - return workflow - - ctype = ContentType.objects.get_for_model(obj) - return get_workflow_for_model(ctype) - -def get_workflow_for_object(obj): - """Returns the workflow for the passed object. - - **Parameters:** - - obj - The object for which the workflow should be returned. Can be any - Django model instance. - """ - try: - ctype = ContentType.objects.get_for_model(obj) - wor = WorkflowObjectRelation.objects.get(content_id=obj.pk, content_type=ctype) - except WorkflowObjectRelation.DoesNotExist: - return None - else: - return wor.workflow - -def get_workflow_for_model(ctype): - """Returns the workflow for the passed model. - - **Parameters:** - - ctype - The content type for which the workflow should be returned. Must be - a Django ContentType instance. - """ - try: - wor = WorkflowModelRelation.objects.get(content_type=ctype) - except WorkflowModelRelation.DoesNotExist: - return None - else: - return wor.workflow - -def get_state(obj): - """Returns the current workflow state for the passed object. - - **Parameters:** - - obj - The object for which the workflow state should be returned. Can be any - Django model instance. - """ - ctype = ContentType.objects.get_for_model(obj) - try: - sor = StateObjectRelation.objects.get(content_type=ctype, content_id=obj.pk) - except StateObjectRelation.DoesNotExist: - return None - else: - return sor.state - -def set_state(obj, state): - """Sets the state for the passed object to the passed state and updates - the permissions for the object. - - **Parameters:** - - obj - The object for which the workflow state should be set. Can be any - Django model instance. - - state - The state which should be set to the passed object. - """ - if not state: - remove_state(obj) - else: - ctype = ContentType.objects.get_for_model(obj) - try: - sor = StateObjectRelation.objects.get(content_type=ctype, content_id=obj.pk) - except StateObjectRelation.DoesNotExist: - sor = StateObjectRelation.objects.create(content=obj, state=state) - else: - sor.state = state - sor.save() - update_permissions(obj) - -def remove_state(obj): - """Removes the current state for the passed object. - - **Parameters:** - - obj - The object for which the workflow state should be set. Can be any - Django model instance. - - """ - ctype = ContentType.objects.get_for_model(obj) - try: - sor = StateObjectRelation.objects.get(content_type=ctype, content_id=obj.pk) - sor.delete() - except StateObjectRelation.DoesNotExist: - pass - update_permissions(obj) - -def set_initial_state(obj): - """Sets the initial state to the passed object. - """ - wf = get_workflow(obj) - if wf is not None: - set_state(obj, wf.get_initial_state()) - -def get_allowed_transitions(obj, user): - """Returns all allowed transitions for passed object and user. Takes the - current state of the object into account. - - **Parameters:** - - obj - The object for which the transitions should be returned. - - user - The user for which the transitions are allowed. - """ - state = get_state(obj) - if state is None: - return [] - - return state.get_allowed_transitions(obj, user) - -def do_transition(obj, transition, user): - """Processes the passed transition to the passed object (if allowed). - """ - if not isinstance(transition, Transition): - try: - transition = Transition.objects.get(name=transition) - except Transition.DoesNotExist: - return False - - transitions = get_allowed_transitions(obj, user) - if transition in transitions: - set_state(obj, transition.destination) - return True - else: - return False - -def update_permissions(obj): - """Updates the permissions of the passed object according to the object's - current workflow state. - """ - workflow = get_workflow(obj) - state = get_state(obj) - - # Remove all permissions for the workflow - ct = ContentType.objects.get_for_model(obj) - ps = [wpr.permission for wpr in WorkflowPermissionRelation.objects.filter(workflow=workflow)] - - ObjectPermission.objects.filter(content_type = ct, content_id=obj.pk, permission__in=ps).delete() - - # Grant permission for the state - for spr in StatePermissionRelation.objects.filter(state=state): - permissions.utils.grant_permission(obj, spr.role, spr.permission) - - # Remove all inheritance blocks from the object - ObjectPermissionInheritanceBlock.objects.filter( - content_type = ct, content_id=obj.pk, permission__in=ps).delete() - - # Add inheritance blocks of this state to the object - for sib in StateInheritanceBlock.objects.filter(state=state): - permissions.utils.add_inheritance_block(obj, sib.permission) diff --git a/workflows/views.py b/workflows/views.py deleted file mode 100644 index e69de29bb..000000000