245 lines
11 KiB
Python
245 lines
11 KiB
Python
# Copyright The IETF Trust 2011, All Rights Reserved
|
|
|
|
import re, os
|
|
from datetime import datetime, time
|
|
|
|
from django.http import HttpResponse, Http404
|
|
from django.shortcuts import render_to_response, get_object_or_404, redirect
|
|
from django.template import RequestContext
|
|
from django.template.defaultfilters import truncatewords_html
|
|
from django.utils import simplejson as json
|
|
from django.utils.decorators import decorator_from_middleware
|
|
from django.middleware.gzip import GZipMiddleware
|
|
from django.core.exceptions import ObjectDoesNotExist
|
|
from ietf.doc.models import GroupBallotPositionDocEvent, WriteupDocEvent
|
|
from ietf.group.models import Group, GroupHistory
|
|
from ietf.person.models import Person
|
|
from wgcharter import markup_txt
|
|
from django.conf import settings
|
|
|
|
from wgcharter.utils import *
|
|
from ietf.utils.history import find_history_active_at
|
|
from ietf.idtracker.templatetags.ietf_filters import format_textarea, fill
|
|
|
|
def _get_html(key, filename):
|
|
f = None
|
|
try:
|
|
f = open(filename, 'rb')
|
|
raw_content = f.read()
|
|
except IOError:
|
|
return "Error; cannot read ("+key+")"
|
|
finally:
|
|
if f:
|
|
f.close()
|
|
content = markup_txt.markup(raw_content)
|
|
return content
|
|
|
|
@decorator_from_middleware(GZipMiddleware)
|
|
def wg_main(request, name, rev, tab):
|
|
if tab is None:
|
|
tab = "charter"
|
|
try:
|
|
wg = Group.objects.get(acronym=name)
|
|
except ObjectDoesNotExist:
|
|
wglist = GroupHistory.objects.filter(acronym=name)
|
|
if wglist:
|
|
return redirect('wg_view', name=wglist[0].group.acronym)
|
|
else:
|
|
raise Http404
|
|
|
|
if not wg.charter:
|
|
set_or_create_charter(wg)
|
|
|
|
if rev != None:
|
|
ch = get_charter_for_revision(wg.charter, rev)
|
|
gh = get_group_for_revision(wg, rev)
|
|
else:
|
|
ch = get_charter_for_revision(wg.charter, wg.charter.rev)
|
|
gh = get_group_for_revision(wg, wg.charter.rev)
|
|
|
|
|
|
info = {}
|
|
|
|
info['prev_acronyms'] = list(set([x.acronym for x in wg.history_set.exclude(acronym=wg.acronym)]))
|
|
prev_list_email = list(set([x.list_email for x in wg.history_set.exclude(list_email=wg.list_email) if x.list_email != u'']))
|
|
if prev_list_email != [u'']:
|
|
info['prev_list_email'] = prev_list_email
|
|
prev_list_subscribe = list(set([x.list_subscribe for x in wg.history_set.exclude(list_subscribe=wg.list_subscribe) if x.list_subscribe != u'']))
|
|
if prev_list_subscribe != [u'']:
|
|
info['prev_list_subscribe'] = prev_list_subscribe
|
|
prev_list_archive = list(set([x.list_archive for x in wg.history_set.exclude(list_archive=wg.list_archive) if x.list_archive != u'']))
|
|
if prev_list_archive != [u'']:
|
|
info['prev_list_archive'] = prev_list_archive
|
|
info['chairs'] = [x.email.person.name for x in wg.role_set.filter(name__slug="chair")]
|
|
if hasattr(gh, 'rolehistory_set'):
|
|
info['history_chairs'] = [x.email.person.name for x in gh.rolehistory_set.filter(name__slug="chair")]
|
|
else:
|
|
info['history_chairs'] = [x.email.person.name for x in gh.role_set.filter(name__slug="chair")]
|
|
info['secr'] = [x.email.person.name for x in wg.role_set.filter(name__slug="secr")]
|
|
info['techadv'] = [x.email.person.name for x in wg.role_set.filter(name__slug="techadv")]
|
|
|
|
if ch:
|
|
file_path = wg.charter.get_file_path() # Get from wg.charter
|
|
content = _get_html(
|
|
"charter-ietf-"+str(gh.acronym)+"-"+str(ch.rev)+".txt",
|
|
os.path.join(file_path, "charter-ietf-"+gh.acronym+"-"+ch.rev+".txt"))
|
|
active_ads = Person.objects.filter(email__role__name="ad", email__role__group__state="active").distinct()
|
|
started_process = datetime.min
|
|
e = wg.charter.latest_event(type="started_iesg_process")
|
|
if e:
|
|
started_process = e.time
|
|
seen = []
|
|
latest_positions = []
|
|
for p in GroupBallotPositionDocEvent.objects.filter(doc=wg.charter, type="changed_ballot_position", time__gte=started_process).order_by("-time", '-id').select_related('ad'):
|
|
if p.ad not in seen:
|
|
latest_positions.append(p)
|
|
seen.append(p.ad)
|
|
no_record = []
|
|
old_ads = []
|
|
for p in latest_positions:
|
|
if p.ad not in active_ads:
|
|
old_ads.append(p.ad)
|
|
for ad in active_ads:
|
|
has_no_record = True
|
|
for p in latest_positions:
|
|
if p.ad == ad:
|
|
has_no_record = False
|
|
if has_no_record:
|
|
no_record.append(ad)
|
|
|
|
info['old_ads'] = old_ads
|
|
info['positions'] = latest_positions
|
|
info['pos_yes'] = filter(lambda x: x.pos_id == "yes", latest_positions)
|
|
info['pos_no'] = filter(lambda x: x.pos_id == "no", latest_positions)
|
|
info['pos_block'] = filter(lambda x: x.pos_id == "block", latest_positions)
|
|
info['pos_abstain'] = filter(lambda x: x.pos_id == "abstain", latest_positions)
|
|
info['pos_no_record'] = no_record + [x.ad for x in latest_positions if x.pos_id == "norecord"]
|
|
|
|
# Get announcement texts
|
|
review_ann = wg.charter.latest_event(WriteupDocEvent, type="changed_review_announcement")
|
|
info['review_text'] = review_ann.text if review_ann else ""
|
|
action_ann = wg.charter.latest_event(WriteupDocEvent, type="changed_action_announcement")
|
|
info['action_text'] = action_ann.text if action_ann else ""
|
|
ballot_ann = wg.charter.latest_event(WriteupDocEvent, type="changed_ballot_writeup_text")
|
|
info['ballot_text'] = ballot_ann.text if ballot_ann else ""
|
|
else:
|
|
content = ""
|
|
|
|
versions = _get_versions(wg.charter) # Important: wg.charter not ch
|
|
history = _get_history(wg, versions)
|
|
|
|
if history:
|
|
info['last_update'] = history[0]['date']
|
|
|
|
template = "wgcharter/wg_tab_%s" % tab
|
|
return render_to_response(template + ".html",
|
|
{'content':content,
|
|
'charter':ch,
|
|
'info':info,
|
|
'wg':wg,
|
|
'tab':tab,
|
|
'rev': rev if rev else ch.rev,
|
|
'gh': gh,
|
|
'snapshot': rev,
|
|
'charter_text_url': settings.CHARTER_TXT_URL,
|
|
'history': history, 'versions': versions,
|
|
},
|
|
context_instance=RequestContext(request))
|
|
|
|
def _get_history(wg, versions=None):
|
|
results = []
|
|
for e in wg.charter.docevent_set.all().order_by('-time'):
|
|
info = {}
|
|
charter_history = find_history_active_at(wg.charter, e.time)
|
|
info['version'] = charter_history.rev if charter_history else wg.charter.rev
|
|
info['text'] = e.desc
|
|
info['by'] = e.by.name
|
|
info['textSnippet'] = truncatewords_html(format_textarea(fill(info['text'], 80)), 25)
|
|
info['snipped'] = info['textSnippet'][-3:] == "..."
|
|
if e.type == "new_revision":
|
|
if charter_history:
|
|
charter = get_charter_for_revision(wg.charter, charter_history.rev)
|
|
group = get_group_for_revision(wg, charter_history.rev)
|
|
else:
|
|
charter = get_charter_for_revision(wg.charter, wg.charter.rev)
|
|
group = get_group_for_revision(wg, wg.charter.rev)
|
|
|
|
if versions:
|
|
vl = [x['rev'] for x in versions]
|
|
if vl:
|
|
prev_charter = get_charter_for_revision(wg.charter, vl[vl.index(charter.rev) - 1])
|
|
else:
|
|
prev_charter = get_charter_for_revision(wg.charter, prev_revision(charter.rev))
|
|
prev_group = get_group_for_revision(wg, prev_revision(charter.rev))
|
|
results.append({'comment':e, 'info':info, 'date':e.time, 'group': group,
|
|
'charter': charter, 'prev_charter': prev_charter,
|
|
'prev_group': prev_group,
|
|
'txt_url': settings.CHARTER_TXT_URL,
|
|
'is_rev':True})
|
|
else:
|
|
results.append({'comment':e, 'info':info, 'date':e.time, 'group': wg, 'is_com':True})
|
|
|
|
# convert plain dates to datetimes (required for sorting)
|
|
for x in results:
|
|
if not isinstance(x['date'], datetime):
|
|
if x['date']:
|
|
x['date'] = datetime.combine(x['date'], time(0,0,0))
|
|
else:
|
|
x['date'] = datetime(1970,1,1)
|
|
|
|
results.sort(key=lambda x: x['date'])
|
|
results.reverse()
|
|
return results
|
|
|
|
def _get_versions(charter, include_replaced=True):
|
|
ov = []
|
|
prev = ""
|
|
for r in charter.history_set.order_by('time'):
|
|
if r.rev != prev:
|
|
d = get_charter_for_revision(charter, r.rev)
|
|
g = get_group_for_revision(charter.chartered_group, r.rev)
|
|
ov.append({"name": "charter-ietf-%s" % g.acronym, "rev":d.rev, "date":d.time})
|
|
prev = r.rev
|
|
if charter.rev != "" and (not ov or ov[-1]['rev'] != charter.rev):
|
|
d = get_charter_for_revision(charter, charter.rev)
|
|
g = get_group_for_revision(charter.chartered_group, charter.rev)
|
|
ov.append({"name": "charter-ietf-%s" % g.acronym, "rev": d.rev, "date":d.time})
|
|
return ov
|
|
|
|
def wg_ballot(request, name):
|
|
try:
|
|
wg = Group.objects.get(acronym=name)
|
|
except ObjectDoesNotExist:
|
|
wglist = GroupHistory.objects.filter(acronym=name)
|
|
if wglist:
|
|
return redirect('wg_view', name=wglist[0].group.acronym)
|
|
else:
|
|
raise Http404
|
|
|
|
doc = set_or_create_charter(wg)
|
|
|
|
if not doc:
|
|
raise Http404
|
|
|
|
active_ads = list(Person.objects.filter(email__role__name="ad",
|
|
email__role__group__type="area",
|
|
email__role__group__state="active").distinct())
|
|
started_process = doc.latest_event(type="started_iesg_process")
|
|
latest_positions = []
|
|
no_record = []
|
|
for p in active_ads:
|
|
p_pos = list(GroupBallotPositionDocEvent.objects.filter(doc=wg.charter, ad=p).order_by("-time"))
|
|
if p_pos != []:
|
|
latest_positions.append(p_pos[0])
|
|
else:
|
|
no_record.append(p)
|
|
info = {}
|
|
info['positions'] = latest_positions
|
|
info['pos_yes'] = filter(lambda x: x.pos_id == "yes", latest_positions)
|
|
info['pos_no'] = filter(lambda x: x.pos_id == "no", latest_positions)
|
|
info['pos_block'] = filter(lambda x: x.pos_id == "block", latest_positions)
|
|
info['pos_abstain'] = filter(lambda x: x.pos_id == "abstain", latest_positions)
|
|
info['pos_no_record'] = no_record
|
|
return render_to_response('wgcharter/wg_ballot.html', {'info':info, 'wg':wg, 'doc': doc}, context_instance=RequestContext(request))
|
|
|