Change auth model for new schema to use Person rather than Email where email is not necessary, use Person for user profiles rather than the old unused profile class, use REMOTE_USER backend directly instead of custom backend, use group roles for authorization rather than Django groups, port/proxy code from using IESGLogin to the new model

- Legacy-Id: 3151
This commit is contained in:
Ole Laursen 2011-05-25 12:33:24 +00:00
parent 43c0288146
commit 1bea94eb12
41 changed files with 576 additions and 308 deletions

View file

@ -88,15 +88,15 @@ class ScheduledAnnouncement(models.Model):
db_table = 'scheduled_announcements'
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
if settings.USE_DB_REDESIGN_PROXY_CLASSES or hasattr(settings, "IMPORTING_ANNOUNCEMENTS"):
import datetime
from person.models import Email
from person.models import Email, Person
from group.models import Group
class Message(models.Model):
time = models.DateTimeField(default=datetime.datetime.now)
by = models.ForeignKey(Email)
by = models.ForeignKey(Person)
subject = models.CharField(max_length=255)
frm = models.CharField(max_length=255)
@ -116,7 +116,8 @@ if settings.USE_DB_REDESIGN_PROXY_CLASSES:
class SendQueue(models.Model):
time = models.DateTimeField(default=datetime.datetime.now)
by = models.ForeignKey(Email)
by = models.ForeignKey(Person)
comment = models.TextField()
message = models.ForeignKey(Message)
send_at = models.DateTimeField(blank=True, null=True)

View file

@ -35,7 +35,6 @@ def nomcom(request):
'regimes' : regimes })
def nomcomREDESIGN(request):
from person.models import Email
from group.models import Group
from ietf.announcements.models import Message
@ -75,7 +74,6 @@ if settings.USE_DB_REDESIGN_PROXY_CLASSES:
def message_detail(request, object_id, queryset):
from person.models import Email
from group.models import Group
from ietf.announcements.models import Message

View file

@ -11,7 +11,7 @@ from ietf.utils.mail import send_mail, send_mail_subj
from ietf.idrfc.utils import log_state_changed, add_document_comment
from doc.models import Document, Event, save_document_in_history
from name.models import IesgDocStateName, DocStateName, DocInfoTagName
from person.models import Email
from person.models import Person, Email
INTERNET_DRAFT_DAYS_TO_EXPIRE = 185
@ -186,7 +186,7 @@ def expire_id(doc):
add_document_comment(None, doc, "Document is expired by system")
def expire_idREDESIGN(doc):
system_email = Email.objects.get(address="(System)")
system = Person.objects.get(name="(System)")
# clean up files
def move_file(f):
@ -219,9 +219,9 @@ def expire_idREDESIGN(doc):
if doc.iesg_state != dead_state:
prev = doc.iesg_state
doc.iesg_state = dead_state
log_state_changed(None, doc, system_email, prev)
log_state_changed(None, doc, system, prev)
e = Event(doc=doc, by=system_email)
e = Event(doc=doc, by=system)
e.type = "expired_document"
e.desc = "Document has expired"
e.save()

View file

@ -641,8 +641,8 @@ class BallotWrapper:
self.old_init()
return
from redesign.person.models import Email
active_ads = Email.objects.filter(role__name="ad", role__group__state="active")
from redesign.person.models import Person
active_ads = Person.objects.filter(email__role__name="ad", email__role__group__state="active").distinct()
positions = []
seen = {}
@ -650,7 +650,7 @@ class BallotWrapper:
from doc.models import BallotPositionEvent
for pos in BallotPositionEvent.objects.filter(doc=self.ballot, type="changed_ballot_position", time__gte=self.ballot.process_start, time__lte=self.ballot.process_end).select_related('ad').order_by("-time", '-id'):
if pos.ad not in seen:
p = dict(ad_name=pos.ad.get_name(),
p = dict(ad_name=pos.ad.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,
@ -684,7 +684,7 @@ class BallotWrapper:
if self.ballot_active:
for ad in active_ads:
if ad not in seen:
d = dict(ad_name=ad.get_name(),
d = dict(ad_name=ad.name,
ad_username=ad.pk,
position="No Record",
)

View file

@ -4,13 +4,13 @@ import datetime
from django.conf import settings
from ietf.idtracker.models import InternetDraft, DocumentComment, BallotInfo, IESGLogin
from ietf.idtracker.models import InternetDraft, DocumentComment, BallotInfo
from ietf.idrfc.mails import *
from ietf.idrfc.utils import *
from doc.models import Document, Event, LastCallEvent, WriteupEvent, save_document_in_history
from name.models import IesgDocStateName
from person.models import Email
from person.models import Person
def request_last_call(request, doc):
try:
@ -33,9 +33,9 @@ def request_last_callREDESIGN(request, doc):
e = Event()
e.type = "requested_last_call"
e.by = request.user.get_profile().email()
e.by = request.user.get_profile()
e.doc = doc
e.desc = "Last call was requested by %s" % e.by.get_name()
e.desc = "Last call was requested by %s" % e.by.name
e.save()
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
@ -83,7 +83,7 @@ def expire_last_callREDESIGN(doc):
prev = doc.iesg_state
doc.iesg_state = state
e = log_state_changed(None, doc, Email.objects.get(address="(System)"), prev)
e = log_state_changed(None, doc, Person.objects.get(name="(System)"), prev)
doc.time = e.time
doc.save()

View file

@ -10,7 +10,7 @@ from django.conf import settings
from ietf.utils.mail import send_mail, send_mail_text
from ietf.idtracker.models import *
from doc.models import WriteupEvent, BallotPositionEvent, LastCallEvent
from person.models import Email
from person.models import Person
def email_state_changed(request, doc, text):
to = [x.strip() for x in doc.idinternal.state_change_notice_to.replace(';', ',').split(',')]
@ -55,7 +55,7 @@ def email_ownerREDESIGN(request, doc, owner, changed_by, text, subject=None):
to = owner.formatted_email()
send_mail(request, to,
"DraftTracker Mail System <iesg-secretary@ietf.org>",
"%s updated by %s" % (doc.file_tag(), changed_by.get_name()),
"%s updated by %s" % (doc.file_tag(), changed_by.name),
"idrfc/change_notice.txt",
dict(text=html_to_text(text),
doc=doc,
@ -88,9 +88,9 @@ def full_intended_status(intended_status):
def generate_ballot_writeup(request, doc):
e = WriteupEvent()
e.type = "changed_ballot_writeup_text"
e.by = request.user.get_profile().email()
e.by = request.user.get_profile()
e.doc = doc
e.desc = u"Ballot writeup was generated by %s" % e.by.get_name()
e.desc = u"Ballot writeup was generated by %s" % e.by.name
e.text = unicode(render_to_string("idrfc/ballot_writeup.txt"))
e.save()
@ -160,9 +160,9 @@ def generate_last_call_announcementREDESIGN(request, doc):
e = WriteupEvent()
e.type = "changed_last_call_text"
e.by = request.user.get_profile().email()
e.by = request.user.get_profile()
e.doc = doc
e.desc = u"Last call announcement was generated by %s" % e.by.get_name()
e.desc = u"Last call announcement was generated by %s" % e.by.name
e.text = unicode(mail)
e.save()
@ -255,9 +255,9 @@ def generate_approval_mailREDESIGN(request, doc):
e = WriteupEvent()
e.type = "changed_ballot_approval_text"
e.by = request.user.get_profile().email()
e.by = request.user.get_profile()
e.doc = doc
e.desc = u"Ballot approval text was generated by %s" % e.by.get_name()
e.desc = u"Ballot approval text was generated by %s" % e.by.name
e.text = unicode(mail)
e.save()
@ -292,12 +292,12 @@ def generate_approval_mail_approved(request, doc):
made_by = "This document is the product of the %s." % doc.group.name_with_wg
director = doc.ad
other_director = Email.objects.filter(role__group__role__email=director, role__group__role__name="ad").exclude(pk=director.pk)
other_director = Person.objects.filter(email__role__group__role__email__person=director, email__role__group__role__name="ad").exclude(pk=director.pk)
if doc.group.type_id != "individ" and other_director:
contacts = "The IESG contact persons are %s and %s." % (director.get_name(), other_director[0].get_name())
contacts = "The IESG contact persons are %s and %s." % (director.name, other_director[0].name)
else:
contacts = "The IESG contact person is %s." % director.get_name()
contacts = "The IESG contact person is %s." % director.name
doc_type = "RFC" if doc.state_id == "rfc" else "Internet Draft"
@ -476,7 +476,7 @@ def generate_issue_ballot_mailREDESIGN(request, doc):
full_status = full_intended_status(doc.intended_std_level.name)
status = full_status.replace("a ", "").replace("an ", "")
active_ads = Email.objects.filter(role__name="ad", role__group__state="active")
active_ads = Person.objects.filter(email__role__name="ad", email__role__group__state="active").distinct()
e = doc.latest_event(type="started_iesg_process")
positions = BallotPositionEvent.objects.filter(doc=doc, type="changed_ballot_position", time__gte=e.time).order_by("-time", '-id').select_related('ad')
@ -499,7 +499,7 @@ def generate_issue_ballot_mailREDESIGN(request, doc):
return "[ ]"
fmt = u"%-21s%-10s%-11s%-9s%-10s" % (
p.ad.get_name()[:21],
p.ad.name[:21],
formatted(p.pos_id == "yes"),
formatted(p.pos_id == "noobj"),
formatted(p.pos_id == "discuss"),
@ -517,7 +517,7 @@ def generate_issue_ballot_mailREDESIGN(request, doc):
active_ad_positions.sort()
inactive_ad_positions.sort()
ad_feedback.sort(key=lambda p: p.ad.get_name())
ad_feedback.sort(key=lambda p: p.ad.name)
e = doc.latest_event(LastCallEvent, type="sent_last_call")
last_call_expires = e.expires if e else None

View file

@ -178,13 +178,13 @@ import django.db.transaction
@django.db.transaction.commit_on_success
def insert_to_databaseREDESIGN(data):
from person.models import Email
from person.models import Person
from doc.models import Document, DocAlias, Event, RelatedDocument
from group.models import Group
from name.models import DocInfoTagName, DocRelationshipName
from name.utils import name
system_email = Email.objects.get(address="(System)")
system = Person.objects.get(name="(System)")
std_level_mapping = get_std_level_mapping()
stream_mapping = get_stream_mapping()
tag_has_errata = name(DocInfoTagName, 'errata', "Has errata")
@ -203,7 +203,8 @@ def insert_to_databaseREDESIGN(data):
# we assume two things can happen: we get a new RFC, or an
# attribute has been updated at the RFC Editor (RFC Editor
# attributes currently take precedence)
# attributes currently take precedence over our local
# attributes)
# make sure we got the document and alias
created = False
@ -257,7 +258,7 @@ def insert_to_databaseREDESIGN(data):
if not doc.latest_event(type="published_rfc", time=pubdate):
e = Event(doc=doc, type="published_rfc")
e.time = pubdate
e.by = system_email
e.by = system
e.desc = "RFC published"
e.save()
changed = True

View file

@ -42,16 +42,20 @@ register = template.Library()
def get_user_adid(context):
if 'user' in context and in_group(context['user'], "Area_Director"):
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
# with the new design, we need the email address (FIXME:
# we shouldn't go through the old classes though,
# IESGLogin needs revamping)
return context['user'].get_profile().person().email()[1]
return context['user'].get_profile().id
return context['user'].get_profile().iesg_login_id()
else:
return None
def get_user_name(context):
if 'user' in context and context['user'].is_authenticated():
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
from person.models import Person
try:
return context['user'].get_profile().name
except Person.DoesNotExist:
return None
person = context['user'].get_profile().person()
if person:
return str(person)

View file

@ -41,7 +41,7 @@ from django.conf import settings
from pyquery import PyQuery
from ietf.idtracker.models import IESGLogin, PersonOrOrgInfo, EmailAddress, IDDates
from ietf.idtracker.models import IDDates
from doc.models import *
from name.models import *
from group.models import *
@ -182,7 +182,7 @@ class EditInfoTestCase(django.test.TestCase):
events_before = draft.event_set.count()
mailbox_before = len(mail_outbox)
new_ad = Email.objects.get(address="ad1@ietf.org")
new_ad = Person.objects.get(name="Ad No1")
r = self.client.post(url,
dict(intended_std_level=str(draft.intended_std_level.pk),
@ -266,13 +266,13 @@ class EditInfoTestCase(django.test.TestCase):
events_before = draft.event_set.count()
mailbox_before = len(mail_outbox)
ad = Email.objects.get(address="aread@ietf.org")
ad = Person.objects.get(name="Aread Irector")
r = self.client.post(url,
dict(intended_std_level=str(draft.intended_std_level_id),
status_date=str(date.today() + timedelta(2)),
via_rfc_editor="1",
ad=ad,
ad=ad.pk,
notify="test@example.com",
note="This is a note",
telechat_date="",
@ -320,7 +320,7 @@ class ResurrectTestCase(django.test.TestCase):
self.assertEquals(draft.event_set.count(), events_before + 1)
e = draft.latest_event(type="requested_resurrect")
self.assertTrue(e)
self.assertEquals(e.by, Email.objects.get(address="aread@ietf.org"))
self.assertEquals(e.by, Person.objects.get(name="Aread Irector"))
self.assertTrue("Resurrection" in e.desc)
self.assertEquals(len(mail_outbox), mailbox_before + 1)
self.assertTrue("Resurrection" in mail_outbox[-1]['Subject'])
@ -331,7 +331,7 @@ class ResurrectTestCase(django.test.TestCase):
draft.save()
Event.objects.create(doc=draft,
type="requested_resurrect",
by=Email.objects.get(address="aread@ietf.org"))
by=Person.objects.get(name="Aread Irector"))
url = urlreverse('doc_resurrect', kwargs=dict(name=draft.name))
@ -392,7 +392,7 @@ class EditPositionTestCase(django.test.TestCase):
url = urlreverse('doc_edit_position', kwargs=dict(name=draft.name))
login_testing_unauthorized(self, "ad", url)
ad = Email.objects.get(address="aread@ietf.org")
ad = Person.objects.get(name="Aread Irector")
# normal get
r = self.client.get(url)
@ -451,7 +451,7 @@ class EditPositionTestCase(django.test.TestCase):
def test_edit_position_as_secretary(self):
draft = make_test_data()
url = urlreverse('doc_edit_position', kwargs=dict(name=draft.name))
ad = Email.objects.get(address="aread@ietf.org")
ad = Person.objects.get(name="Aread Irector")
url += "?ad=%s" % ad.pk
login_testing_unauthorized(self, "secretary", url)
@ -476,7 +476,7 @@ class EditPositionTestCase(django.test.TestCase):
draft.notify = "somebody@example.com"
draft.save()
ad = Email.objects.get(address="aread@ietf.org")
ad = Person.objects.get(name="Aread Irector")
BallotPositionEvent.objects.create(doc=draft, type="changed_ballot_position",
by=ad, ad=ad, pos=BallotPositionName.objects.get(slug="yes"),
@ -643,7 +643,7 @@ class BallotWriteupsTestCase(django.test.TestCase):
login_testing_unauthorized(self, "ad", url)
def create_pos(num, vote, comment="", discuss=""):
ad = Email.objects.get(address="ad%s@ietf.org" % num)
ad = Person.objects.get(name="Ad No%s" % num)
e = BallotPositionEvent()
e.doc = draft
e.by = ad
@ -671,7 +671,7 @@ class BallotWriteupsTestCase(django.test.TestCase):
# we need approval text to be able to submit
e = WriteupEvent()
e.doc = draft
e.by = Email.objects.get(address="aread@ietf.org")
e.by = Person.objects.get(name="Aread Irector")
e.type = "changed_ballot_approval_text"
e.text = "The document has been approved."
e.save()
@ -866,7 +866,7 @@ class ExpireIDsTestCase(django.test.TestCase):
NewRevisionEvent.objects.create(
type="new_revision",
by=Email.objects.get(address="aread@ietf.org"),
by=Person.objects.get(name="Aread Irector"),
doc=draft,
desc="New revision",
time=datetime.datetime.now() - datetime.timedelta(days=INTERNET_DRAFT_DAYS_TO_EXPIRE - 7),
@ -897,7 +897,7 @@ class ExpireIDsTestCase(django.test.TestCase):
NewRevisionEvent.objects.create(
type="new_revision",
by=Email.objects.get(address="aread@ietf.org"),
by=Person.objects.get(name="Aread Irector"),
doc=draft,
desc="New revision",
time=datetime.datetime.now() - datetime.timedelta(days=INTERNET_DRAFT_DAYS_TO_EXPIRE + 1),
@ -986,7 +986,7 @@ class ExpireIDsTestCase(django.test.TestCase):
e = Event()
e.doc = draft
e.by = Email.objects.get(address="(System)")
e.by = Person.objects.get(name="(System)")
e.type = "expired_document"
e.text = "Document has expired"
e.time = datetime.date.today() - datetime.timedelta(days=INTERNET_DRAFT_DAYS_TO_EXPIRE + 1)
@ -1028,12 +1028,14 @@ class ExpireLastCallTestCase(django.test.TestCase):
draft = make_test_data()
draft.iesg_state_id = "lc"
draft.save()
secretary = Person.objects.get(name="Sec Retary")
self.assertEquals(len(list(get_expired_last_calls())), 0)
e = LastCallEvent()
e.doc = draft
e.by = Email.objects.get(address="sec.retary@ietf.org")
e.by = secretary
e.type = "sent_last_call"
e.text = "Last call sent"
e.expires = datetime.datetime.now() + datetime.timedelta(days=14)
@ -1044,7 +1046,7 @@ class ExpireLastCallTestCase(django.test.TestCase):
# test expired
e = LastCallEvent()
e.doc = draft
e.by = Email.objects.get(address="sec.retary@ietf.org")
e.by = secretary
e.type = "sent_last_call"
e.text = "Last call sent"
e.expires = datetime.datetime.now()

View file

@ -67,7 +67,7 @@ def log_state_changedREDESIGN(request, doc, by, prev_iesg_state):
e.desc = u"State changed to <b>%s</b> from <b>%s</b> by %s" % (
doc.iesg_state.name,
prev_iesg_state.name if prev_iesg_state else "None",
by.get_name())
by.name)
e.save()
return e
@ -145,19 +145,19 @@ def update_telechatREDESIGN(request, doc, by, new_telechat_date, new_returning_i
if on_agenda != prev_agenda:
if on_agenda:
e.desc = "Placed on agenda for telechat - %s by %s" % (
new_telechat_date, by.get_name())
new_telechat_date, by.name)
else:
e.desc = "Removed from agenda for telechat by %s" % by.get_name()
e.desc = "Removed from agenda for telechat by %s" % by.name
elif on_agenda and new_telechat_date != prev_telechat:
e.desc = "Telechat date has been changed to <b>%s</b> from <b>%s</b> by %s" % (
new_telechat_date, prev_telechat, by.get_name())
new_telechat_date, prev_telechat, by.name)
else:
# we didn't reschedule but flipped returning item bit - let's
# just explain that
if returning:
e.desc = "Added as returning item on telechat by %s" % by.get_name()
e.desc = "Added as returning item on telechat by %s" % by.name
else:
e.desc = "Removed as returning item on telechat by %s" % by.get_name()
e.desc = "Removed as returning item on telechat by %s" % by.name
e.save()

View file

@ -15,6 +15,7 @@ from django.conf import settings
from ietf.utils.mail import send_mail_text, send_mail_preformatted
from ietf.ietfauth.decorators import group_required
from ietf.idtracker.templatetags.ietf_filters import in_group
from ietf.ietfauth.decorators import has_role
from ietf.idtracker.models import *
from ietf.iesg.models import *
from ietf.ipr.models import IprDetail
@ -205,7 +206,7 @@ def edit_positionREDESIGN(request, name):
if not doc.iesg_state or not started_process:
raise Http404()
ad = login = request.user.get_profile().email()
ad = login = request.user.get_profile()
if 'HTTP_REFERER' in request.META:
return_to_url = request.META['HTTP_REFERER']
@ -213,11 +214,12 @@ def edit_positionREDESIGN(request, name):
return_to_url = doc.get_absolute_url()
# if we're in the Secretariat, we can select an AD to act as stand-in for
if not in_group(request.user, "Area_Director"):
if not has_role(request.user, "Area Director"):
ad_id = request.GET.get('ad')
if not ad_id:
raise Http404()
ad = get_object_or_404(Email, pk=ad_id)
from person.models import Person
ad = get_object_or_404(Person, pk=ad_id)
old_pos = doc.latest_event(BallotPositionEvent, type="changed_ballot_position", ad=ad, time__gte=started_process.time)
@ -270,17 +272,17 @@ def edit_positionREDESIGN(request, name):
# figure out a description
if not old_pos and pos.pos.slug != "norecord":
pos.desc = u"[Ballot Position Update] New position, %s, has been recorded for %s" % (pos.pos.name, pos.ad.get_name())
pos.desc = u"[Ballot Position Update] New position, %s, has been recorded for %s" % (pos.pos.name, pos.ad.name)
elif old_pos and pos.pos != old_pos.pos:
pos.desc = "[Ballot Position Update] Position for %s has been changed to %s from %s" % (pos.ad.get_name(), pos.pos.name, old_pos.pos.name)
pos.desc = "[Ballot Position Update] Position for %s has been changed to %s from %s" % (pos.ad.name, pos.pos.name, old_pos.pos.name)
if not pos.desc and changes:
pos.desc = u"Ballot %s text updated for %s" % (u" and ".join(changes), ad.get_name())
pos.desc = u"Ballot %s text updated for %s" % (u" and ".join(changes), ad.name)
# only add new event if we actually got a change
if pos.desc:
if login != ad:
pos.desc += u" by %s" % login.get_name()
pos.desc += u" by %s" % login.name
pos.save()
@ -399,7 +401,7 @@ def send_ballot_commentREDESIGN(request, name):
if not started_process:
raise Http404()
ad = login = request.user.get_profile().email()
ad = login = request.user.get_profile()
return_to_url = request.GET.get('return_to_url')
if not return_to_url:
@ -411,11 +413,12 @@ def send_ballot_commentREDESIGN(request, name):
back_url = doc.get_absolute_url()
# if we're in the Secretariat, we can select an AD to act as stand-in for
if not in_group(request.user, "Area_Director"):
if not has_role(request.user, "Area Director"):
ad_id = request.GET.get('ad')
if not ad_id:
raise Http404()
ad = get_object_or_404(Email, pk=ad_id)
from person.models import Person
ad = get_object_or_404(Person, pk=ad_id)
pos = doc.latest_event(BallotPositionEvent, type="changed_ballot_position", ad=ad, time__gte=started_process.time)
if not pos:
@ -503,7 +506,7 @@ def defer_ballotREDESIGN(request, name):
if not doc.iesg_state:
raise Http404()
login = request.user.get_profile().email()
login = request.user.get_profile()
telechat_date = TelechatDates.objects.all()[0].date2
if request.method == 'POST':
@ -519,7 +522,7 @@ def defer_ballotREDESIGN(request, name):
email_state_changed(request, doc, e.desc)
update_telechat(request, doc, login, telechat_date)
email_ballot_deferred(request, doc, login.get_name(), telechat_date)
email_ballot_deferred(request, doc, login.name, telechat_date)
return HttpResponseRedirect(doc.get_absolute_url())
@ -565,7 +568,7 @@ def undefer_ballotREDESIGN(request, name):
if not doc.iesg_state:
raise Http404()
login = request.user.get_profile().email()
login = request.user.get_profile()
if request.method == 'POST':
save_document_in_history(doc)
@ -702,7 +705,7 @@ def lastcalltextREDESIGN(request, name):
if not doc.iesg_state:
raise Http404()
login = request.user.get_profile().email()
login = request.user.get_profile()
existing = doc.latest_event(WriteupEvent, type="changed_last_call_text")
if not existing:
@ -719,7 +722,7 @@ def lastcalltextREDESIGN(request, name):
e = WriteupEvent(doc=doc, by=login)
e.by = login
e.type = "changed_last_call_text"
e.desc = "Last call announcement was changed by %s" % login.get_name()
e.desc = "Last call announcement was changed by %s" % login.name
e.text = t
e.save()
@ -867,7 +870,7 @@ def ballot_writeupnotesREDESIGN(request, name):
if not started_process:
raise Http404()
login = request.user.get_profile().email()
login = request.user.get_profile()
approval = doc.latest_event(WriteupEvent, type="changed_ballot_approval_text")
@ -885,7 +888,7 @@ def ballot_writeupnotesREDESIGN(request, name):
e = WriteupEvent(doc=doc, by=login)
e.by = login
e.type = "changed_ballot_writeup_text"
e.desc = "Ballot writeup was changed by %s" % login.get_name()
e.desc = "Ballot writeup was changed by %s" % login.name
e.text = t
e.save()
@ -893,13 +896,13 @@ def ballot_writeupnotesREDESIGN(request, name):
doc.save()
if "issue_ballot" in request.POST and approval:
if in_group(request.user, "Area_Director") and not doc.latest_event(BallotPositionEvent, ad=login, time__gte=started_process.time):
if has_role(request.user, "Area Director") and not doc.latest_event(BallotPositionEvent, ad=login, time__gte=started_process.time):
# sending the ballot counts as a yes
pos = BallotPositionEvent(doc=doc, by=login)
pos.type = "changed_ballot_position"
pos.ad = login
pos.pos_id = "yes"
pos.desc = "[Ballot Position Update] New position, %s, has been recorded for %s" % (pos.pos.name, pos.ad.get_name())
pos.desc = "[Ballot Position Update] New position, %s, has been recorded for %s" % (pos.pos.name, pos.ad.name)
pos.save()
msg = generate_issue_ballot_mail(request, doc)
@ -910,7 +913,7 @@ def ballot_writeupnotesREDESIGN(request, name):
e = Event(doc=doc, by=login)
e.by = login
e.type = "sent_ballot_announcement"
e.desc = "Ballot has been issued by %s" % login.get_name()
e.desc = "Ballot has been issued by %s" % login.name
e.save()
doc.time = e.time
@ -1002,7 +1005,7 @@ def ballot_approvaltextREDESIGN(request, name):
if not doc.iesg_state:
raise Http404()
login = request.user.get_profile().email()
login = request.user.get_profile()
existing = doc.latest_event(WriteupEvent, type="changed_ballot_approval_text")
if not existing:
@ -1019,7 +1022,7 @@ def ballot_approvaltextREDESIGN(request, name):
e = WriteupEvent(doc=doc, by=login)
e.by = login
e.type = "changed_ballot_approval_text"
e.desc = "Ballot approval text was changed by %s" % login.get_name()
e.desc = "Ballot approval text was changed by %s" % login.name
e.text = t
e.save()
@ -1131,7 +1134,7 @@ def approve_ballotREDESIGN(request, name):
if not doc.iesg_state:
raise Http404()
login = request.user.get_profile().email()
login = request.user.get_profile()
e = doc.latest_event(WriteupEvent, type="changed_ballot_approval_text")
if not e:
@ -1281,7 +1284,7 @@ def make_last_callREDESIGN(request, name):
if not doc.iesg_state:
raise Http404()
login = request.user.get_profile().email()
login = request.user.get_profile()
e = doc.latest_event(WriteupEvent, type="changed_last_call_text")
if not e:
@ -1325,7 +1328,7 @@ def make_last_callREDESIGN(request, name):
e = LastCallEvent(doc=doc, by=login)
e.type = "sent_last_call"
e.desc = "Last call sent by %s" % login.get_name()
e.desc = "Last call sent by %s" % login.name
if form.cleaned_data['last_call_sent_date'] != e.time.date():
e.time = datetime.datetime.combine(form.cleaned_data['last_call_sent_date'], e.time.time())
e.expires = form.cleaned_data['last_call_expiration_date']

View file

@ -109,7 +109,7 @@ def document_main(request, name):
return document_main_rfc(request, int(m.group(1)))
id = get_object_or_404(InternetDraft, filename=name)
doc = IdWrapper(id)
info = {}
stream_id = doc.stream_id()
if stream_id == 2:
@ -168,7 +168,7 @@ def _get_history(doc, versions):
info["dontmolest"] = True
info['text'] = e.desc
info['by'] = e.by.get_name()
info['by'] = e.by.name
info['textSnippet'] = truncatewords_html(format_textarea(fill(info['text'], 80)), 25)
info['snipped'] = info['textSnippet'][-3:] == "..." and e.type != "new_revision"
results.append({'comment':e, 'info':info, 'date':e.time, 'is_com':True})

View file

@ -16,6 +16,7 @@ from django.conf import settings
from ietf.utils.mail import send_mail_text
from ietf.ietfauth.decorators import group_required
from ietf.idtracker.templatetags.ietf_filters import in_group
from ietf.ietfauth.decorators import has_role
from ietf.idtracker.models import *
from ietf.iesg.models import *
from ietf.idrfc.mails import *
@ -24,6 +25,7 @@ from ietf.idrfc.lastcall import request_last_call
from doc.models import Document, Event, StatusDateEvent, TelechatEvent, save_document_in_history, DocHistory
from name.models import IesgDocStateName, IntendedStdLevelName, DocInfoTagName, get_next_iesg_states, DocStateName
from person.models import Person, Email
class ChangeStateForm(forms.Form):
state = forms.ModelChoiceField(IDState.objects.all(), empty_label=None, required=True)
@ -93,7 +95,7 @@ def change_stateREDESIGN(request, name):
if (not doc.latest_event(type="started_iesg_process")) or doc.state_id == "expired":
raise Http404()
login = request.user.get_profile().email()
login = request.user.get_profile()
if request.method == 'POST':
form = ChangeStateForm(request.POST)
@ -371,15 +373,11 @@ def edit_info(request, name):
login=login),
context_instance=RequestContext(request))
class NameFromEmailModelChoiceField(forms.ModelChoiceField):
def label_from_instance(self, obj):
return obj.get_name()
class EditInfoFormREDESIGN(forms.Form):
intended_std_level = forms.ModelChoiceField(IntendedStdLevelName.objects.all(), empty_label=None, required=True)
status_date = forms.DateField(required=False, help_text="Format is YYYY-MM-DD")
via_rfc_editor = forms.BooleanField(required=False, label="Via IRTF or RFC Editor")
ad = NameFromEmailModelChoiceField(Email.objects.filter(role__name__in=("ad", "ex-ad")).order_by('role__name', 'person__name'), label="Responsible AD", empty_label=None, required=True)
ad = forms.ModelChoiceField(Person.objects.filter(email__role__name__in=("ad", "ex-ad")).order_by('email__role__name', 'name'), label="Responsible AD", empty_label=None, required=True)
notify = forms.CharField(max_length=255, label="Notice emails", help_text="Separate email addresses with commas", required=False)
note = forms.CharField(widget=forms.Textarea, label="IESG note", required=False)
telechat_date = forms.TypedChoiceField(coerce=lambda x: datetime.datetime.strptime(x, '%Y-%m-%d').date(), empty_value=None, required=False)
@ -392,7 +390,7 @@ class EditInfoFormREDESIGN(forms.Form):
# fix up ad field
choices = self.fields['ad'].choices
ex_ads = dict((e.pk, e) for e in Email.objects.filter(role__name="ex-ad"))
ex_ads = dict((e.pk, e) for e in Person.objects.filter(email__role__name="ex-ad").distinct())
if old_ads:
# separate active ADs from inactive
for i, t in enumerate(choices):
@ -455,7 +453,7 @@ def edit_infoREDESIGN(request, name):
if doc.state_id == "expired":
raise Http404()
login = request.user.get_profile().email()
login = request.user.get_profile()
new_document = False
if not doc.iesg_state: # FIXME: should probably get this as argument to view
@ -486,7 +484,7 @@ def edit_infoREDESIGN(request, name):
# place where the replace relationship is established
e = Event()
e.type = "added_comment"
e.by = Email.objects.get(address="(System)")
e.by = Person.objects.get(name="(System)")
e.doc = doc
e.desc = "Earlier history may be found in the Comment Log for <a href=\"%s\">%s</a>" % (replaces[0], replaces[0].get_absolute_url())
e.save()
@ -535,7 +533,7 @@ def edit_infoREDESIGN(request, name):
for c in changes:
e = Event(doc=doc, by=login)
e.type = "changed_document"
e.desc = c + " by %s" % login.get_name()
e.desc = c + " by %s" % login.name
e.save()
update_telechat(request, doc, login,
@ -548,11 +546,11 @@ def edit_infoREDESIGN(request, name):
e.type ="changed_status_date"
d = desc("Status date", r["status_date"], status_date)
changes.append(d)
e.desc = d + " by %s" % login.get_name()
e.desc = d + " by %s" % login.name
e.date = r["status_date"]
e.save()
if in_group(request.user, 'Secretariat'):
if has_role(request.user, 'Secretariat'):
via_rfc = DocInfoTagName.objects.get(slug="via-rfc")
if r['via_rfc_editor']:
doc.tags.add(via_rfc)
@ -580,7 +578,7 @@ def edit_infoREDESIGN(request, name):
form = EditInfoForm(old_ads=False, initial=init)
if not in_group(request.user, 'Secretariat'):
if not has_role(request.user, 'Secretariat'):
# filter out Via RFC Editor
form.standard_fields = [x for x in form.standard_fields if x.name != "via_rfc_editor"]
@ -627,14 +625,14 @@ def request_resurrectREDESIGN(request, name):
if doc.state_id != "expired":
raise Http404()
login = request.user.get_profile().email()
login = request.user.get_profile()
if request.method == 'POST':
email_resurrect_requested(request, doc, login)
e = Event(doc=doc, by=login)
e.type = "requested_resurrect"
e.desc = "Resurrection was requested by %s" % login.get_name()
e.desc = "Resurrection was requested by %s" % login.name
e.save()
return HttpResponseRedirect(doc.get_absolute_url())
@ -682,7 +680,7 @@ def resurrectREDESIGN(request, name):
if doc.state_id != "expired":
raise Http404()
login = request.user.get_profile().email()
login = request.user.get_profile()
if request.method == 'POST':
save_document_in_history(doc)
@ -693,7 +691,7 @@ def resurrectREDESIGN(request, name):
e = Event(doc=doc, by=login)
e.type = "completed_resurrect"
e.desc = "Resurrection was completed by %s" % login.get_name()
e.desc = "Resurrection was completed by %s" % login.name
e.save()
doc.state = DocStateName.objects.get(slug="active")
@ -746,7 +744,7 @@ def add_commentREDESIGN(request, name):
if not doc.iesg_state:
raise Http404()
login = request.user.get_profile().email()
login = request.user.get_profile()
if request.method == 'POST':
form = AddCommentForm(request.POST)
@ -759,7 +757,7 @@ def add_commentREDESIGN(request, name):
e.save()
email_owner(request, doc, doc.ad, login,
"A new comment added by %s" % login.get_name())
"A new comment added by %s" % login.name)
return HttpResponseRedirect(doc.get_absolute_url())
else:
form = AddCommentForm()

View file

@ -276,18 +276,16 @@ if settings.USE_DB_REDESIGN_PROXY_CLASSES:
def __init__(self, *args, **kwargs):
super(SearchForm, self).__init__(*args, **kwargs)
responsible = Document.objects.values_list('ad', flat=True).distinct()
active_ads = list(Email.objects.filter(role__name="ad",
role__group__type="area",
role__group__state="active")
.select_related('person'))
inactive_ads = list(Email.objects.filter(pk__in=responsible)
.exclude(pk__in=[x.pk for x in active_ads])
.select_related('person'))
extract_last_name = lambda x: x.get_name().split(' ')[-1]
active_ads = list(Person.objects.filter(email__role__name="ad",
email__role__group__type="area",
email__role__group__state="active").distinct())
inactive_ads = list(Person.objects.filter(pk__in=responsible)
.exclude(pk__in=[x.pk for x in active_ads]))
extract_last_name = lambda x: x.name_parts()[3]
active_ads.sort(key=extract_last_name)
inactive_ads.sort(key=extract_last_name)
self.fields['ad'].choices = c = [('', 'any AD')] + [(ad.pk, ad.get_name()) for ad in active_ads] + [('', '------------------')] + [(ad.pk, ad.get_name()) for ad in inactive_ads]
self.fields['ad'].choices = c = [('', 'any AD')] + [(ad.pk, ad.name) for ad in active_ads] + [('', '------------------')] + [(ad.pk, ad.name) for ad in inactive_ads]
self.fields['subState'].choices = [('', 'any substate'), ('0', 'no substate')] + [(n.slug, n.name) for n in DocInfoTagName.objects.filter(slug__in=('point', 'ad-f-up', 'need-rev', 'extpty'))]
def clean_name(self):
value = self.cleaned_data.get('name','')
@ -479,16 +477,21 @@ def search_main(request):
def by_ad(request, name):
ad_id = None
ad_name = None
for i in IESGLogin.objects.filter(user_level__in=[1,2]):
iname = str(i).lower().replace(' ','.')
if name == iname:
ad_id = i.id
ad_name = str(i)
break
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
for p in Person.objects.filter(email__role__name__in=("ad", "ex-ad")):
if name == p.name.lower().replace(" ", "."):
ad_id = p.id
ad_name = p.name
break
else:
for i in IESGLogin.objects.filter(user_level__in=[1,2]):
iname = str(i).lower().replace(' ','.')
if name == iname:
ad_id = i.id
ad_name = str(i)
break
if not ad_id:
raise Http404
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
ad_id = i.person.email()[1]
form = SearchForm({'by':'ad','ad':ad_id,
'rfcs':'on', 'activeDrafts':'on', 'oldDrafts':'on'})
if not form.is_valid():

View file

@ -88,7 +88,8 @@ class IESGLoginAdmin(admin.ModelAdmin):
ordering=['user_level', 'last_name']
list_display=('login_name', 'first_name', 'last_name', 'user_level')
raw_id_fields=['person']
admin.site.register(IESGLogin, IESGLoginAdmin)
if not settings.USE_DB_REDESIGN_PROXY_CLASSES:
admin.site.register(IESGLogin, IESGLoginAdmin)
class IETFWGAdmin(admin.ModelAdmin):
list_display=('group_acronym', 'group_type', 'status', 'area_acronym', 'start_date', 'concluded_date')

View file

@ -1094,8 +1094,10 @@ if settings.USE_DB_REDESIGN_PROXY_CLASSES:
IDSubStateOld = IDSubState
AreaOld = Area
AcronymOld = Acronym
IESGLoginOld = IESGLogin
from redesign.doc.proxy import InternetDraft, IDInternal, BallotInfo, IDState, IDSubState
from redesign.group.proxy import Area, Acronym
from redesign.person.proxy import IESGLogin
# changes done by convert-096.py:changed maxlength to max_length

View file

@ -2,6 +2,7 @@
import textwrap
from django import template
from django.conf import settings
from django.utils.html import escape, fix_ampersands
from django.template.defaultfilters import linebreaksbr, wordwrap, stringfilter
from django.template import resolve_variable
@ -358,8 +359,18 @@ def startswith(x, 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
if not user:
return False
return has_role(user, role_names.split(','))
@register.filter
def stable_dictsort(value, arg):
"""

View file

@ -42,6 +42,6 @@ class IESGAgenda(Feed):
return str( item.job_owner )
def item_author_email(self, item):
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
return item.ad.address
return item.ad.email_address()
return item.job_owner.person.email()[1]

View file

@ -66,7 +66,7 @@ class RescheduleOnAgendaTestCaseREDESIGN(django.test.TestCase):
def test_reschedule(self):
from ietf.utils.test_data import make_test_data
from redesign.person.models import Email
from redesign.person.models import Person
from doc.models import TelechatEvent
draft = make_test_data()
@ -74,7 +74,7 @@ class RescheduleOnAgendaTestCaseREDESIGN(django.test.TestCase):
# add to schedule
e = TelechatEvent(type="scheduled_for_telechat")
e.doc = draft
e.by = Email.objects.get(address="aread@ietf.org")
e.by = Person.objects.get(name="Aread Irector")
e.telechat_date = TelechatDates.objects.all()[0].date1
e.returning_item = True
e.save()
@ -159,6 +159,56 @@ class ManageTelechatDatesTestCase(django.test.TestCase):
self.assertTrue(dates.date4 == new_date)
self.assertTrue(dates.date1 == old_date2)
class ManageTelechatDatesTestCaseREDESIGN(django.test.TestCase):
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
class WorkingGroupActionsTestCase(django.test.TestCase):
fixtures = ['base', 'wgactions']
@ -320,7 +370,7 @@ class WorkingGroupActionsTestCaseREDESIGN(django.test.TestCase):
def test_edit_wgaction(self):
from ietf.utils.test_data import make_test_data
from redesign.person.models import Email
from redesign.person.models import Person
make_test_data()
@ -337,7 +387,7 @@ class WorkingGroupActionsTestCaseREDESIGN(django.test.TestCase):
# change
dates = TelechatDates.objects.all()[0]
token_name = Email.objects.get(address="ad1@ietf.org").get_name().split(" ")[0]
token_name = Person.objects.get(name="Ad No1").name_parts()[1]
old = wga.pk
r = self.client.post(url, dict(status_date=dates.date1.isoformat(),
token_name=token_name,
@ -355,7 +405,7 @@ class WorkingGroupActionsTestCaseREDESIGN(django.test.TestCase):
def test_add_possible_wg(self):
from ietf.utils.test_data import make_test_data
from redesign.person.models import Email
from redesign.person.models import Person
from redesign.group.models import Group
make_test_data()
@ -388,7 +438,7 @@ class WorkingGroupActionsTestCaseREDESIGN(django.test.TestCase):
wgas_before = WGAction.objects.all().count()
dates = TelechatDates.objects.all()[0]
token_name = Email.objects.get(address="ad1@ietf.org").get_name().split(" ")[0]
token_name = Person.objects.get(name="Ad No1").name_parts()[1]
r = self.client.post(add_url,
dict(status_date=dates.date1.isoformat(),
token_name=token_name,

View file

@ -309,6 +309,7 @@ def agenda_scribe_template(request):
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))
@group_required('Area_Director','Secretariat')
@ -381,7 +382,7 @@ def handle_reschedule_form(request, idinternal, dates):
form = RescheduleForm(request.POST, **formargs)
if form.is_valid():
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
login = request.user.get_profile().email()
login = request.user.get_profile()
update_telechat(request, idinternal, login,
form.cleaned_data['telechat_date'],
False if form.cleaned_data['clear_returning_item'] else None)

View file

@ -31,6 +31,8 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from django.utils.http import urlquote
from django.conf import settings
from django.db.models import Q
from django.contrib.auth.decorators import _CheckLogin
from django.http import HttpResponseRedirect, HttpResponseForbidden
@ -62,3 +64,48 @@ def group_required(*group_names):
def decorate(view_func):
return _CheckLogin403(view_func, lambda u: bool(u.groups.filter(name__in=group_names)), "Restricted to group%s %s" % ("s" if len(group_names) != 1 else "", ",".join(group_names)))
return decorate
def has_role(user, role_names):
"""Determines whether user has any of the given standard roles
given. Role names must be a list or, in case of a single value, a
string."""
if isinstance(role_names, str) or isinstance(role_names, unicode):
role_names = [ role_names ]
if not user or not user.is_authenticated():
return False
from redesign.person.models import Person
try:
person = user.get_profile()
except Person.DoesNotExist:
return False
role_qs = {
"Area Director": Q(email__person=person, name="ad"),
"Secretariat": Q(email__person=person, name="secr", group__acronym="secretariat")
}
filter_expr = Q()
for r in role_names:
filter_expr |= role_qs[r]
from redesign.group.models import Role
return bool(Role.objects.filter(filter_expr)[:1])
def role_required(*role_names):
"""View decorator for checking that the user is logged in and
belongs to (at least) one of the listed roles. Users who are not
logged in are redirected to the login page; users who don't have
one of the roles get a "403" page.
"""
def decorate(view_func):
return _CheckLogin403(view_func,
lambda u: has_role(u, role_names),
"Restricted to role%s %s" % ("s" if len(role_names) != 1 else "", ",".join(role_names)))
return decorate
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
group_required = lambda *group_names: role_required(*[n.replace("Area_Director", "Area Director") for n in group_names])

View file

@ -31,6 +31,7 @@
# 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
@ -41,6 +42,8 @@ class IetfAuthUrlTestCase(SimpleUrlTestCase):
def testUrls(self):
self.doTestUrls(__file__)
# 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()
@ -61,7 +64,7 @@ class IetfAuthTestCase(unittest.TestCase,RealDatabaseTest):
response = c.get(nexturl[2], {}, False, REMOTE_USER=username)
self.assertEquals(response.status_code, 200)
self.assert_("Roles/Groups:" in response.content)
self.assert_("User name" in response.content)
return response
def testLogin(self):
@ -95,4 +98,7 @@ class IetfAuthTestCase(unittest.TestCase,RealDatabaseTest):
self.assert_("IETF_Chair" in groups)
print "OK"
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
# this test doesn't make any sense anymore
IetfAuthTestCase.testGroups = lambda x: None

View file

@ -69,4 +69,21 @@ def ietf_loggedin(request):
@login_required
def profile(request):
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
from person.models import Person
from group.models import Role
roles = []
person = None
try:
person = request.user.get_profile()
roles = Role.objects.filter(email__person=person).distinct()
except Person.DoesNotExist:
pass
return render_to_response('registration/profileREDESIGN.html',
dict(roles=roles,
person=person),
context_instance=RequestContext(request))
return render_to_response('registration/profile.html', context_instance=RequestContext(request))

View file

@ -198,6 +198,10 @@ LIAISON_ATTACH_URL = '/documents/LIAISON/'
# DB redesign
USE_DB_REDESIGN_PROXY_CLASSES = True
if USE_DB_REDESIGN_PROXY_CLASSES:
AUTH_PROFILE_MODULE = 'person.Person'
AUTHENTICATION_BACKENDS = ( 'django.contrib.auth.backends.RemoteUserBackend', )
# Put SECRET_KEY in here, or any other sensitive or site-specific
# changes. DO NOT commit settings_local.py to svn.
from settings_local import *

View file

@ -1,6 +1,6 @@
{% extends "base.html" %}
{% block title %}Change position for {{ ad.get_name }}{% endblock %}
{% block title %}Change position for {{ ad.name }}{% endblock %}
{% block morecss %}
form.position-form .position ul {
@ -29,7 +29,7 @@ form.position-form .comment-text {
{% endblock %}
{% block content %}
<h1>Change position for {{ ad.get_name }}</h1>
<h1>Change position for {{ ad.name }}</h1>
<form class="position-form" action="" method="POST">
<div class="position">{{ form.position }}</div>

View file

@ -1,6 +1,6 @@
{% extends "base.html" %}
{% block title %}Email Discuss and Comment text for {{ ad.get_name }} to IESG list{% endblock %}
{% block title %}Email Discuss and Comment text for {{ ad.name }} to IESG list{% endblock %}
{% block morecss %}
form.send-ballot pre {
@ -12,7 +12,7 @@ form.send-ballot pre {
{% endblock %}
{% block content %}
<h1>Email Discuss and Comment text for {{ ad.get_name }} to IESG list</h1>
<h1>Email Discuss and Comment text for {{ ad.name }} to IESG list</h1>
<form class="send-ballot" action="" method="POST">
<table>

View file

@ -49,9 +49,9 @@ Some parts Copyright (c) 2009 The IETF Trust, all rights reserved.
{% endfor %} {% if doc.obj.ballot.active %}<br><b>Discusses/comments</b> (from <a href="http://datatracker.ietf.org/idtracker/ballot/{{ doc.obj.ballot.ballot}}/">ballot {{doc.obj.ballot.ballot }})</a>:
<ol>
{% if USE_DB_REDESIGN_PROXY_CLASSES %}
{% for p in doc.obj.active_positions|dictsort:"ad.get_name" %}{% if p.pos %}{% ifequal p.pos.pos_id "discuss" %}<li><a href="#{{doc.obj.document.filename}}+{{p.pos.ad|slugify}}+discuss">{{ p.pos.ad.get_name }}: Discuss [{{ p.pos.discuss_time.date }}]</a>:
{% for p in doc.obj.active_positions|dictsort:"ad.name" %}{% if p.pos %}{% ifequal p.pos.pos_id "discuss" %}<li><a href="#{{doc.obj.document.filename}}+{{p.pos.ad|slugify}}+discuss">{{ p.pos.ad.name }}: Discuss [{{ p.pos.discuss_time.date }}]</a>:
<br>...
{% endifequal %}{% if p.pos.comment %} <li><a href="#{{doc.obj.document.filename}}+{{position.ad|slugify}}+comment">{{ p.pos.ad.get_name }}: Comment [{{ p.pos.comment_time.date }}]</a>:
{% endifequal %}{% if p.pos.comment %} <li><a href="#{{doc.obj.document.filename}}+{{position.ad|slugify}}+comment">{{ p.pos.ad.name }}: Comment [{{ p.pos.comment_time.date }}]</a>:
<br>...
{% endif %}{% endif %}{% endfor %}
{% else %}

View file

@ -0,0 +1,31 @@
{# Copyright The IETF Trust 2007, All Rights Reserved #}
{% extends "base.html" %}
{% block morecss %}
table.userProfile th {
text-align: left;
}
{% endblock %}
{% block title %}Profile for {{ user }}{% endblock %}
{% block content %}
<h1>User information</h1>
<table class="userProfile">
<tr>
<th>User name:</th>
<td>{{ user.username }}</td>
</tr>
<tr>
<th>Person:</th>
<td>{{ person.name|default:"?" }}</td>
</tr>
{% for role in roles %}
<tr>
<th>{% if forloop.first %}Roles:{% endif %}</th>
<td>{{ role.name }} in {{ role.group.name }} ({{ role.group.type }})</td>
</tr>
{% endfor %}
</table>
{% endblock %}

View file

@ -1,4 +1,5 @@
from ietf.idtracker.models import IESGLogin, PersonOrOrgInfo, EmailAddress
from django.contrib.auth.models import User
from ietf.iesg.models import TelechatDates, WGAction
from redesign.doc.models import *
from redesign.name.models import *
@ -7,6 +8,12 @@ from redesign.person.models import *
def make_test_data():
# groups
secretariat = Group.objects.create(
name="Secretariat",
acronym="secretariat",
state_id="active",
type_id="ietf",
parent=None)
area = Group.objects.create(
name="Far Future",
acronym="farfut",
@ -22,45 +29,43 @@ def make_test_data():
)
# persons
Email.objects.get_or_create(address="(System)")
# system
system_person = Person.objects.create(
id=0, # special value
name="(System)",
ascii="(System)",
address="",
)
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)
Alias.objects.get_or_create(person=system_person, name=system_person.name)
Email.objects.get_or_create(address="", person=system_person)
# ad
p = Person.objects.create(
u = User.objects.create(username="ad")
ad = p = Person.objects.create(
name="Aread Irector",
ascii="Aread Irector",
)
ad = Email.objects.create(
user=u)
email = Email.objects.create(
address="aread@ietf.org",
person=p)
Role.objects.create(
name_id="ad",
group=area,
email=ad)
porg = PersonOrOrgInfo.objects.create(
first_name="Aread",
last_name="Irector",
middle_initial="",
)
EmailAddress.objects.create(
person_or_org=porg,
priority=1,
address=ad.address,
)
IESGLogin.objects.create(
login_name="ad",
password="foo",
user_level=1,
first_name=porg.first_name,
last_name=porg.last_name,
person=porg,
)
email=email)
# create a bunch of ads for swarm tests
for i in range(1, 10):
u = User.objects.create(username="ad%s" % i)
p = Person.objects.create(
name="Ad No%s" % i,
ascii="Ad No%s" % i,
)
user=u)
email = Email.objects.create(
address="ad%s@ietf.org" % i,
person=p)
@ -68,24 +73,6 @@ def make_test_data():
name_id="ad" if i <= 5 else "ex-ad",
group=area,
email=email)
porg = PersonOrOrgInfo.objects.create(
first_name="Ad",
last_name="No%s" % i,
middle_initial="",
)
EmailAddress.objects.create(
person_or_org=porg,
priority=1,
address=ad.address,
)
IESGLogin.objects.create(
login_name="ad%s" % i,
password="foo",
user_level=1,
first_name=porg.first_name,
last_name=porg.last_name,
person=porg,
)
# group chair
p = Person.objects.create(
@ -96,36 +83,24 @@ def make_test_data():
address="wgchairman@ietf.org",
person=p)
Role.objects.create(
name=RoleName.objects.get(slug="chair"),
name_id="chair",
group=group,
email=wgchair,
)
# secretary
u = User.objects.create(username="secretary")
p = Person.objects.create(
name="Sec Retary",
ascii="Sec Retary",
)
Email.objects.create(
user=u)
email = Email.objects.create(
address="sec.retary@ietf.org",
person=p)
porg = PersonOrOrgInfo.objects.create(
first_name="Sec",
last_name="Retary",
middle_initial="",
)
EmailAddress.objects.create(
person_or_org=porg,
priority=1,
address="sec.retary@ietf.org",
)
IESGLogin.objects.create(
login_name="secretary",
password="foo",
user_level=0,
first_name=porg.first_name,
last_name=porg.last_name,
person=porg,
Role.objects.create(
name_id="secr",
group=secretariat,
email=email,
)
# draft

View file

@ -5,7 +5,7 @@ from django.core.urlresolvers import reverse as urlreverse
from redesign.group.models import *
from redesign.name.models import *
from redesign.person.models import Email
from redesign.person.models import Email, Person
from redesign.util import admin_link
import datetime
@ -31,8 +31,8 @@ class DocumentInfo(models.Model):
pages = models.IntegerField(blank=True, null=True)
intended_std_level = models.ForeignKey(IntendedStdLevelName, blank=True, null=True)
std_level = models.ForeignKey(StdLevelName, blank=True, null=True)
ad = models.ForeignKey(Email, verbose_name="area director", related_name='ad_%(class)s_set', blank=True, null=True)
shepherd = models.ForeignKey(Email, related_name='shepherd_%(class)s_set', blank=True, null=True)
ad = models.ForeignKey(Person, verbose_name="area director", related_name='ad_%(class)s_set', blank=True, null=True)
shepherd = models.ForeignKey(Person, related_name='shepherd_%(class)s_set', blank=True, null=True)
notify = models.CharField(max_length=255, blank=True)
external_url = models.URLField(blank=True) # Should be set for documents with type 'External'.
note = models.TextField(blank=True)
@ -60,8 +60,8 @@ class RelatedDocument(models.Model):
class DocumentAuthor(models.Model):
document = models.ForeignKey('Document')
author = models.ForeignKey(Email)
order = models.IntegerField()
author = models.ForeignKey(Email, help_text="Email address used by author for submission")
order = models.IntegerField(default=1)
def __unicode__(self):
return u"%s %s (%s)" % (self.document.name, self.author.get_name(), self.order)
@ -224,12 +224,12 @@ class Event(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")
type = models.CharField(max_length=50, choices=EVENT_TYPES)
by = models.ForeignKey(Email, blank=True, null=True) # FIXME: make NOT NULL?
by = models.ForeignKey(Person)
doc = models.ForeignKey('doc.Document')
desc = models.TextField()
def __unicode__(self):
return u"%s %s at %s" % (self.by.get_name(), self.get_type_display().lower(), self.time)
return u"%s %s at %s" % (self.by.name, self.get_type_display().lower(), self.time)
class Meta:
ordering = ['-time', 'id']
@ -239,7 +239,7 @@ class NewRevisionEvent(Event):
# IESG events
class BallotPositionEvent(Event):
ad = models.ForeignKey(Email)
ad = models.ForeignKey(Person)
pos = models.ForeignKey(BallotPositionName, verbose_name="position", default="norecord")
discuss = models.TextField(help_text="Discuss text if position is discuss", blank=True)
discuss_time = models.DateTimeField(help_text="Time discuss text was written", blank=True, null=True)

View file

@ -305,12 +305,12 @@ class InternetDraft(Document):
#token_name = models.CharField(blank=True, max_length=25)
@property
def token_name(self):
return self.ad.get_name()
return self.ad.name
#token_email = models.CharField(blank=True, max_length=255)
@property
def token_email(self):
return self.ad.address
return self.ad.email_address()
#note = models.TextField(blank=True) # same name
@ -556,7 +556,7 @@ class InternetDraft(Document):
# return remarks
def active_positions(self):
"""Returns a list of dicts, with AD and Position tuples"""
active_ads = Email.objects.filter(role__name="ad", role__group__state="active")
active_ads = Person.objects.filter(email__role__name="ad", email__role__group__state="active")
res = []
def add(ad, pos):
from person.proxy import IESGLogin as IESGLoginProxy
@ -638,7 +638,7 @@ class InternetDraft(Document):
e = self.published_rfc
else:
e = self.latest_event(type="published_rfc")
return e.time.date() if e else None
return e.time.date() if e else datetime.date(1990,1,1)
#current_status = models.CharField(max_length=50,null=True)
@property
@ -782,11 +782,11 @@ class DocumentComment(Event):
def get_absolute_url(self):
return "/doc/%s/" % self.doc.name
def get_author(self):
return self.by.get_name()
return self.by.name
def get_username(self):
return unicode(self.by)
def get_fullname(self):
return self.by.get_name()
return self.by.name
def datetime(self):
return self.time
def __str__(self):

View file

@ -2,7 +2,7 @@
from django.db import models
from redesign.name.models import *
from redesign.person.models import Email
from redesign.person.models import Email, Person
import datetime
@ -35,11 +35,11 @@ class GroupEvent(models.Model):
group = models.ForeignKey(Group)
time = models.DateTimeField(default=datetime.datetime.now, help_text="When the event happened")
type = models.CharField(max_length=50, choices=GROUP_EVENT_CHOICES)
by = models.ForeignKey(Email)
by = models.ForeignKey(Person)
desc = models.TextField()
def __unicode__(self):
return u"%s %s at %s" % (self.by.get_name(), self.get_type_display().lower(), self.time)
return u"%s %s at %s" % (self.by.name, self.get_type_display().lower(), self.time)
class Meta:
ordering = ['-time', 'id']
@ -73,8 +73,8 @@ class GroupHistory(models.Model):
class Role(models.Model):
name = models.ForeignKey(RoleName)
group = models.ForeignKey(Group)
email = models.ForeignKey(Email)
auth = models.CharField(max_length=255, blank=True)
email = models.ForeignKey(Email, help_text="Email address used by person for this role")
auth = models.CharField(max_length=255, blank=True) # unused?
def __unicode__(self):
return u"%s is %s in %s" % (self.email.get_name(), self.name.name, self.group.acronym)

View file

@ -7,6 +7,7 @@ sys.path = [ basedir ] + sys.path
from ietf import settings
settings.USE_DB_REDESIGN_PROXY_CLASSES = False
settings.IMPORTING_ANNOUNCEMENTS = True
from django.core import management
management.setup_environ(settings)
@ -14,7 +15,7 @@ management.setup_environ(settings)
from redesign.person.models import *
from redesign.group.models import *
from redesign.name.utils import name
from redesign.importing.utils import person_email
from redesign.importing.utils import old_person_to_person
from ietf.announcements.models import Message
from ietf.announcements.models import Announcement, PersonOrOrgInfo, AnnouncedTo, AnnouncedFrom
@ -26,7 +27,7 @@ from ietf.announcements.models import Announcement, PersonOrOrgInfo, AnnouncedTo
# FIXME: should import ScheduledAnnouncements
system_email, _ = Email.objects.get_or_create(address="(System)")
system = Person.objects.get(name="(System)")
# Announcement
for o in Announcement.objects.all().select_related('announced_to', 'announced_from').order_by('announcement_id').iterator():
@ -41,12 +42,12 @@ for o in Announcement.objects.all().select_related('announced_to', 'announced_fr
try:
x = o.announced_by
except PersonOrOrgInfo.DoesNotExist:
message.by = system_email
message.by = system
else:
if not o.announced_by.first_name and o.announced_by.last_name == 'None':
message.by = system_email
message.by = system
else:
message.by = Email.objects.get(address=person_email(o.announced_by))
message.by = old_person_to_person(o.announced_by)
message.subject = o.subject.strip()
if o.announced_from_id == 99:

View file

@ -14,7 +14,7 @@ management.setup_environ(settings)
from redesign.doc.models import *
from redesign.group.models import *
from redesign.name.models import *
from redesign.importing.utils import person_email
from redesign.importing.utils import old_person_to_person
from redesign.name.utils import name
from ietf.idtracker.models import InternetDraft, IDInternal, IESGLogin, DocumentComment, PersonOrOrgInfo, Rfc, IESGComment, IESGDiscuss, BallotInfo, Position
from ietf.idrfc.models import RfcIndex, DraftVersions
@ -145,7 +145,7 @@ tag_has_errata = name(DocInfoTagName, 'errata', "Has errata")
# helpers
def save_event(doc, event, comment):
event.time = comment.datetime()
event.by = iesg_login_to_email(comment.created_by)
event.by = iesg_login_to_person(comment.created_by)
event.doc = doc
if not event.desc:
event.desc = comment.comment_text # FIXME: consider unquoting here
@ -159,17 +159,16 @@ def sync_tag(d, include, tag):
buggy_iesg_logins_cache = {}
# make sure system email exists
system_email, _ = Email.objects.get_or_create(address="(System)")
system = Person.objects.get(name="(System)")
def iesg_login_to_email(l):
def iesg_login_to_person(l):
if not l:
return system_email
return system
else:
# there's a bunch of old weird comments made by "IESG
# Member", transform these into "System" instead
if l.id == 2:
return system_email
return system
# fix logins without the right person
if not l.person:
@ -185,19 +184,22 @@ def iesg_login_to_email(l):
else:
buggy_iesg_logins_cache[l.id] = None
l = buggy_iesg_logins_cache[l.id]
if not l:
return system
try:
return Email.objects.get(address=person_email(l.person))
return old_person_to_person(l.person)
except Email.DoesNotExist:
try:
return Email.objects.get(person__name="%s %s" % (l.person.first_name, l.person.last_name))
except Email.DoesNotExist:
print "MISSING IESG LOGIN", l.person.email()
return Person.objects.get(name="%s %s" % (l.person.first_name, l.person.last_name))
except Person.DoesNotExist:
print "MISSING IESG LOGIN", l.person, l.person.email()
return None
def iesg_login_is_secretary(l):
# Amy has two users, for some reason
return l.user_level == IESGLogin.SECRETARIAT_LEVEL or l.first_name == "Amy" and l.last_name == "Vezza"
# Amy has two users, for some reason, we sometimes get the wrong one
return l.user_level == IESGLogin.SECRETARIAT_LEVEL or (l.first_name == "Amy" and l.last_name == "Vezza")
# regexps for parsing document comments
@ -234,10 +236,9 @@ re_comment_discuss_by_tag = re.compile(r" by [\w-]+ [\w-]+$")
def import_from_idinternal(d, idinternal):
d.time = idinternal.event_date
d.iesg_state = iesg_state_mapping[idinternal.cur_state.state]
d.ad = iesg_login_to_email(idinternal.job_owner)
d.ad = iesg_login_to_person(idinternal.job_owner)
d.notify = idinternal.state_change_notice_to or ""
d.note = idinternal.note or ""
d.note = d.note.replace('<br>', '\n').strip().replace('\n', '<br>')
d.note = (idinternal.note or "").replace('<br>', '\n').strip().replace('\n', '<br>')
d.save()
# extract events
@ -267,14 +268,14 @@ def import_from_idinternal(d, idinternal):
save_event(d, e, c)
handled = True
ad = iesg_login_to_email(c.created_by)
ad = iesg_login_to_person(c.created_by)
last_pos = d.latest_event(BallotPositionEvent, type="changed_ballot_position", ad=ad)
if not last_pos and not iesg_login_is_secretary(c.created_by):
# when you issue a ballot, you also vote yes; add that vote
e = BallotPositionEvent()
e.type = "changed_ballot_position"
e.ad = ad
e.desc = "[Ballot Position Update] New position, Yes, has been recorded by %s" % e.ad.get_name()
e.desc = "[Ballot Position Update] New position, Yes, has been recorded by %s" % e.ad.name
e.pos = ballot_position_mapping["Yes"]
e.discuss = last_pos.discuss if last_pos else ""
@ -309,7 +310,7 @@ def import_from_idinternal(d, idinternal):
found = False
for p in positions:
if not d.event_set.filter(type="changed_ballot_position", ballotposition__pos=position, ballotposition__ad=iesg_login_to_email(p.ad)):
if not d.event_set.filter(type="changed_ballot_position", ballotposition__pos=position, ballotposition__ad=iesg_login_to_person(p.ad)):
login = p.ad
found = True
break
@ -335,7 +336,7 @@ def import_from_idinternal(d, idinternal):
e = BallotPositionEvent()
e.type = "changed_ballot_position"
e.ad = iesg_login_to_email(login)
e.ad = iesg_login_to_person(login)
last_pos = d.latest_event(BallotPositionEvent, type="changed_ballot_position", ad=e.ad)
e.pos = position
e.discuss = last_pos.discuss if last_pos else ""
@ -353,7 +354,7 @@ def import_from_idinternal(d, idinternal):
if c.ballot in (DocumentComment.BALLOT_DISCUSS, DocumentComment.BALLOT_COMMENT):
e = BallotPositionEvent()
e.type = "changed_ballot_position"
e.ad = iesg_login_to_email(c.created_by)
e.ad = iesg_login_to_person(c.created_by)
last_pos = d.latest_event(BallotPositionEvent, type="changed_ballot_position", ad=e.ad)
e.pos = last_pos.pos if last_pos else ballot_position_mapping[None]
c.comment_text = re_comment_discuss_by_tag.sub("", c.comment_text)
@ -565,7 +566,7 @@ def import_from_idinternal(d, idinternal):
if idinternal.status_date != status_date:
e = StatusDateEvent(type="changed_status_date", date=idinternal.status_date)
e.time = made_up_date
e.by = system_email
e.by = system
e.doc = d
e.desc = "Status date has been changed to <b>%s</b> from <b>%s</b>" % (idinternal.status_date, status_date)
e.save()
@ -584,7 +585,7 @@ def import_from_idinternal(d, idinternal):
# comments, in that case the time is simply the day after
# the telechat
e.time = telechat_date + datetime.timedelta(days=1) if telechat_date and not idinternal.telechat_date else made_up_date
e.by = system_email
e.by = system
args = ("Placed on", idinternal.telechat_date) if idinternal.telechat_date else ("Removed from", telechat_date)
e.doc = d
e.desc = "%s agenda for telechat - %s by system" % args
@ -611,7 +612,7 @@ def import_from_idinternal(d, idinternal):
if iesg_login_is_secretary(p.ad):
continue
ad = iesg_login_to_email(p.ad)
ad = iesg_login_to_person(p.ad)
if p.noobj > 0:
pos = ballot_position_mapping["No Objection"]
elif p.yes > 0:
@ -636,7 +637,7 @@ def import_from_idinternal(d, idinternal):
e.type = "changed_ballot_position"
e.doc = d
e.time = position_date
e.by = system_email
e.by = system
e.ad = ad
last_pos = d.latest_event(BallotPositionEvent, type="changed_ballot_position", ad=e.ad)
e.pos = pos
@ -649,9 +650,9 @@ def import_from_idinternal(d, idinternal):
e.comment = last_pos.comment if last_pos else ""
e.comment_time = last_pos.comment_time if last_pos else None
if last_pos:
e.desc = "[Ballot Position Update] Position for %s has been changed to %s from %s" % (ad.get_name(), pos.name, last_pos.pos.name)
e.desc = "[Ballot Position Update] Position for %s has been changed to %s from %s" % (ad.name, pos.name, last_pos.pos.name)
else:
e.desc = "[Ballot Position Update] New position, %s, has been recorded for %s" % (pos.name, ad.get_name())
e.desc = "[Ballot Position Update] New position, %s, has been recorded for %s" % (pos.name, ad.name)
e.save()
# make sure we got the ballot issued event
@ -666,14 +667,14 @@ def import_from_idinternal(d, idinternal):
e.type = "sent_ballot_announcement"
e.doc = d
e.time = sent_date
e.by = system_email
e.by = system
e.desc = "Ballot has been issued"
e.save()
# make sure the comments and discusses are updated
positions = list(BallotPositionEvent.objects.filter(doc=d).order_by("-time", '-id'))
for c in IESGComment.objects.filter(ballot=ballot):
ad = iesg_login_to_email(c.ad)
ad = iesg_login_to_person(c.ad)
for p in positions:
if p.ad == ad:
if p.comment != c.text:
@ -683,7 +684,7 @@ def import_from_idinternal(d, idinternal):
break
for c in IESGDiscuss.objects.filter(ballot=ballot):
ad = iesg_login_to_email(c.ad)
ad = iesg_login_to_person(c.ad)
for p in positions:
if p.ad == ad:
if p.discuss != c.text:
@ -701,26 +702,26 @@ def import_from_idinternal(d, idinternal):
text_date = made_up_date
if idinternal.ballot.approval_text:
e, _ = WriteupEvent.objects.get_or_create(type="changed_ballot_approval_text", doc=d)
e, _ = WriteupEvent.objects.get_or_create(type="changed_ballot_approval_text", doc=d,
defaults=dict(by=system))
e.text = idinternal.ballot.approval_text
e.time = text_date
e.by = system_email
e.desc = "Ballot approval text was added"
e.save()
if idinternal.ballot.last_call_text:
e, _ = WriteupEvent.objects.get_or_create(type="changed_last_call_text", doc=d)
e, _ = WriteupEvent.objects.get_or_create(type="changed_last_call_text", doc=d,
defaults=dict(by=system))
e.text = idinternal.ballot.last_call_text
e.time = text_date
e.by = system_email
e.desc = "Last call text was added"
e.save()
if idinternal.ballot.ballot_writeup:
e, _ = WriteupEvent.objects.get_or_create(type="changed_ballot_writeup_text", doc=d)
e, _ = WriteupEvent.objects.get_or_create(type="changed_ballot_writeup_text", doc=d,
defaults=dict(by=system))
e.text = idinternal.ballot.ballot_writeup
e.time = text_date
e.by = system_email
e.desc = "Ballot writeup text was added"
e.save()
@ -728,10 +729,9 @@ def import_from_idinternal(d, idinternal):
if len(ballot_set) > 1:
others = sorted(b.draft.filename for b in ballot_set if b != idinternal)
desc = u"This was part of a ballot set with: %s" % ",".join(others)
e, _ = Event.objects.get_or_create(type="added_comment", doc=d, desc=desc)
e.time = made_up_date
e.by = system_email
e.save()
Event.objects.get_or_create(type="added_comment", doc=d, desc=desc,
defaults=dict(time=made_up_date,
by=system))
# fix tags
sync_tag(d, idinternal.via_rfc_editor, tag_via_rfc_editor)
@ -798,10 +798,11 @@ for index, o in enumerate(all_drafts.iterator()):
if o.rfc_number:
alias_doc("rfc%s" % o.rfc_number, d)
# authors
d.authors.clear()
for i, a in enumerate(o.authors.all().select_related("person").order_by('author_order', 'person')):
try:
e = Email.objects.get(address=a.person.email()[1] or u"unknown-email-%s-%s" % (a.person.first_name, a.person.last_name))
e = Email.objects.get(address__iexact=a.email() or a.person.email()[1] or u"unknown-email-%s-%s" % (a.person.first_name, a.person.last_name))
# renumber since old numbers may be a bit borked
DocumentAuthor.objects.create(document=d, author=e, order=i)
except Email.DoesNotExist:
@ -827,7 +828,7 @@ for index, o in enumerate(all_drafts.iterator()):
# hack the seconds to include the revision to ensure
# they're ordered correctly
e.time = datetime.datetime.combine(v.revision_date, datetime.time(0, 0, 0)) + datetime.timedelta(seconds=int(v.revision))
e.by = system_email
e.by = system
e.doc = d
e.desc = "New version available"
e.save()
@ -844,7 +845,7 @@ for index, o in enumerate(all_drafts.iterator()):
disapproved = o.idinternal and o.idinternal.dnp
e = Event(type="iesg_disapproved" if disapproved else "iesg_approved")
e.time = o.b_approve_date
e.by = system_email
e.by = system
e.doc = d
e.desc = "Do Not Publish note has been sent to RFC Editor" if disapproved else "IESG has approved"
e.save()
@ -856,7 +857,7 @@ for index, o in enumerate(all_drafts.iterator()):
# event time is more accurate with actual time instead of just
# date, gives better sorting
e.time = events[0].time if events else o.lc_sent_date
e.by = events[0].by if events else system_email
e.by = events[0].by if events else system
e.doc = d
e.desc = "Last call sent"
e.save()
@ -956,9 +957,9 @@ for index, o in enumerate(all_rfcs.iterator()):
import_from_idinternal(d, internals[0])
# publication date
e, _ = Event.objects.get_or_create(doc=d, type="published_rfc")
e, _ = Event.objects.get_or_create(doc=d, type="published_rfc",
defaults=dict(by=system))
e.time = o.rfc_published_date
e.by = system_email
e.desc = "RFC published"
e.save()

View file

@ -21,6 +21,8 @@ from ietf.idtracker.models import AreaGroup, IETFWG, Area, AreaGroup, Acronym, A
# also creates nomcom groups
# assumptions: persons have been imported
state_names = dict(
bof=name(GroupStateName, slug="bof", name="BOF"),
proposed=name(GroupStateName, slug="proposed", name="Proposed"),
@ -33,6 +35,7 @@ state_names = dict(
type_names = dict(
ietf=name(GroupTypeName, slug="ietf", name="IETF"),
area=name(GroupTypeName, slug="area", name="Area"),
ag=name(GroupTypeName, slug="ag", name="AG"),
wg=name(GroupTypeName, slug="wg", name="WG"),
rg=name(GroupTypeName, slug="rg", name="RG"),
team=name(GroupTypeName, slug="team", name="Team"),
@ -53,7 +56,14 @@ irtf_group.state = state_names["active"]
irtf_group.type = type_names["ietf"]
irtf_group.save()
system_email, _ = Email.objects.get_or_create(address="(System)")
# create Secretariat for use with roles
secretariat_group, _ = Group.objects.get_or_create(acronym="secretariat")
secretariat_group.name = "IETF Secretariat"
secretariat_group.state = state_names["active"]
secretariat_group.type = type_names["ietf"]
secretariat_group.save()
system = Person.objects.get(name="(System)")
# NomCom
@ -75,13 +85,13 @@ for o in ChairsHistory.objects.filter(chair_type=Role.NOMCOM_CHAIR).order_by("st
# we need start/end year so fudge events
e = GroupEvent(group=group, type="started")
e.time = datetime.datetime(o.start_year, 5, 1, 12, 0, 0)
e.by = system_email
e.by = system
e.desc = e.get_type_display()
e.save()
e = GroupEvent(group=group, type="concluded")
e.time = datetime.datetime(o.end_year, 5, 1, 12, 0, 0)
e.by = system_email
e.by = system
e.desc = e.get_type_display()
e.save()
@ -108,7 +118,7 @@ for o in Area.objects.all():
if o.concluded_date:
e = GroupEvent(group=group, type="concluded")
e.time = datetime.datetime.combine(o.concluded_date, datetime.time(12, 0, 0))
e.by = system_email
e.by = system
e.desc = e.get_type_display()
e.save()
@ -164,15 +174,15 @@ for o in IETFWG.objects.all():
elif o.group_acronym.acronym == "iab":
group.type = type_names["ietf"]
group.parent = None
elif o.group_acronym.acronym in ("tsvdir", "secdir", "saag"):
elif o.group_acronym.acronym in ("tsvdir", "secdir", "saag", "usac"):
group.type = type_names["team"]
elif o.group_acronym.acronym == "iesg":
pass # we already treated iesg
elif o.group_acronym.acronym in ('apparea', 'opsarea', 'rtgarea', 'usvarea', 'genarea', 'tsvarea', 'raiarea'):
pass # we already treated areas
elif o.group_acronym.acronym in ("apparea", "opsarea", "rtgarea", "usvarea", "genarea", "tsvarea", "raiarea", "apptsv"):
group.type = type_names["ag"]
else:
# the remaining groups are
# apptsv, apples, usac, null, dirdir
# apples, null, dirdir
# for now, we don't transfer them
if group.id:
group.delete()
@ -200,7 +210,7 @@ for o in IETFWG.objects.all():
if d:
e = GroupEvent(group=group, type=name)
e.time = datetime.datetime.combine(d, datetime.time(12, 0, 0))
e.by = system_email
e.by = system
e.desc = e.get_type_display()
e.save()

View file

@ -0,0 +1,44 @@
#!/usr/bin/python
import sys, os, re, datetime
basedir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../.."))
sys.path = [ basedir ] + sys.path
from ietf import settings
settings.USE_DB_REDESIGN_PROXY_CLASSES = False
from django.core import management
management.setup_environ(settings)
from redesign.person.models import *
# creates system person and email
# should probably also import the old person/email tables
try:
system_person = Person.objects.get(name="(System)")
except Person.DoesNotExist:
system_person = Person.objects.create(
id=0, # special value
name="(System)",
ascii="(System)",
address="",
)
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
)
system_email = Email.objects.get_or_create(
address="",
person=system_person,
active=True
)

View file

@ -1,7 +1,6 @@
#!/usr/bin/python
import sys, os, re, datetime
import unaccent
basedir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../.."))
sys.path = [ basedir ] + sys.path
@ -12,11 +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 person_email
from redesign.importing.utils import old_person_to_email, clean_email_address
from ietf.idtracker.models import IESGLogin, AreaDirector, IDAuthor, PersonOrOrgInfo, WGChair, WGEditor, WGSecretary, WGTechAdvisor, ChairsHistory, Role as OldRole, Acronym, IRTFChair
@ -43,7 +43,7 @@ techadvisor_role = name(RoleName, "techadv", "Tech Advisor")
# helpers for creating the objects
def get_or_create_email(o, create_fake):
email = person_email(o.person)
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)
@ -62,6 +62,7 @@ def get_or_create_email(o, create_fake):
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)
@ -162,14 +163,22 @@ for o in IESGLogin.objects.all():
continue
email = get_or_create_email(o, create_fake=False)
if not email:
continue
if o.user_level == IESGLogin.INACTIVE_AD_LEVEL:
user, _ = User.objects.get_or_create(username=o.login_name)
email.person.user = user
email.person.save()
# current ADs are imported below
if o.user_level == IESGLogin.SECRETARIAT_LEVEL:
if not Role.objects.filter(name=secretary_role, email=email):
Role.objects.create(name=secretary_role, group=Group.objects.get(acronym="secretariat"), email=email)
elif o.user_level == IESGLogin.INACTIVE_AD_LEVEL:
if not Role.objects.filter(name=inactive_area_director_role, email=email):
# connect them directly to the IESG as we don't really know where they belong
Role.objects.create(name=inactive_area_director_role, group=Group.objects.get(acronym="iesg"), email=email)
# FIXME: import o.login_name, o.user_level
# AreaDirector
for o in AreaDirector.objects.all():
if not o.area:
@ -206,7 +215,20 @@ for o in PersonOrOrgInfo.objects.filter(announcement__announcement_id__gte=1).di
email = get_or_create_email(o, create_fake=False)
# IDAuthor persons
for o in IDAuthor.objects.all().order_by('id').select_related('person'):
for o in IDAuthor.objects.all().order_by('id').select_related('person').iterator():
print "importing IDAuthor", o.id, o.person_id, o.person.first_name.encode('utf-8'), o.person.last_name.encode('utf-8')
email = get_or_create_email(o, create_fake=True)
# we may also need to import email address used specifically for
# the document
addr = clean_email_address(o.email() or "")
if addr and addr.lower() != email.address.lower():
try:
e = Email.objects.get(address=addr)
if e.person != email.person or e.active != False:
e.person = email.person
e.active = False
e.save()
except Email.DoesNotExist:
Email.objects.create(address=addr, person=email.person, active=False)

View file

@ -1,5 +1,17 @@
def person_email(person):
from person.models import Person
def clean_email_address(addr):
addr = addr.replace("<", "").replace(">", "").replace("!", "@").replace("(at)", "@").strip()
if not "@" in addr:
return ""
else:
return addr
def old_person_to_person(person):
return Person.objects.get(id=person.pk)
def old_person_to_email(person):
hardcoded_emails = { 'Dinara Suleymanova': "dinaras@ietf.org" }
return person.email()[1] or hardcoded_emails.get("%s %s" % (person.first_name, person.last_name))
return clean_email_address(person.email()[1] or hardcoded_emails.get("%s %s" % (person.first_name, person.last_name)) or "")

View file

@ -20,7 +20,7 @@ class AliasInline(admin.StackedInline):
model = Alias
class PersonAdmin(admin.ModelAdmin):
list_display = ["name", "short", "time", ]
list_display = ["name", "short", "time", "user", ]
search_fields = ["name", "ascii"]
inlines = [ EmailInline, AliasInline, ]
# actions = None

View file

@ -1,14 +1,18 @@
# Copyright The IETF Trust 2007, All Rights Reserved
from django.db import models
from django.contrib.auth.models import User
class Person(models.Model):
time = models.DateTimeField(auto_now_add=True) # When this Person record entered the system
name = models.CharField(max_length=255) # The normal unicode form of the name. This must be
name = models.CharField(max_length=255, db_index=True) # The normal unicode form of the name. This must be
# set to the same value as the ascii-form if equal.
ascii = models.CharField(max_length=255) # The normal ascii-form of the name.
ascii_short = models.CharField(max_length=32, null=True, blank=True) # The short ascii-form of the name. Also in alias table if non-null
address = models.TextField(max_length=255, blank=True)
user = models.OneToOneField(User, blank=True, null=True)
def __unicode__(self):
return self.name
def _parts(self, name):
@ -40,6 +44,23 @@ 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 email_address(self):
e = self.email_set.filter(active=True)
if e:
return e[0]
else:
return ""
def formatted_email(self):
e = self.email_set.order_by("-active")
if e:
return e[0].formatted_email()
else:
return ""
def person(self): # little temporary wrapper to help porting
return self
def full_name_as_key(self):
return self.name.lower().replace(" ", ".")
class Alias(models.Model):
"""This is used for alternative forms of a name. This is the
@ -48,7 +69,7 @@ class Alias(models.Model):
recorded in the Person record.
"""
person = models.ForeignKey(Person)
name = models.CharField(max_length=255)
name = models.CharField(max_length=255, db_index=True)
def __unicode__(self):
return self.name
class Meta:

View file

@ -1,6 +1,12 @@
from redesign.proxy_utils import TranslatingManager
from models import *
class IESGLogin(Email):
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))
@ -10,9 +16,6 @@ class IESGLogin(Email):
AD_LEVEL = 1
INACTIVE_AD_LEVEL = 2
@property
def id(self):
return self.pk # this is not really backwards-compatible
#login_name = models.CharField(blank=True, max_length=255)
@property
def login_name(self): raise NotImplemented
@ -26,12 +29,12 @@ class IESGLogin(Email):
#first_name = models.CharField(blank=True, max_length=25)
@property
def first_name(self):
return self.get_name().split(" ")[0]
return self.name_parts()[1]
#last_name = models.CharField(blank=True, max_length=25)
@property
def last_name(self):
return self.get_name().split(" ")[-1]
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)
@ -41,15 +44,14 @@ class IESGLogin(Email):
#default_search = models.NullBooleanField()
def __str__(self):
return self.get_name()
return self.name
def __unicode__(self):
return self.get_name()
return self.name
def is_current_ad(self):
return self in Email.objects.filter(role__name="ad", role__group__state="active")
return self in Person.objects.filter(email__role__name="ad", email__role__group__state="active").distinct()
@staticmethod
def active_iesg():
raise NotImplemented
#return IESGLogin.objects.filter(user_level=1,id__gt=1).order_by('last_name')
return IESGLogin.objects.filter(email__role__name="ad", email__role__group__state="active").distinct().order_by('name')
class Meta:
proxy = True