Port wginfo views
- Legacy-Id: 3160
This commit is contained in:
parent
68d0e4c801
commit
5dcc94e5a4
|
@ -378,9 +378,10 @@ if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
|||
# canonical name
|
||||
for r in results:
|
||||
if r.pk in rfc_aliases:
|
||||
r.canonical_name = rfc_aliases[r.pk]
|
||||
# lambda weirdness works around lambda binding in local for loop scope
|
||||
r.canonical_name = (lambda x: lambda: x)(rfc_aliases[r.pk])
|
||||
else:
|
||||
r.canonical_name = r.name
|
||||
r.canonical_name = (lambda x: lambda: x)(r.name)
|
||||
|
||||
result_map = dict((r.pk, r) for r in results)
|
||||
|
||||
|
@ -419,12 +420,13 @@ if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
|||
|
||||
# sort
|
||||
def sort_key(d):
|
||||
if d.canonical_name.startswith('rfc'):
|
||||
return (2, "%06d" % int(d.canonical_name[3:]))
|
||||
n = d.canonical_name()
|
||||
if n.startswith('rfc'):
|
||||
return (2, "%06d" % int(n[3:]))
|
||||
elif d.state_id == "active":
|
||||
return (1, d.canonical_name)
|
||||
return (1, n)
|
||||
else:
|
||||
return (3, d.canonical_name)
|
||||
return (3, n)
|
||||
|
||||
results.sort(key=sort_key)
|
||||
|
||||
|
|
|
@ -95,7 +95,8 @@ class IETFWGAdmin(admin.ModelAdmin):
|
|||
list_display=('group_acronym', 'group_type', 'status', 'area_acronym', 'start_date', 'concluded_date')
|
||||
search_fields=['group_acronym__acronym', 'group_acronym__name']
|
||||
list_filter=['status', 'group_type']
|
||||
admin.site.register(IETFWG, IETFWGAdmin)
|
||||
if not settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
admin.site.register(IETFWG, IETFWGAdmin)
|
||||
|
||||
class IRTFAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
|
|
|
@ -1096,8 +1096,9 @@ if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
|||
AreaOld = Area
|
||||
AcronymOld = Acronym
|
||||
IESGLoginOld = IESGLogin
|
||||
IETFWGOld = IETFWG
|
||||
from redesign.doc.proxy import InternetDraft, IDInternal, BallotInfo, IDState, IDSubState, Rfc
|
||||
from redesign.group.proxy import Area, Acronym
|
||||
from redesign.group.proxy import Area, Acronym, IETFWG
|
||||
from redesign.person.proxy import IESGLogin
|
||||
|
||||
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
# Copyright The IETF Trust 2007, All Rights Reserved
|
||||
|
||||
from django.conf.urls.defaults import patterns
|
||||
from django.conf import settings
|
||||
from ietf.idtracker.models import IETFWG
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
from redesign.group.proxy import IETFWG
|
||||
http_archive_wg_queryset = IETFWG.objects.filter(list_pages__startswith='http')
|
||||
else:
|
||||
http_archive_wg_queryset = IETFWG.objects.filter(email_archive__startswith='http')
|
||||
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' }),
|
||||
|
|
|
@ -2,14 +2,9 @@
|
|||
IETF Working Group Summary (By Acronym)
|
||||
|
||||
|
||||
The following Area Abreviations are used in this document
|
||||
The following Area Abbreviations are used in this document
|
||||
{% for area in area_list %}
|
||||
{{ area }} - {{ area.area_acronym.name }}{% endfor %}
|
||||
{{ 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 }}
|
||||
{% 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 }}
|
||||
{% endif %}{% endfor %}
|
||||
{% include "wginfo/wg_summary.txt" %}{% endif %}{% endfor %}
|
||||
|
|
|
@ -5,9 +5,4 @@
|
|||
{{ ad.person }} <{{ ad.person.email.1 }}>{% endfor %}
|
||||
{% endif %}{% if wg.start_date %}
|
||||
{{ wg.group_acronym.name|safe }} ({{ wg }})
|
||||
{% 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 }}
|
||||
{% endif %}{% endifequal %}{% endfor %}{% endfor %}
|
||||
{% include "wginfo/wg_summary.txt" %}{% endif %}{% endifequal %}{% endfor %}{% endfor %}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% load ietf_filters %}{{wg.group_acronym.name|safe}} ({{wg}})
|
||||
{% 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
|
||||
|
@ -44,4 +44,4 @@ Internet-Drafts:
|
|||
* {{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 %}
|
||||
{%else%}No Requests for Comments{% endif %}{% endif %}
|
||||
|
|
47
ietf/templates/wginfo/wg-charterREDESIGN.txt
Normal file
47
ietf/templates/wginfo/wg-charterREDESIGN.txt
Normal file
|
@ -0,0 +1,47 @@
|
|||
{% 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.person.email.1}}>
|
||||
{% 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.name|safe }} <{{techadvisor.address}}>
|
||||
{% endfor %}{% endif %}{% if wg.editors %}
|
||||
Editor{{ wg.editors|pluralize }}:
|
||||
{% for editor in wg.editors %} {{ editor.person.name|safe }} <{{editor.person.address}}>
|
||||
{% endfor %}{% endif %}{% if wg.secretaries %}
|
||||
Secretar{{ wg.secretaries|pluralize:"y,ies" }}:
|
||||
{% for secretary in wg.secretaries %} {{ secretary.person.name|safe }} <{{secretary.person.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.done %}Done {% else %}{{ milestone.expected_due_date|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 %}
|
92
ietf/templates/wginfo/wg-dirREDESIGN.html
Normal file
92
ietf/templates/wginfo/wg-dirREDESIGN.html
Normal file
|
@ -0,0 +1,92 @@
|
|||
{% 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 <pasi.eronen@nokia.com>
|
||||
|
||||
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 %}
|
||||
<h1>Active IETF Working Groups</h1>
|
||||
|
||||
<p>See also: <a href="http://www.ietf.org/wg/concluded/">Concluded
|
||||
Working Groups (www.ietf.org)</a>, <a href="http://tools.ietf.org/wg/concluded/">Concluded Working Groups (tools.ietf.org)</a>, <a href="http://www.ietf.org/dyn/wg/charter/history/">Historic Charters</a>.</p>
|
||||
|
||||
{% for area in areas %}
|
||||
<h2 class="ietf-divider" id="{{ area.name|cut:" " }}">{{ area.name }}</h2>
|
||||
|
||||
{% for ad in area.ads %}
|
||||
{% if forloop.first %}
|
||||
<p>Area Director{{ forloop.revcounter|pluralize }}:</p>
|
||||
<p style="margin-left: 2em">
|
||||
{% endif %}
|
||||
<a href="mailto:{{ ad.address }}">{{ ad.person.name }} <{{ ad.address }}></a>{% if not forloop.last %}<br/>{% endif %}
|
||||
{% if forloop.last %}
|
||||
</p>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% for url in area.urls %}
|
||||
{% if forloop.first %}
|
||||
<p>Area Specific Web Page{{ forloop.revcounter|pluralize}}:</p>
|
||||
<p style="margin-left: 2em">
|
||||
{% endif %}
|
||||
<a href="{{url.url}}">{{ url.name }}</a>{% if not forloop.last %}<br/>{% endif %}
|
||||
{% if forloop.last %}
|
||||
</p>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% for wg in area.wgs %}
|
||||
{% if forloop.first %}
|
||||
<p>Active Working Groups:</p>
|
||||
<div style="margin-left:2em;">
|
||||
<table class="ietf-wg-table">
|
||||
{% endif %}
|
||||
<tr><td width="10%;"><a href="/wg/{{ wg.acronym }}/">{{ wg.acronym }}</a></td><td width="50%">{{ wg.name }}</td>
|
||||
<td width="39%">{% for chair in wg.chairs %}<a href="mailto:{{ chair.address }}">{{ chair.person.name }}</a>{% if not forloop.last %}, {% endif %}{% endfor %}</td></tr>
|
||||
{% if forloop.last %}
|
||||
</table>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% empty %}
|
||||
<p>No Active Working Groups</p>
|
||||
{% endfor %}{# wg #}
|
||||
|
||||
{% endfor %}{# area #}
|
||||
{% endblock %}
|
137
ietf/templates/wginfo/wg_charterREDESIGN.html
Normal file
137
ietf/templates/wginfo/wg_charterREDESIGN.html
Normal file
|
@ -0,0 +1,137 @@
|
|||
{% extends "wginfo/wg_base.html" %}
|
||||
{% comment %}
|
||||
Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
All rights reserved. Contact: Pasi Eronen <pasi.eronen@nokia.com>
|
||||
|
||||
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 wg_content %}
|
||||
|
||||
<div class="ietf-box ietf-wg-details">
|
||||
{% if concluded %}
|
||||
<span class="ietf-concluded-warning">Note: The data for concluded WGs
|
||||
is occasionally incorrect.</span>
|
||||
{% endif %}
|
||||
<table>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<b>Personnel</b>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr valign="top">
|
||||
<td style="width:14ex;">Chair{{ wg.chairs|pluralize }}:</td>
|
||||
<td>
|
||||
{% for chair in wg.chairs %}
|
||||
<a href="mailto:{{ chair.address }}">{{ chair.person.name }} <{{ chair.address }}></a><br/>
|
||||
{% endfor %}
|
||||
</td></tr>
|
||||
<tr><td>Area Director:</td>
|
||||
<td>
|
||||
{% if not wg.ad %}?{% else %}
|
||||
<a href="mailto:{{ wg.ad_email }}">{{ wg.ad.name }} <{{ wg.ad_email }}></a>{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% if wg.techadvisors %}
|
||||
<tr>
|
||||
<td>Tech Advisor{{ wg.techadvisors|pluralize }}:</td>
|
||||
<td>
|
||||
{% for techadvisor in wg.techadvisors %}
|
||||
<a href="mailto:{{ techadvisor.address }}">{{ techadvisor.person.name }} <{{ techadvisor.address }}></a><br/>
|
||||
{% endfor %}
|
||||
</td></tr>
|
||||
{% endif %}
|
||||
{% if wg.editors %}
|
||||
<td>Editor{{ wg.editors|pluralize }}:</td>
|
||||
<td>
|
||||
{% for editor in wg.editors %}
|
||||
<a href="mailto:{{ editor.address }}">{{ editor.person.name }} <{{ editor.address }}></a><br/>
|
||||
{% endfor %}
|
||||
</td></tr>
|
||||
{% endif %}
|
||||
{% if wg.secretaries %}
|
||||
<tr><td>Secretar{{ wg.secretaries|pluralize:"y,ies" }}:</td>
|
||||
<td>
|
||||
{% for secretary in wg.secretaries %}
|
||||
<a href="mailto:{{ secretary.address }}">{{ secretary.person.name }} <{{ secretary.address }}></a><br/>
|
||||
{% endfor %}
|
||||
</td></tr>
|
||||
{% endif %}
|
||||
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<br/><b>Mailing List</b>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td>Address:</td><td>{{ wg.email_address|urlize }}</td></tr>
|
||||
<tr><td>To Subscribe:</td><td>{{ wg.email_subscribe|urlize }}</td></tr>
|
||||
<tr><td>Archive:</td><td>{{ wg.clean_email_archive|urlize }}</td></tr>
|
||||
|
||||
{% if not concluded %}
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<br/><b>Jabber Chat</b>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td>Room Address:</td><td><a href="xmpp:{{wg}}@jabber.ietf.org">xmpp:{{wg}}@jabber.ietf.org</a></td></tr>
|
||||
<tr><td>Logs:</td><td><a href="http://jabber.ietf.org/logs/{{wg}}/">http://jabber.ietf.org/logs/{{wg}}/</a></td></tr>
|
||||
{% endif %}
|
||||
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{% if wg.additional_urls %}
|
||||
<p>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 %}
|
||||
<a href="{{ url.url }}">{{ url.description}}</a>{% if not forloop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
<h2>Description of Working Group</h2>
|
||||
<p>{{ wg.charter_text|escape|format_charter|safe }}</p>
|
||||
|
||||
<h2>Goals and Milestones</h2>
|
||||
<table>
|
||||
{% for milestone in wg.milestones %}
|
||||
<tr>
|
||||
<td width="80px">
|
||||
{% if milestone.done %}Done{% else %}{{ milestone.expected_due_date|date:"M Y" }}{% endif %}
|
||||
</td>
|
||||
<td>{{ milestone.desc|escape }}
|
||||
</td></tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endblock wg_content %}
|
5
ietf/templates/wginfo/wg_summary.txt
Normal file
5
ietf/templates/wginfo/wg_summary.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
{% 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 }}
|
|
@ -32,13 +32,37 @@
|
|||
# (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 Area, IETFWG
|
||||
from django.shortcuts import get_object_or_404, render_to_response
|
||||
from django.template import RequestContext, loader
|
||||
from django.http import HttpResponse
|
||||
from django.conf import settings
|
||||
from ietf.idtracker.models import Area, IETFWG
|
||||
from ietf.idrfc.views_search import SearchForm, search_query
|
||||
from ietf.idrfc.idrfc_wrapper import IdRfcWrapper
|
||||
|
||||
def fill_in_charter_info(wg, include_drafts=False):
|
||||
from redesign.person.models import Email
|
||||
from redesign.doc.models import DocAlias, RelatedDocument
|
||||
|
||||
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")
|
||||
wg.milestones = wg.groupmilestone_set.all().order_by('expected_due_date')
|
||||
|
||||
if include_drafts:
|
||||
aliases = DocAlias.objects.filter(document__type="draft", document__group=wg).select_related('document').order_by("name")
|
||||
wg.drafts = []
|
||||
wg.rfcs = []
|
||||
for a in aliases:
|
||||
if a.name.startswith("draft"):
|
||||
wg.drafts.append(a)
|
||||
else:
|
||||
wg.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)
|
||||
|
@ -50,16 +74,39 @@ def wg_summary_area(request):
|
|||
|
||||
def wg_charters(request):
|
||||
wgs = IETFWG.objects.filter(status='1',start_date__isnull=False)
|
||||
return HttpResponse(loader.render_to_string('wginfo/1wg-charters.txt', {'wg_list': wgs}),mimetype='text/plain; charset=UTF-8')
|
||||
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',start_date__isnull=False)
|
||||
return HttpResponse(loader.render_to_string('wginfo/1wg-charters-by-acronym.txt', {'wg_list': wgs}),mimetype='text/plain; charset=UTF-8')
|
||||
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 redesign.group.models import Group, GroupURL
|
||||
from redesign.person.models import Email
|
||||
|
||||
areas = Group.objects.filter(type="area", state="active").order_by("name")
|
||||
for area in areas:
|
||||
area.ads = sorted(Email.objects.filter(role__group=area, role__name="ad").select_related("person"), key=lambda e: e.person.name_parts()[3])
|
||||
area.wgs = 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))
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
wg_dir = wg_dirREDESIGN
|
||||
|
||||
def wg_documents(request, acronym):
|
||||
wg = get_object_or_404(IETFWG, group_acronym__acronym=acronym, group_type=1)
|
||||
concluded = (wg.status_id != 1)
|
||||
|
@ -88,4 +135,13 @@ def wg_documents(request, acronym):
|
|||
def wg_charter(request, acronym):
|
||||
wg = get_object_or_404(IETFWG, group_acronym__acronym=acronym, group_type=1)
|
||||
concluded = (wg.status_id != 1)
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
fill_in_charter_info(wg)
|
||||
return render_to_response('wginfo/wg_charterREDESIGN.html',
|
||||
dict(wg=wg,
|
||||
concluded=concluded,
|
||||
selected='charter'),
|
||||
RequestContext(request))
|
||||
|
||||
return render_to_response('wginfo/wg_charter.html', {'wg': wg, 'concluded':concluded, 'selected':'charter'}, RequestContext(request))
|
||||
|
|
|
@ -42,19 +42,16 @@ class DocumentInfo(models.Model):
|
|||
abstract = True
|
||||
def author_list(self):
|
||||
return ", ".join(email.address for email in self.authors.all())
|
||||
def latest_event(self, *args, **filter_args):
|
||||
"""Get latest event of optional Python type and with filter
|
||||
arguments, e.g. d.latest_event(type="xyz") returns an Event
|
||||
while d.latest_event(WriteupEvent, type="xyz") returns a
|
||||
WriteupEvent event."""
|
||||
model = args[0] if args else Event
|
||||
e = model.objects.filter(doc=self).filter(**filter_args).order_by('-time', '-id')[:1]
|
||||
return e[0] if e else None
|
||||
|
||||
class RelatedDocument(models.Model):
|
||||
source = models.ForeignKey('Document')
|
||||
target = models.ForeignKey('DocAlias')
|
||||
relationship = models.ForeignKey(DocRelationshipName)
|
||||
def action(self):
|
||||
return self.relationship.name
|
||||
def inverse_action():
|
||||
infinitive = self.relationship.name[:-1]
|
||||
return u"%sd by" % infinitive
|
||||
def __unicode__(self):
|
||||
return u"%s %s %s" % (self.source.name, self.relationship.name.lower(), self.target.name)
|
||||
|
||||
|
@ -89,6 +86,21 @@ class Document(DocumentInfo):
|
|||
# FIXME: compensate for tombstones?
|
||||
return u"<%s-%s.txt>" % (self.name, self.rev)
|
||||
|
||||
def latest_event(self, *args, **filter_args):
|
||||
"""Get latest event of optional Python type and with filter
|
||||
arguments, e.g. d.latest_event(type="xyz") returns an Event
|
||||
while d.latest_event(WriteupEvent, type="xyz") returns a
|
||||
WriteupEvent event."""
|
||||
model = args[0] if args else Event
|
||||
e = model.objects.filter(doc=self).filter(**filter_args).order_by('-time', '-id')[:1]
|
||||
return e[0] if e else None
|
||||
|
||||
def canonical_name(self):
|
||||
if self.type_id == "draft" and self.state_id == "rfc":
|
||||
return self.docalias_set.get(name__startswith="rfc").name
|
||||
else:
|
||||
return self.name
|
||||
|
||||
class RelatedDocHistory(models.Model):
|
||||
source = models.ForeignKey('DocHistory')
|
||||
target = models.ForeignKey('DocAlias', related_name="reversely_related_document_history_set")
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from redesign.doc.models import *
|
||||
from redesign.person.models import Email
|
||||
from redesign.proxy_utils import TranslatingManager
|
||||
from redesign.name.proxy import *
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
|
@ -86,8 +87,7 @@ class InternetDraft(Document):
|
|||
#status = models.ForeignKey(IDStatus)
|
||||
@property
|
||||
def status(self):
|
||||
from redesign.name.proxy import IDStatus
|
||||
return IDStatus(self.state) if self.state else None
|
||||
return IDStatus().from_object(self.state) if self.state else None
|
||||
|
||||
@property
|
||||
def status_id(self):
|
||||
|
@ -132,11 +132,8 @@ class InternetDraft(Document):
|
|||
@property
|
||||
def rfc_number(self):
|
||||
# simple optimization for search results
|
||||
if hasattr(self, "canonical_name"):
|
||||
return int(self.canonical_name[3:]) if self.canonical_name.startswith('rfc') else None
|
||||
|
||||
aliases = self.docalias_set.filter(name__startswith="rfc")
|
||||
return int(aliases[0].name[3:]) if aliases else None
|
||||
n = self.canonical_name()
|
||||
return int(n[3:]) if n.startswith("rfc") else None
|
||||
|
||||
#comments = models.TextField(blank=True) # unused
|
||||
|
||||
|
@ -857,100 +854,6 @@ class Position(BallotPositionEvent):
|
|||
class Meta:
|
||||
proxy = True
|
||||
|
||||
class IDState(IesgDocStateName):
|
||||
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="order"))
|
||||
|
||||
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
|
||||
from name.models import get_next_iesg_states
|
||||
return IDState.objects.filter(pk__in=[x.pk for x in get_next_iesg_states(self)])
|
||||
|
||||
@property
|
||||
def next_state(self):
|
||||
# simulate IDNextState
|
||||
return self
|
||||
|
||||
def __str__(self):
|
||||
return self.state
|
||||
|
||||
@staticmethod
|
||||
def choices():
|
||||
return [(state.slug, state.name) for state in IDState.objects.all()]
|
||||
|
||||
class Meta:
|
||||
proxy = True
|
||||
|
||||
|
||||
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(DocInfoTagName):
|
||||
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 DraftLikeDocAlias(DocAlias):
|
||||
# this class is mostly useful for the IPR part
|
||||
|
||||
|
|
|
@ -7,14 +7,17 @@ from redesign.person.models import Email, Person
|
|||
import datetime
|
||||
|
||||
class Group(models.Model):
|
||||
time = models.DateTimeField(default=datetime.datetime.now) # should probably have auto_now=True
|
||||
name = models.CharField(max_length=80)
|
||||
acronym = models.CharField(max_length=16, db_index=True)
|
||||
state = models.ForeignKey(GroupStateName, null=True)
|
||||
type = models.ForeignKey(GroupTypeName, null=True)
|
||||
charter = models.OneToOneField('doc.Document', related_name='chartered_group', blank=True, null=True)
|
||||
parent = models.ForeignKey('Group', blank=True, null=True)
|
||||
ad = models.ForeignKey(Person, blank=True, null=True)
|
||||
list_email = models.CharField(max_length=64, blank=True)
|
||||
list_pages = models.CharField(max_length=255, blank=True)
|
||||
list_subscribe = models.CharField(max_length=255, blank=True)
|
||||
list_archive = models.CharField(max_length=255, blank=True)
|
||||
comments = models.TextField(blank=True)
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
@ -24,6 +27,22 @@ class Group(models.Model):
|
|||
e = GroupEvent.objects.filter(group=self).filter(**filter_args).order_by('-time', '-id')[:1]
|
||||
return e[0] if e else None
|
||||
|
||||
class GroupURL(models.Model):
|
||||
group = models.ForeignKey(Group)
|
||||
name = models.CharField(max_length=255)
|
||||
url = models.URLField(verify_exists=False)
|
||||
|
||||
class GroupMilestone(models.Model):
|
||||
group = models.ForeignKey(Group)
|
||||
desc = models.TextField()
|
||||
expected_due_date = models.DateField()
|
||||
done = models.BooleanField()
|
||||
done_date = models.DateField(null=True, blank=True)
|
||||
time = models.DateTimeField(auto_now=True)
|
||||
def __unicode__(self):
|
||||
return self.desc[:20] + "..."
|
||||
class Meta:
|
||||
ordering = ['expected_due_date']
|
||||
|
||||
GROUP_EVENT_CHOICES = [("proposed", "Proposed group"),
|
||||
("started", "Started group"),
|
||||
|
@ -48,6 +67,7 @@ class GroupEvent(models.Model):
|
|||
# This will record the new state and the date it occurred for any changes
|
||||
# to a group. The group acronym must be unique and is the invariant used
|
||||
# to select group history from this table.
|
||||
# FIXME: this class needs to be updated
|
||||
class GroupHistory(models.Model):
|
||||
group = models.ForeignKey('Group', related_name='group_history')
|
||||
# Event related
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
from redesign.proxy_utils import TranslatingManager
|
||||
|
||||
from models import *
|
||||
|
||||
class Acronym(Group):
|
||||
|
@ -47,8 +49,14 @@ class Area(Group):
|
|||
#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 }[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):
|
||||
|
@ -68,8 +76,22 @@ class Area(Group):
|
|||
class Meta:
|
||||
proxy = True
|
||||
|
||||
def proxied_role_emails(emails):
|
||||
for e in emails:
|
||||
e.person.email = { 1: e }
|
||||
return emails
|
||||
|
||||
class IETFWG(Group):
|
||||
objects = TranslatingManager(dict(group_acronym="id",
|
||||
group_acronym__acronym="acronym",
|
||||
email_archive__startswith="list_archive__startswith",
|
||||
group_type=lambda v: ("type", { 1: "wg" }[int(v)]),
|
||||
status=lambda v: ("state", { 1: "active" }[int(v)]),
|
||||
areagroup__area__status=lambda v: ("parent__state", { 1: "active" }[v]),
|
||||
start_date__isnull=lambda v: None if v else ("groupevent__type", "started")
|
||||
),
|
||||
always_filter=dict(type="wg"))
|
||||
|
||||
ACTIVE=1
|
||||
#group_acronym = models.OneToOneField(Acronym, primary_key=True, editable=False)
|
||||
@property
|
||||
|
@ -79,9 +101,17 @@ class IETFWG(Group):
|
|||
#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 = self.latest_event(type="started")
|
||||
return e.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 }[self.state_id]
|
||||
#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)
|
||||
|
@ -89,66 +119,79 @@ class IETFWG(Group):
|
|||
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_pages
|
||||
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):
|
||||
class AreaGroup: pass
|
||||
if self.parent:
|
||||
areagroup = AreaGroup()
|
||||
areagroup.area = Area().from_object(self.parent)
|
||||
return areagroup
|
||||
else:
|
||||
return None
|
||||
|
||||
def __str__(self):
|
||||
return self.group_acronym.acronym
|
||||
|
||||
def __unicode__(self):
|
||||
return self.group_acronym.acronym
|
||||
|
||||
# everything below here is not fixed yet
|
||||
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)
|
||||
from redesign.doc.proxy import InternetDraft
|
||||
return InternetDraft.objects.filter(group=self, state="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
|
||||
return Area().from_object(self.parent) if self.parent else 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:
|
||||
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 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)
|
||||
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
|
||||
# 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"
|
||||
filename = os.path.join(settings.IETFWG_DESCRIPTIONS_PATH, self.acronym) + ".desc.txt"
|
||||
desc_file = open(filename)
|
||||
desc = desc_file.read()
|
||||
except BaseException:
|
||||
desc = 'Error Loading Work Group Description'
|
||||
desc = 'Error Loading Work Group Description'
|
||||
return desc
|
||||
|
||||
def additional_urls(self):
|
||||
return AreaWGURL.objects.filter(name=self.group_acronym.acronym)
|
||||
return self.groupurl_set.all().order_by("name")
|
||||
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
|
||||
return self.list_archive
|
||||
def wgchair_set(self):
|
||||
# gross hack ...
|
||||
class Dummy: pass
|
||||
d = Dummy()
|
||||
d.all = self.chairs()
|
||||
return d
|
||||
|
||||
class Meta:
|
||||
proxy = True
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import sys, os
|
||||
import sys, os, datetime
|
||||
|
||||
basedir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../.."))
|
||||
sys.path = [ basedir ] + sys.path
|
||||
|
@ -15,9 +15,10 @@ management.setup_environ(settings)
|
|||
from redesign.group.models import *
|
||||
from redesign.name.models import *
|
||||
from redesign.name.utils import name
|
||||
from ietf.idtracker.models import AreaGroup, IETFWG, Area, AreaGroup, Acronym, AreaWGURL, IRTF, ChairsHistory, Role
|
||||
from redesign.importing.utils import old_person_to_person
|
||||
from ietf.idtracker.models import AreaGroup, IETFWG, Area, AreaGroup, Acronym, AreaWGURL, IRTF, ChairsHistory, Role, AreaDirector
|
||||
|
||||
# imports IETFWG, Area, AreaGroup, Acronym, IRTF
|
||||
# imports IETFWG, Area, AreaGroup, Acronym, IRTF, AreaWGURL
|
||||
|
||||
# also creates nomcom groups
|
||||
|
||||
|
@ -67,8 +68,6 @@ system = Person.objects.get(name="(System)")
|
|||
|
||||
|
||||
# NomCom
|
||||
#Group.objects.filter(acronym__startswith="nomcom").exclude(acronym="nomcom").delete()
|
||||
|
||||
for o in ChairsHistory.objects.filter(chair_type=Role.NOMCOM_CHAIR).order_by("start_year"):
|
||||
print "importing ChairsHistory/Nomcom", o.pk, "nomcom%s" % o.start_year
|
||||
group, _ = Group.objects.get_or_create(acronym="nomcom%s" % o.start_year)
|
||||
|
@ -83,6 +82,8 @@ for o in ChairsHistory.objects.filter(chair_type=Role.NOMCOM_CHAIR).order_by("st
|
|||
group.save()
|
||||
|
||||
# we need start/end year so fudge events
|
||||
group.groupevent_set.all().delete()
|
||||
|
||||
e = GroupEvent(group=group, type="started")
|
||||
e.time = datetime.datetime(o.start_year, 5, 1, 12, 0, 0)
|
||||
e.by = system
|
||||
|
@ -104,7 +105,9 @@ for o in Area.objects.all():
|
|||
except Group.DoesNotExist:
|
||||
group = Group(acronym=o.area_acronym.acronym)
|
||||
group.id = o.area_acronym_id # transfer id
|
||||
|
||||
|
||||
if o.last_modified_date:
|
||||
group.time = datetime.datetime.combine(o.last_modified_date, datetime.time(12, 0, 0))
|
||||
group.name = o.area_acronym.name
|
||||
if o.status.status == "Active":
|
||||
s = state_names["active"]
|
||||
|
@ -119,6 +122,11 @@ for o in Area.objects.all():
|
|||
|
||||
group.save()
|
||||
|
||||
for u in o.additional_urls():
|
||||
url, _ = GroupURL.objects.get_or_create(group=group, url=u.url)
|
||||
url.name = u.description.strip()
|
||||
url.save()
|
||||
|
||||
# import events
|
||||
group.groupevent_set.all().delete()
|
||||
|
||||
|
@ -129,7 +137,7 @@ for o in Area.objects.all():
|
|||
e.desc = e.get_type_display()
|
||||
e.save()
|
||||
|
||||
# FIXME: missing fields from old: last_modified_date, extra_email_addresses
|
||||
# FIXME: missing fields from old: extra_email_addresses
|
||||
|
||||
|
||||
# IRTF
|
||||
|
@ -162,6 +170,8 @@ for o in IETFWG.objects.all().order_by("pk"):
|
|||
group = Group(acronym=o.group_acronym.acronym)
|
||||
group.id = o.group_acronym_id # transfer id
|
||||
|
||||
if o.last_modified_date:
|
||||
group.time = datetime.datetime.combine(o.last_modified_date, datetime.time(12, 0, 0))
|
||||
group.name = o.group_acronym.name
|
||||
# state
|
||||
if o.group_type.type == "BOF":
|
||||
|
@ -208,30 +218,57 @@ for o in IETFWG.objects.all().order_by("pk"):
|
|||
elif not group.parent:
|
||||
print "no area/parent for", group.acronym, group.name, group.type, group.state
|
||||
|
||||
try:
|
||||
area_director = o.area_director
|
||||
except AreaDirector.DoesNotExist:
|
||||
area_director = None
|
||||
if area_director and not area_director.area_id:
|
||||
area_director = None # fake TBD guy
|
||||
|
||||
group.ad = old_person_to_person(area_director.person) if area_director else None
|
||||
group.list_email = o.email_address if o.email_address else ""
|
||||
l = o.email_archive.strip() if o.email_archive else ""
|
||||
group.list_subscribe = (o.email_subscribe or "").replace("//listinfo", "/listinfo").strip()
|
||||
l = o.clean_email_archive().strip() if o.email_archive else ""
|
||||
if l in ("none", "not available"):
|
||||
l = ""
|
||||
group.list_pages = l
|
||||
group.list_archive = l
|
||||
group.comments = o.comments.strip() if o.comments else ""
|
||||
|
||||
group.save()
|
||||
|
||||
for u in o.additional_urls():
|
||||
url, _ = GroupURL.objects.get_or_create(group=group, url=u.url)
|
||||
url.name = u.description.strip()
|
||||
url.save()
|
||||
|
||||
for m in o.milestones():
|
||||
desc = m.description.strip()
|
||||
try:
|
||||
milestone = GroupMilestone.objects.get(group=group, desc=desc)
|
||||
except GroupMilestone.DoesNotExist:
|
||||
milestone = GroupMilestone(group=group, desc=desc)
|
||||
|
||||
milestone.expected_due_date = m.expected_due_date
|
||||
milestone.done = m.done == "Done"
|
||||
milestone.done_date = m.done_date
|
||||
milestone.time = datetime.datetime.combine(m.last_modified_date, datetime.time(12, 0, 0))
|
||||
milestone.save()
|
||||
|
||||
# import events
|
||||
group.groupevent_set.all().delete()
|
||||
|
||||
def import_date_event(name):
|
||||
def import_date_event(name, type_name):
|
||||
d = getattr(o, "%s_date" % name)
|
||||
if d:
|
||||
e = GroupEvent(group=group, type=name)
|
||||
e = GroupEvent(group=group, type=type_name)
|
||||
e.time = datetime.datetime.combine(d, datetime.time(12, 0, 0))
|
||||
e.by = system
|
||||
e.desc = e.get_type_display()
|
||||
e.save()
|
||||
|
||||
import_date_event("proposed")
|
||||
import_date_event("start")
|
||||
import_date_event("concluded")
|
||||
import_date_event("proposed", "proposed")
|
||||
import_date_event("start", "started")
|
||||
import_date_event("concluded", "concluded")
|
||||
# dormant_date is empty on all so don't bother with that
|
||||
|
||||
# FIXME: missing fields from old: meeting_scheduled, email_subscribe, email_keyword, last_modified_date, meeting_scheduled_old
|
||||
# FIXME: missing fields from old: meeting_scheduled, email_keyword, meeting_scheduled_old
|
||||
|
|
|
@ -11,12 +11,17 @@ settings.USE_DB_REDESIGN_PROXY_CLASSES = False
|
|||
from django.core import management
|
||||
management.setup_environ(settings)
|
||||
|
||||
from ietf.idtracker.models import AreaDirector, IETFWG
|
||||
from redesign.person.models import *
|
||||
from redesign.importing.utils import get_or_create_email
|
||||
|
||||
# creates system person and email
|
||||
|
||||
# imports AreaDirector persons that are connected to an IETFWG
|
||||
|
||||
# should probably also import the old person/email tables
|
||||
|
||||
print "creating (System) person and email"
|
||||
try:
|
||||
system_person = Person.objects.get(name="(System)")
|
||||
except Person.DoesNotExist:
|
||||
|
@ -33,7 +38,6 @@ if system_person.id != 0: # work around bug in Django
|
|||
Person.objects.filter(id=system_person.id).update(id=0)
|
||||
system_person = Person.objects.get(id=0)
|
||||
|
||||
|
||||
system_alias = Alias.objects.get_or_create(
|
||||
person=system_person,
|
||||
name=system_person.name
|
||||
|
@ -41,6 +45,10 @@ system_alias = Alias.objects.get_or_create(
|
|||
|
||||
system_email = Email.objects.get_or_create(
|
||||
address="",
|
||||
person=system_person,
|
||||
active=True
|
||||
defaults=dict(active=True, person=system_person)
|
||||
)
|
||||
|
||||
for o in AreaDirector.objects.filter(ietfwg__in=IETFWG.objects.all()).exclude(area_acronym=None).distinct().order_by("pk").iterator():
|
||||
print "importing AreaDirector (from IETFWG) persons", o.pk
|
||||
|
||||
get_or_create_email(o, create_fake=False)
|
||||
|
|
|
@ -11,12 +11,12 @@ settings.USE_DB_REDESIGN_PROXY_CLASSES = False
|
|||
from django.core import management
|
||||
management.setup_environ(settings)
|
||||
|
||||
from redesign import unaccent
|
||||
from redesign.person.models import *
|
||||
from redesign.group.models import *
|
||||
from redesign.name.models import *
|
||||
from redesign.name.utils import name
|
||||
from redesign.importing.utils import old_person_to_email, clean_email_address
|
||||
from redesign.importing.utils import old_person_to_email, clean_email_address, get_or_create_email
|
||||
|
||||
from ietf.idtracker.models import IESGLogin, AreaDirector, IDAuthor, PersonOrOrgInfo, WGChair, WGEditor, WGSecretary, WGTechAdvisor, ChairsHistory, Role as OldRole, Acronym, IRTFChair
|
||||
|
||||
|
||||
|
@ -41,36 +41,6 @@ editor_role = name(RoleName, "editor", "Editor")
|
|||
secretary_role = name(RoleName, "secr", "Secretary")
|
||||
techadvisor_role = name(RoleName, "techadv", "Tech Advisor")
|
||||
|
||||
# helpers for creating the objects
|
||||
def get_or_create_email(o, create_fake):
|
||||
email = old_person_to_email(o.person)
|
||||
if not email:
|
||||
if create_fake:
|
||||
email = u"unknown-email-%s-%s" % (o.person.first_name, o.person.last_name)
|
||||
print ("USING FAKE EMAIL %s for %s %s %s" % (email, o.person.pk, o.person.first_name, o.person.last_name)).encode('utf-8')
|
||||
else:
|
||||
print ("NO EMAIL FOR %s %s %s %s %s" % (o.__class__, o.pk, o.person.pk, o.person.first_name, o.person.last_name)).encode('utf-8')
|
||||
return None
|
||||
|
||||
e, _ = Email.objects.select_related("person").get_or_create(address=email)
|
||||
if not e.person:
|
||||
n = u"%s %s" % (o.person.first_name, o.person.last_name)
|
||||
asciified = unaccent.asciify(n)
|
||||
aliases = Alias.objects.filter(name__in=(n, asciified))
|
||||
if aliases:
|
||||
p = aliases[0].person
|
||||
else:
|
||||
p = Person.objects.create(id=o.person.pk, name=n, ascii=asciified)
|
||||
# FIXME: fill in address?
|
||||
|
||||
Alias.objects.create(name=n, person=p)
|
||||
if asciified != n:
|
||||
Alias.objects.create(name=asciified, person=p)
|
||||
|
||||
e.person = p
|
||||
e.save()
|
||||
|
||||
return e
|
||||
|
||||
# WGEditor
|
||||
for o in WGEditor.objects.all():
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from person.models import Person
|
||||
from redesign import unaccent
|
||||
from redesign.person.models import Person, Email, Alias
|
||||
|
||||
def clean_email_address(addr):
|
||||
addr = addr.replace("!", "@").replace("(at)", "@") # some obvious @ replacements
|
||||
|
@ -16,4 +17,34 @@ def old_person_to_email(person):
|
|||
hardcoded_emails = { 'Dinara Suleymanova': "dinaras@ietf.org" }
|
||||
|
||||
return clean_email_address(person.email()[1] or hardcoded_emails.get("%s %s" % (person.first_name, person.last_name)) or "")
|
||||
|
||||
def get_or_create_email(o, create_fake):
|
||||
# take person on o and get or create new Email and Person objects
|
||||
email = old_person_to_email(o.person)
|
||||
if not email:
|
||||
if create_fake:
|
||||
email = u"unknown-email-%s-%s" % (o.person.first_name, o.person.last_name)
|
||||
print ("USING FAKE EMAIL %s for %s %s %s" % (email, o.person.pk, o.person.first_name, o.person.last_name)).encode('utf-8')
|
||||
else:
|
||||
print ("NO EMAIL FOR %s %s %s %s %s" % (o.__class__, o.pk, o.person.pk, o.person.first_name, o.person.last_name)).encode('utf-8')
|
||||
return None
|
||||
|
||||
e, _ = Email.objects.select_related("person").get_or_create(address=email)
|
||||
if not e.person:
|
||||
n = u"%s %s" % (o.person.first_name, o.person.last_name)
|
||||
asciified = unaccent.asciify(n)
|
||||
aliases = Alias.objects.filter(name__in=(n, asciified))
|
||||
if aliases:
|
||||
p = aliases[0].person
|
||||
else:
|
||||
p = Person.objects.create(id=o.person.pk, name=n, ascii=asciified)
|
||||
# FIXME: fill in address?
|
||||
|
||||
Alias.objects.create(name=n, person=p)
|
||||
if asciified != n:
|
||||
Alias.objects.create(name=asciified, person=p)
|
||||
|
||||
e.person = p
|
||||
e.save()
|
||||
|
||||
return e
|
||||
|
|
|
@ -2,10 +2,11 @@ from redesign.proxy_utils import TranslatingManager
|
|||
from models import *
|
||||
|
||||
class IDStatus(DocStateName):
|
||||
def __init__(self, base):
|
||||
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')
|
||||
|
@ -18,3 +19,98 @@ class IDStatus(DocStateName):
|
|||
|
||||
class Meta:
|
||||
proxy = True
|
||||
|
||||
class IDState(IesgDocStateName):
|
||||
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="order"))
|
||||
|
||||
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
|
||||
from name.models import get_next_iesg_states
|
||||
return IDState.objects.filter(pk__in=[x.pk for x in get_next_iesg_states(self)])
|
||||
|
||||
@property
|
||||
def next_state(self):
|
||||
# simulate IDNextState
|
||||
return self
|
||||
|
||||
def __str__(self):
|
||||
return self.state
|
||||
|
||||
@staticmethod
|
||||
def choices():
|
||||
return [(state.slug, state.name) for state in IDState.objects.all()]
|
||||
|
||||
class Meta:
|
||||
proxy = True
|
||||
|
||||
|
||||
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(DocInfoTagName):
|
||||
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
|
||||
|
||||
|
|
|
@ -44,6 +44,14 @@ class Person(models.Model):
|
|||
else:
|
||||
prefix, first, middle, last, suffix = self.ascii_parts()
|
||||
return (first and first[0]+"." or "")+(middle or "")+" "+last+(suffix and " "+suffix or "")
|
||||
def role_email(self, role_name, group):
|
||||
e = Email.objects.filter(person=self, role__group=group, role__name=role_name)
|
||||
if e:
|
||||
return e[0]
|
||||
e = self.email_set.order("-active")
|
||||
if e:
|
||||
return e[0]
|
||||
return None
|
||||
def email_address(self):
|
||||
e = self.email_set.filter(active=True)
|
||||
if e:
|
||||
|
|
|
@ -150,13 +150,16 @@ class TranslatingManager(Manager):
|
|||
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):
|
||||
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):
|
||||
|
|
Loading…
Reference in a new issue