Changed all usage of ForeignKey and OneToOneFiled in model.py files to the compatibility versions from ietf.utils.models.
- Legacy-Id: 14661
This commit is contained in:
parent
c760792339
commit
5638cf3da3
|
@ -6,10 +6,11 @@ from django.urls import reverse as urlreverse
|
||||||
from ietf.doc.models import Document, DocEvent, State
|
from ietf.doc.models import Document, DocEvent, State
|
||||||
from ietf.group.models import Group
|
from ietf.group.models import Group
|
||||||
from ietf.person.models import Person, Email
|
from ietf.person.models import Person, Email
|
||||||
|
from ietf.utils.models import ForeignKey, OneToOneField
|
||||||
|
|
||||||
class CommunityList(models.Model):
|
class CommunityList(models.Model):
|
||||||
user = models.ForeignKey(User, blank=True, null=True)
|
user = ForeignKey(User, blank=True, null=True)
|
||||||
group = models.ForeignKey(Group, blank=True, null=True)
|
group = ForeignKey(Group, blank=True, null=True)
|
||||||
added_docs = models.ManyToManyField(Document)
|
added_docs = models.ManyToManyField(Document)
|
||||||
|
|
||||||
def long_name(self):
|
def long_name(self):
|
||||||
|
@ -59,13 +60,13 @@ class SearchRule(models.Model):
|
||||||
('name_contains', 'All I-Ds with particular text/regular expression in the name'),
|
('name_contains', 'All I-Ds with particular text/regular expression in the name'),
|
||||||
]
|
]
|
||||||
|
|
||||||
community_list = models.ForeignKey(CommunityList)
|
community_list = ForeignKey(CommunityList)
|
||||||
rule_type = models.CharField(max_length=30, choices=RULE_TYPES)
|
rule_type = models.CharField(max_length=30, choices=RULE_TYPES)
|
||||||
|
|
||||||
# these are filled in depending on the type
|
# these are filled in depending on the type
|
||||||
state = models.ForeignKey(State, blank=True, null=True)
|
state = ForeignKey(State, blank=True, null=True)
|
||||||
group = models.ForeignKey(Group, blank=True, null=True)
|
group = ForeignKey(Group, blank=True, null=True)
|
||||||
person = models.ForeignKey(Person, blank=True, null=True)
|
person = ForeignKey(Person, blank=True, null=True)
|
||||||
text = models.CharField(verbose_name="Text/RegExp", max_length=255, blank=True, default="")
|
text = models.CharField(verbose_name="Text/RegExp", max_length=255, blank=True, default="")
|
||||||
|
|
||||||
# store a materialized view/index over which documents are matched
|
# store a materialized view/index over which documents are matched
|
||||||
|
@ -78,8 +79,8 @@ class SearchRule(models.Model):
|
||||||
return "%s %s %s/%s/%s/%s" % (self.community_list, self.rule_type, self.state, self.group, self.person, self.text)
|
return "%s %s %s/%s/%s/%s" % (self.community_list, self.rule_type, self.state, self.group, self.person, self.text)
|
||||||
|
|
||||||
class EmailSubscription(models.Model):
|
class EmailSubscription(models.Model):
|
||||||
community_list = models.ForeignKey(CommunityList)
|
community_list = ForeignKey(CommunityList)
|
||||||
email = models.ForeignKey(Email)
|
email = ForeignKey(Email)
|
||||||
|
|
||||||
NOTIFICATION_CHOICES = [
|
NOTIFICATION_CHOICES = [
|
||||||
("all", "All changes"),
|
("all", "All changes"),
|
||||||
|
|
|
@ -2,6 +2,7 @@ from django.db import models
|
||||||
|
|
||||||
from ietf.group.models import Group
|
from ietf.group.models import Group
|
||||||
from ietf.name.models import DBTemplateTypeName
|
from ietf.name.models import DBTemplateTypeName
|
||||||
|
from ietf.utils.models import ForeignKey, OneToOneField
|
||||||
|
|
||||||
|
|
||||||
TEMPLATE_TYPES = (
|
TEMPLATE_TYPES = (
|
||||||
|
@ -15,9 +16,9 @@ class DBTemplate(models.Model):
|
||||||
path = models.CharField( max_length=255, unique=True, blank=False, null=False, )
|
path = models.CharField( max_length=255, unique=True, blank=False, null=False, )
|
||||||
title = models.CharField( max_length=255, blank=False, null=False, )
|
title = models.CharField( max_length=255, blank=False, null=False, )
|
||||||
variables = models.TextField( blank=True, null=True, )
|
variables = models.TextField( blank=True, null=True, )
|
||||||
type = models.ForeignKey( DBTemplateTypeName, )
|
type = ForeignKey( DBTemplateTypeName, )
|
||||||
content = models.TextField( blank=False, null=False, )
|
content = models.TextField( blank=False, null=False, )
|
||||||
group = models.ForeignKey( Group, blank=True, null=True, )
|
group = ForeignKey( Group, blank=True, null=True, )
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.title
|
return self.title
|
||||||
|
|
|
@ -27,6 +27,7 @@ from ietf.utils import log
|
||||||
from ietf.utils.admin import admin_link
|
from ietf.utils.admin import admin_link
|
||||||
from ietf.utils.validators import validate_no_control_chars
|
from ietf.utils.validators import validate_no_control_chars
|
||||||
from ietf.utils.mail import formataddr
|
from ietf.utils.mail import formataddr
|
||||||
|
from ietf.utils.models import ForeignKey, OneToOneField
|
||||||
|
|
||||||
logger = logging.getLogger('django')
|
logger = logging.getLogger('django')
|
||||||
|
|
||||||
|
@ -52,7 +53,7 @@ def check_statetype_slugs(app_configs, **kwargs):
|
||||||
return errors
|
return errors
|
||||||
|
|
||||||
class State(models.Model):
|
class State(models.Model):
|
||||||
type = models.ForeignKey(StateType)
|
type = ForeignKey(StateType)
|
||||||
slug = models.SlugField()
|
slug = models.SlugField()
|
||||||
name = models.CharField(max_length=255)
|
name = models.CharField(max_length=255)
|
||||||
used = models.BooleanField(default=True)
|
used = models.BooleanField(default=True)
|
||||||
|
@ -74,13 +75,13 @@ class DocumentInfo(models.Model):
|
||||||
"""Any kind of document. Draft, RFC, Charter, IPR Statement, Liaison Statement"""
|
"""Any kind of document. Draft, RFC, Charter, IPR Statement, Liaison Statement"""
|
||||||
time = models.DateTimeField(default=datetime.datetime.now) # should probably have auto_now=True
|
time = models.DateTimeField(default=datetime.datetime.now) # should probably have auto_now=True
|
||||||
|
|
||||||
type = models.ForeignKey(DocTypeName, blank=True, null=True) # Draft, Agenda, Minutes, Charter, Discuss, Guideline, Email, Review, Issue, Wiki, External ...
|
type = ForeignKey(DocTypeName, blank=True, null=True) # Draft, Agenda, Minutes, Charter, Discuss, Guideline, Email, Review, Issue, Wiki, External ...
|
||||||
title = models.CharField(max_length=255, validators=[validate_no_control_chars, ])
|
title = models.CharField(max_length=255, validators=[validate_no_control_chars, ])
|
||||||
|
|
||||||
states = models.ManyToManyField(State, blank=True) # plain state (Active/Expired/...), IESG state, stream state
|
states = models.ManyToManyField(State, blank=True) # plain state (Active/Expired/...), IESG state, stream state
|
||||||
tags = models.ManyToManyField(DocTagName, blank=True) # Revised ID Needed, ExternalParty, AD Followup, ...
|
tags = models.ManyToManyField(DocTagName, blank=True) # Revised ID Needed, ExternalParty, AD Followup, ...
|
||||||
stream = models.ForeignKey(StreamName, blank=True, null=True) # IETF, IAB, IRTF, Independent Submission
|
stream = ForeignKey(StreamName, blank=True, null=True) # IETF, IAB, IRTF, Independent Submission
|
||||||
group = models.ForeignKey(Group, blank=True, null=True) # WG, RG, IAB, IESG, Edu, Tools
|
group = ForeignKey(Group, blank=True, null=True) # WG, RG, IAB, IESG, Edu, Tools
|
||||||
|
|
||||||
abstract = models.TextField(blank=True)
|
abstract = models.TextField(blank=True)
|
||||||
rev = models.CharField(verbose_name="revision", max_length=16, blank=True)
|
rev = models.CharField(verbose_name="revision", max_length=16, blank=True)
|
||||||
|
@ -88,10 +89,10 @@ class DocumentInfo(models.Model):
|
||||||
words = models.IntegerField(blank=True, null=True)
|
words = models.IntegerField(blank=True, null=True)
|
||||||
formal_languages = models.ManyToManyField(FormalLanguageName, blank=True, help_text="Formal languages used in document")
|
formal_languages = models.ManyToManyField(FormalLanguageName, blank=True, help_text="Formal languages used in document")
|
||||||
order = models.IntegerField(default=1, blank=True) # This is probably obviated by SessionPresentaion.order
|
order = models.IntegerField(default=1, blank=True) # This is probably obviated by SessionPresentaion.order
|
||||||
intended_std_level = models.ForeignKey(IntendedStdLevelName, verbose_name="Intended standardization level", blank=True, null=True)
|
intended_std_level = ForeignKey(IntendedStdLevelName, verbose_name="Intended standardization level", blank=True, null=True)
|
||||||
std_level = models.ForeignKey(StdLevelName, verbose_name="Standardization level", blank=True, null=True)
|
std_level = ForeignKey(StdLevelName, verbose_name="Standardization level", blank=True, null=True)
|
||||||
ad = models.ForeignKey(Person, verbose_name="area director", related_name='ad_%(class)s_set', blank=True, null=True)
|
ad = ForeignKey(Person, 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)
|
shepherd = ForeignKey(Email, related_name='shepherd_%(class)s_set', blank=True, null=True)
|
||||||
expires = models.DateTimeField(blank=True, null=True)
|
expires = models.DateTimeField(blank=True, null=True)
|
||||||
notify = models.CharField(max_length=255, blank=True)
|
notify = models.CharField(max_length=255, blank=True)
|
||||||
external_url = models.URLField(blank=True) # Should be set for documents with type 'External'.
|
external_url = models.URLField(blank=True) # Should be set for documents with type 'External'.
|
||||||
|
@ -482,9 +483,9 @@ class DocumentInfo(models.Model):
|
||||||
STATUSCHANGE_RELATIONS = ('tops','tois','tohist','toinf','tobcp','toexp')
|
STATUSCHANGE_RELATIONS = ('tops','tois','tohist','toinf','tobcp','toexp')
|
||||||
|
|
||||||
class RelatedDocument(models.Model):
|
class RelatedDocument(models.Model):
|
||||||
source = models.ForeignKey('Document')
|
source = ForeignKey('Document')
|
||||||
target = models.ForeignKey('DocAlias')
|
target = ForeignKey('DocAlias')
|
||||||
relationship = models.ForeignKey(DocRelationshipName)
|
relationship = ForeignKey(DocRelationshipName)
|
||||||
def action(self):
|
def action(self):
|
||||||
return self.relationship.name
|
return self.relationship.name
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
|
@ -536,9 +537,9 @@ class RelatedDocument(models.Model):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
class DocumentAuthorInfo(models.Model):
|
class DocumentAuthorInfo(models.Model):
|
||||||
person = models.ForeignKey(Person)
|
person = ForeignKey(Person)
|
||||||
# email should only be null for some historic documents
|
# email should only be null for some historic documents
|
||||||
email = models.ForeignKey(Email, help_text="Email address used by author for submission", blank=True, null=True)
|
email = ForeignKey(Email, help_text="Email address used by author for submission", blank=True, null=True)
|
||||||
affiliation = models.CharField(max_length=100, blank=True, help_text="Organization/company used by author for submission")
|
affiliation = models.CharField(max_length=100, blank=True, help_text="Organization/company used by author for submission")
|
||||||
country = models.CharField(max_length=255, blank=True, help_text="Country used by author for submission")
|
country = models.CharField(max_length=255, blank=True, help_text="Country used by author for submission")
|
||||||
order = models.IntegerField(default=1)
|
order = models.IntegerField(default=1)
|
||||||
|
@ -555,7 +556,7 @@ class DocumentAuthorInfo(models.Model):
|
||||||
ordering = ["document", "order"]
|
ordering = ["document", "order"]
|
||||||
|
|
||||||
class DocumentAuthor(DocumentAuthorInfo):
|
class DocumentAuthor(DocumentAuthorInfo):
|
||||||
document = models.ForeignKey('Document')
|
document = ForeignKey('Document')
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u"%s %s (%s)" % (self.document.name, self.person, self.order)
|
return u"%s %s (%s)" % (self.document.name, self.person, self.order)
|
||||||
|
@ -807,28 +808,28 @@ class Document(DocumentInfo):
|
||||||
|
|
||||||
|
|
||||||
class DocumentURL(models.Model):
|
class DocumentURL(models.Model):
|
||||||
doc = models.ForeignKey(Document)
|
doc = ForeignKey(Document)
|
||||||
tag = models.ForeignKey(DocUrlTagName)
|
tag = ForeignKey(DocUrlTagName)
|
||||||
desc = models.CharField(max_length=255, default='', blank=True)
|
desc = models.CharField(max_length=255, default='', blank=True)
|
||||||
url = models.URLField(max_length=512)
|
url = models.URLField(max_length=512)
|
||||||
|
|
||||||
class RelatedDocHistory(models.Model):
|
class RelatedDocHistory(models.Model):
|
||||||
source = models.ForeignKey('DocHistory')
|
source = ForeignKey('DocHistory')
|
||||||
target = models.ForeignKey('DocAlias', related_name="reversely_related_document_history_set")
|
target = ForeignKey('DocAlias', related_name="reversely_related_document_history_set")
|
||||||
relationship = models.ForeignKey(DocRelationshipName)
|
relationship = ForeignKey(DocRelationshipName)
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u"%s %s %s" % (self.source.doc.name, self.relationship.name.lower(), self.target.name)
|
return u"%s %s %s" % (self.source.doc.name, self.relationship.name.lower(), self.target.name)
|
||||||
|
|
||||||
class DocHistoryAuthor(DocumentAuthorInfo):
|
class DocHistoryAuthor(DocumentAuthorInfo):
|
||||||
# use same naming convention as non-history version to make it a bit
|
# use same naming convention as non-history version to make it a bit
|
||||||
# easier to write generic code
|
# easier to write generic code
|
||||||
document = models.ForeignKey('DocHistory', related_name="documentauthor_set")
|
document = ForeignKey('DocHistory', related_name="documentauthor_set")
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u"%s %s (%s)" % (self.document.doc.name, self.person, self.order)
|
return u"%s %s (%s)" % (self.document.doc.name, self.person, self.order)
|
||||||
|
|
||||||
class DocHistory(DocumentInfo):
|
class DocHistory(DocumentInfo):
|
||||||
doc = models.ForeignKey(Document, related_name="history_set")
|
doc = ForeignKey(Document, related_name="history_set")
|
||||||
# the name here is used to capture the canonical name at the time
|
# the name here is used to capture the canonical name at the time
|
||||||
# - it would perhaps be more elegant to simply call the attribute
|
# - it would perhaps be more elegant to simply call the attribute
|
||||||
# canonical_name and replace the function on Document with a
|
# canonical_name and replace the function on Document with a
|
||||||
|
@ -878,7 +879,7 @@ class DocAlias(models.Model):
|
||||||
to by RFC number, primarily, after achieving RFC status.
|
to by RFC number, primarily, after achieving RFC status.
|
||||||
"""
|
"""
|
||||||
name = models.CharField(max_length=255, primary_key=True)
|
name = models.CharField(max_length=255, primary_key=True)
|
||||||
document = models.ForeignKey(Document)
|
document = ForeignKey(Document)
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return "%s-->%s" % (self.name, self.document.name)
|
return "%s-->%s" % (self.name, self.document.name)
|
||||||
document_link = admin_link("document")
|
document_link = admin_link("document")
|
||||||
|
@ -887,8 +888,8 @@ class DocAlias(models.Model):
|
||||||
verbose_name_plural = "document aliases"
|
verbose_name_plural = "document aliases"
|
||||||
|
|
||||||
class DocReminder(models.Model):
|
class DocReminder(models.Model):
|
||||||
event = models.ForeignKey('DocEvent')
|
event = ForeignKey('DocEvent')
|
||||||
type = models.ForeignKey(DocReminderTypeName)
|
type = ForeignKey(DocReminderTypeName)
|
||||||
due = models.DateTimeField()
|
due = models.DateTimeField()
|
||||||
active = models.BooleanField(default=True)
|
active = models.BooleanField(default=True)
|
||||||
|
|
||||||
|
@ -972,8 +973,8 @@ class DocEvent(models.Model):
|
||||||
"""An occurrence for a document, used for tracking who, when and what."""
|
"""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", db_index=True)
|
time = models.DateTimeField(default=datetime.datetime.now, help_text="When the event happened", db_index=True)
|
||||||
type = models.CharField(max_length=50, choices=EVENT_TYPES)
|
type = models.CharField(max_length=50, choices=EVENT_TYPES)
|
||||||
by = models.ForeignKey(Person)
|
by = ForeignKey(Person)
|
||||||
doc = models.ForeignKey('doc.Document')
|
doc = ForeignKey('doc.Document')
|
||||||
rev = models.CharField(verbose_name="revision", max_length=16, null=True, blank=True)
|
rev = models.CharField(verbose_name="revision", max_length=16, null=True, blank=True)
|
||||||
desc = models.TextField()
|
desc = models.TextField()
|
||||||
|
|
||||||
|
@ -998,15 +999,15 @@ class NewRevisionDocEvent(DocEvent):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class StateDocEvent(DocEvent):
|
class StateDocEvent(DocEvent):
|
||||||
state_type = models.ForeignKey(StateType)
|
state_type = ForeignKey(StateType)
|
||||||
state = models.ForeignKey(State, blank=True, null=True)
|
state = ForeignKey(State, blank=True, null=True)
|
||||||
|
|
||||||
class ConsensusDocEvent(DocEvent):
|
class ConsensusDocEvent(DocEvent):
|
||||||
consensus = models.NullBooleanField(default=None)
|
consensus = models.NullBooleanField(default=None)
|
||||||
|
|
||||||
# IESG events
|
# IESG events
|
||||||
class BallotType(models.Model):
|
class BallotType(models.Model):
|
||||||
doc_type = models.ForeignKey(DocTypeName, blank=True, null=True)
|
doc_type = ForeignKey(DocTypeName, blank=True, null=True)
|
||||||
slug = models.SlugField()
|
slug = models.SlugField()
|
||||||
name = models.CharField(max_length=255)
|
name = models.CharField(max_length=255)
|
||||||
question = models.TextField(blank=True)
|
question = models.TextField(blank=True)
|
||||||
|
@ -1021,7 +1022,7 @@ class BallotType(models.Model):
|
||||||
ordering = ['order']
|
ordering = ['order']
|
||||||
|
|
||||||
class BallotDocEvent(DocEvent):
|
class BallotDocEvent(DocEvent):
|
||||||
ballot_type = models.ForeignKey(BallotType)
|
ballot_type = ForeignKey(BallotType)
|
||||||
|
|
||||||
def active_ad_positions(self):
|
def active_ad_positions(self):
|
||||||
"""Return dict mapping each active AD to a current ballot position (or None if they haven't voted)."""
|
"""Return dict mapping each active AD to a current ballot position (or None if they haven't voted)."""
|
||||||
|
@ -1083,9 +1084,9 @@ class BallotDocEvent(DocEvent):
|
||||||
return positions
|
return positions
|
||||||
|
|
||||||
class BallotPositionDocEvent(DocEvent):
|
class BallotPositionDocEvent(DocEvent):
|
||||||
ballot = models.ForeignKey(BallotDocEvent, null=True, default=None) # default=None is a temporary migration period fix, should be removed when charter branch is live
|
ballot = ForeignKey(BallotDocEvent, null=True, default=None) # default=None is a temporary migration period fix, should be removed when charter branch is live
|
||||||
ad = models.ForeignKey(Person)
|
ad = ForeignKey(Person)
|
||||||
pos = models.ForeignKey(BallotPositionName, verbose_name="position", default="norecord")
|
pos = ForeignKey(BallotPositionName, verbose_name="position", default="norecord")
|
||||||
discuss = models.TextField(help_text="Discuss text if position is discuss", blank=True)
|
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)
|
discuss_time = models.DateTimeField(help_text="Time discuss text was written", blank=True, null=True)
|
||||||
comment = models.TextField(help_text="Optional comment", blank=True)
|
comment = models.TextField(help_text="Optional comment", blank=True)
|
||||||
|
@ -1102,8 +1103,8 @@ class TelechatDocEvent(DocEvent):
|
||||||
returning_item = models.BooleanField(default=False)
|
returning_item = models.BooleanField(default=False)
|
||||||
|
|
||||||
class ReviewRequestDocEvent(DocEvent):
|
class ReviewRequestDocEvent(DocEvent):
|
||||||
review_request = models.ForeignKey('review.ReviewRequest')
|
review_request = ForeignKey('review.ReviewRequest')
|
||||||
state = models.ForeignKey(ReviewRequestStateName, blank=True, null=True)
|
state = ForeignKey(ReviewRequestStateName, blank=True, null=True)
|
||||||
|
|
||||||
# charter events
|
# charter events
|
||||||
class InitialReviewDocEvent(DocEvent):
|
class InitialReviewDocEvent(DocEvent):
|
||||||
|
@ -1111,20 +1112,20 @@ class InitialReviewDocEvent(DocEvent):
|
||||||
|
|
||||||
class AddedMessageEvent(DocEvent):
|
class AddedMessageEvent(DocEvent):
|
||||||
import ietf.message.models
|
import ietf.message.models
|
||||||
message = models.ForeignKey(ietf.message.models.Message, null=True, blank=True,related_name='doc_manualevents')
|
message = ForeignKey(ietf.message.models.Message, null=True, blank=True,related_name='doc_manualevents')
|
||||||
msgtype = models.CharField(max_length=25)
|
msgtype = models.CharField(max_length=25)
|
||||||
in_reply_to = models.ForeignKey(ietf.message.models.Message, null=True, blank=True,related_name='doc_irtomanual')
|
in_reply_to = ForeignKey(ietf.message.models.Message, null=True, blank=True,related_name='doc_irtomanual')
|
||||||
|
|
||||||
|
|
||||||
class SubmissionDocEvent(DocEvent):
|
class SubmissionDocEvent(DocEvent):
|
||||||
import ietf.submit.models
|
import ietf.submit.models
|
||||||
submission = models.ForeignKey(ietf.submit.models.Submission)
|
submission = ForeignKey(ietf.submit.models.Submission)
|
||||||
|
|
||||||
# dumping store for removed events
|
# dumping store for removed events
|
||||||
class DeletedEvent(models.Model):
|
class DeletedEvent(models.Model):
|
||||||
content_type = models.ForeignKey(ContentType)
|
content_type = ForeignKey(ContentType)
|
||||||
json = models.TextField(help_text="Deleted object in JSON format, with attribute names chosen to be suitable for passing into the relevant create method.")
|
json = models.TextField(help_text="Deleted object in JSON format, with attribute names chosen to be suitable for passing into the relevant create method.")
|
||||||
by = models.ForeignKey(Person)
|
by = ForeignKey(Person)
|
||||||
time = models.DateTimeField(default=datetime.datetime.now)
|
time = models.DateTimeField(default=datetime.datetime.now)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.core.urlresolvers import reverse as urlreverse
|
from django.urls import reverse as urlreverse
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
|
|
||||||
|
|
|
@ -15,14 +15,15 @@ from ietf.name.models import GroupStateName, GroupTypeName, DocTagName, GroupMil
|
||||||
from ietf.person.models import Email, Person
|
from ietf.person.models import Email, Person
|
||||||
from ietf.utils.mail import formataddr
|
from ietf.utils.mail import formataddr
|
||||||
from ietf.utils import log
|
from ietf.utils import log
|
||||||
|
from ietf.utils.models import ForeignKey, OneToOneField
|
||||||
|
|
||||||
|
|
||||||
class GroupInfo(models.Model):
|
class GroupInfo(models.Model):
|
||||||
time = models.DateTimeField(default=datetime.datetime.now)
|
time = models.DateTimeField(default=datetime.datetime.now)
|
||||||
name = models.CharField(max_length=80)
|
name = models.CharField(max_length=80)
|
||||||
state = models.ForeignKey(GroupStateName, null=True)
|
state = ForeignKey(GroupStateName, null=True)
|
||||||
type = models.ForeignKey(GroupTypeName, null=True)
|
type = ForeignKey(GroupTypeName, null=True)
|
||||||
parent = models.ForeignKey('Group', blank=True, null=True)
|
parent = ForeignKey('Group', blank=True, null=True)
|
||||||
description = models.TextField(blank=True)
|
description = models.TextField(blank=True)
|
||||||
list_email = models.CharField(max_length=64, blank=True)
|
list_email = models.CharField(max_length=64, blank=True)
|
||||||
list_subscribe = models.CharField(max_length=255, blank=True)
|
list_subscribe = models.CharField(max_length=255, blank=True)
|
||||||
|
@ -76,7 +77,7 @@ class Group(GroupInfo):
|
||||||
objects = GroupManager()
|
objects = GroupManager()
|
||||||
|
|
||||||
acronym = models.SlugField(max_length=40, unique=True, db_index=True)
|
acronym = models.SlugField(max_length=40, unique=True, db_index=True)
|
||||||
charter = models.OneToOneField('doc.Document', related_name='chartered_group', blank=True, null=True)
|
charter = OneToOneField('doc.Document', related_name='chartered_group', blank=True, null=True)
|
||||||
|
|
||||||
def latest_event(self, *args, **filter_args):
|
def latest_event(self, *args, **filter_args):
|
||||||
"""Get latest event of optional Python type and with filter
|
"""Get latest event of optional Python type and with filter
|
||||||
|
@ -193,14 +194,14 @@ class Group(GroupInfo):
|
||||||
return desc
|
return desc
|
||||||
|
|
||||||
class GroupHistory(GroupInfo):
|
class GroupHistory(GroupInfo):
|
||||||
group = models.ForeignKey(Group, related_name='history_set')
|
group = ForeignKey(Group, related_name='history_set')
|
||||||
acronym = models.CharField(max_length=40)
|
acronym = models.CharField(max_length=40)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name_plural="group histories"
|
verbose_name_plural="group histories"
|
||||||
|
|
||||||
class GroupURL(models.Model):
|
class GroupURL(models.Model):
|
||||||
group = models.ForeignKey(Group)
|
group = ForeignKey(Group)
|
||||||
name = models.CharField(max_length=255)
|
name = models.CharField(max_length=255)
|
||||||
url = models.URLField()
|
url = models.URLField()
|
||||||
|
|
||||||
|
@ -208,12 +209,12 @@ class GroupURL(models.Model):
|
||||||
return u"%s (%s)" % (self.url, self.name)
|
return u"%s (%s)" % (self.url, self.name)
|
||||||
|
|
||||||
class GroupMilestoneInfo(models.Model):
|
class GroupMilestoneInfo(models.Model):
|
||||||
group = models.ForeignKey(Group)
|
group = ForeignKey(Group)
|
||||||
# a group has two sets of milestones, current milestones
|
# a group has two sets of milestones, current milestones
|
||||||
# (active/under review/deleted) and charter milestones (active
|
# (active/under review/deleted) and charter milestones (active
|
||||||
# during a charter/recharter event), events for charter milestones
|
# during a charter/recharter event), events for charter milestones
|
||||||
# are stored on the charter document
|
# are stored on the charter document
|
||||||
state = models.ForeignKey(GroupMilestoneStateName)
|
state = ForeignKey(GroupMilestoneStateName)
|
||||||
desc = models.CharField(verbose_name="Description", max_length=500)
|
desc = models.CharField(verbose_name="Description", max_length=500)
|
||||||
due = models.DateField()
|
due = models.DateField()
|
||||||
resolved = models.CharField(max_length=50, blank=True, help_text="Explanation of why milestone is resolved (usually \"Done\"), or empty if still due.")
|
resolved = models.CharField(max_length=50, blank=True, help_text="Explanation of why milestone is resolved (usually \"Done\"), or empty if still due.")
|
||||||
|
@ -231,13 +232,13 @@ class GroupMilestone(GroupMilestoneInfo):
|
||||||
|
|
||||||
class GroupMilestoneHistory(GroupMilestoneInfo):
|
class GroupMilestoneHistory(GroupMilestoneInfo):
|
||||||
time = models.DateTimeField()
|
time = models.DateTimeField()
|
||||||
milestone = models.ForeignKey(GroupMilestone, related_name="history_set")
|
milestone = ForeignKey(GroupMilestone, related_name="history_set")
|
||||||
|
|
||||||
class GroupStateTransitions(models.Model):
|
class GroupStateTransitions(models.Model):
|
||||||
"""Captures that a group has overriden the default available
|
"""Captures that a group has overriden the default available
|
||||||
document state transitions for a certain state."""
|
document state transitions for a certain state."""
|
||||||
group = models.ForeignKey(Group)
|
group = ForeignKey(Group)
|
||||||
state = models.ForeignKey('doc.State', help_text="State for which the next states should be overridden")
|
state = ForeignKey('doc.State', help_text="State for which the next states should be overridden")
|
||||||
next_states = models.ManyToManyField('doc.State', related_name='previous_groupstatetransitions_states')
|
next_states = models.ManyToManyField('doc.State', related_name='previous_groupstatetransitions_states')
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
|
@ -255,10 +256,10 @@ GROUP_EVENT_CHOICES = [
|
||||||
|
|
||||||
class GroupEvent(models.Model):
|
class GroupEvent(models.Model):
|
||||||
"""An occurrence for a group, used for tracking who, when and what."""
|
"""An occurrence for a group, used for tracking who, when and what."""
|
||||||
group = models.ForeignKey(Group)
|
group = ForeignKey(Group)
|
||||||
time = models.DateTimeField(default=datetime.datetime.now, help_text="When the event happened")
|
time = models.DateTimeField(default=datetime.datetime.now, help_text="When the event happened")
|
||||||
type = models.CharField(max_length=50, choices=GROUP_EVENT_CHOICES)
|
type = models.CharField(max_length=50, choices=GROUP_EVENT_CHOICES)
|
||||||
by = models.ForeignKey(Person)
|
by = ForeignKey(Person)
|
||||||
desc = models.TextField()
|
desc = models.TextField()
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
|
@ -268,16 +269,16 @@ class GroupEvent(models.Model):
|
||||||
ordering = ['-time', 'id']
|
ordering = ['-time', 'id']
|
||||||
|
|
||||||
class ChangeStateGroupEvent(GroupEvent):
|
class ChangeStateGroupEvent(GroupEvent):
|
||||||
state = models.ForeignKey(GroupStateName)
|
state = ForeignKey(GroupStateName)
|
||||||
|
|
||||||
class MilestoneGroupEvent(GroupEvent):
|
class MilestoneGroupEvent(GroupEvent):
|
||||||
milestone = models.ForeignKey(GroupMilestone)
|
milestone = ForeignKey(GroupMilestone)
|
||||||
|
|
||||||
class Role(models.Model):
|
class Role(models.Model):
|
||||||
name = models.ForeignKey(RoleName)
|
name = ForeignKey(RoleName)
|
||||||
group = models.ForeignKey(Group)
|
group = ForeignKey(Group)
|
||||||
person = models.ForeignKey(Person)
|
person = ForeignKey(Person)
|
||||||
email = models.ForeignKey(Email, help_text="Email address used by person for this role.")
|
email = ForeignKey(Email, help_text="Email address used by person for this role.")
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u"%s is %s in %s" % (self.person.plain_name(), self.name.name, self.group.acronym or self.group.name)
|
return u"%s is %s in %s" % (self.person.plain_name(), self.name.name, self.group.acronym or self.group.name)
|
||||||
|
|
||||||
|
@ -295,10 +296,10 @@ class RoleHistory(models.Model):
|
||||||
# used on its own - there should always be a GroupHistory
|
# used on its own - there should always be a GroupHistory
|
||||||
# accompanying a change in roles, so lookup the appropriate
|
# accompanying a change in roles, so lookup the appropriate
|
||||||
# GroupHistory instead
|
# GroupHistory instead
|
||||||
name = models.ForeignKey(RoleName)
|
name = ForeignKey(RoleName)
|
||||||
group = models.ForeignKey(GroupHistory)
|
group = ForeignKey(GroupHistory)
|
||||||
person = models.ForeignKey(Person)
|
person = ForeignKey(Person)
|
||||||
email = models.ForeignKey(Email, help_text="Email address used by person for this role.")
|
email = ForeignKey(Email, help_text="Email address used by person for this role.")
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u"%s is %s in %s" % (self.person.plain_name(), self.name.name, self.group.acronym)
|
return u"%s is %s in %s" % (self.person.plain_name(), self.name.name, self.group.acronym)
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,8 @@ import datetime
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
|
from ietf.utils.models import ForeignKey, OneToOneField
|
||||||
|
|
||||||
class TelechatAgendaItem(models.Model):
|
class TelechatAgendaItem(models.Model):
|
||||||
TYPE_CHOICES = (
|
TYPE_CHOICES = (
|
||||||
(1, "Any Other Business (WG News, New Proposals, etc.)"),
|
(1, "Any Other Business (WG News, New Proposals, etc.)"),
|
||||||
|
|
|
@ -10,16 +10,17 @@ from ietf.doc.models import DocAlias
|
||||||
from ietf.name.models import DocRelationshipName,IprDisclosureStateName,IprLicenseTypeName,IprEventTypeName
|
from ietf.name.models import DocRelationshipName,IprDisclosureStateName,IprLicenseTypeName,IprEventTypeName
|
||||||
from ietf.person.models import Person
|
from ietf.person.models import Person
|
||||||
from ietf.message.models import Message
|
from ietf.message.models import Message
|
||||||
|
from ietf.utils.models import ForeignKey, OneToOneField
|
||||||
|
|
||||||
class IprDisclosureBase(models.Model):
|
class IprDisclosureBase(models.Model):
|
||||||
by = models.ForeignKey(Person) # who was logged in, or System if nobody was logged in
|
by = ForeignKey(Person) # who was logged in, or System if nobody was logged in
|
||||||
compliant = models.BooleanField("Complies to RFC3979", default=True)
|
compliant = models.BooleanField("Complies to RFC3979", default=True)
|
||||||
docs = models.ManyToManyField(DocAlias, through='IprDocRel')
|
docs = models.ManyToManyField(DocAlias, through='IprDocRel')
|
||||||
holder_legal_name = models.CharField(max_length=255)
|
holder_legal_name = models.CharField(max_length=255)
|
||||||
notes = models.TextField("Additional notes", blank=True)
|
notes = models.TextField("Additional notes", blank=True)
|
||||||
other_designations = models.CharField("Designations for other contributions", blank=True, max_length=255)
|
other_designations = models.CharField("Designations for other contributions", blank=True, max_length=255)
|
||||||
rel = models.ManyToManyField('self', through='RelatedIpr', symmetrical=False)
|
rel = models.ManyToManyField('self', through='RelatedIpr', symmetrical=False)
|
||||||
state = models.ForeignKey(IprDisclosureStateName)
|
state = ForeignKey(IprDisclosureStateName)
|
||||||
submitter_name = models.CharField(max_length=255,blank=True)
|
submitter_name = models.CharField(max_length=255,blank=True)
|
||||||
submitter_email = models.EmailField(blank=True)
|
submitter_email = models.EmailField(blank=True)
|
||||||
time = models.DateTimeField(auto_now_add=True)
|
time = models.DateTimeField(auto_now_add=True)
|
||||||
|
@ -118,7 +119,7 @@ class HolderIprDisclosure(IprDisclosureBase):
|
||||||
holder_contact_email = models.EmailField()
|
holder_contact_email = models.EmailField()
|
||||||
holder_contact_name = models.CharField(max_length=255)
|
holder_contact_name = models.CharField(max_length=255)
|
||||||
holder_contact_info = models.TextField(blank=True, help_text="Address, phone, etc.")
|
holder_contact_info = models.TextField(blank=True, help_text="Address, phone, etc.")
|
||||||
licensing = models.ForeignKey(IprLicenseTypeName)
|
licensing = ForeignKey(IprLicenseTypeName)
|
||||||
licensing_comments = models.TextField(blank=True)
|
licensing_comments = models.TextField(blank=True)
|
||||||
submitter_claims_all_terms_disclosed = models.BooleanField(default=False)
|
submitter_claims_all_terms_disclosed = models.BooleanField(default=False)
|
||||||
|
|
||||||
|
@ -145,8 +146,8 @@ class GenericIprDisclosure(IprDisclosureBase):
|
||||||
statement = models.TextField() # includes licensing info
|
statement = models.TextField() # includes licensing info
|
||||||
|
|
||||||
class IprDocRel(models.Model):
|
class IprDocRel(models.Model):
|
||||||
disclosure = models.ForeignKey(IprDisclosureBase)
|
disclosure = ForeignKey(IprDisclosureBase)
|
||||||
document = models.ForeignKey(DocAlias)
|
document = ForeignKey(DocAlias)
|
||||||
sections = models.TextField(blank=True)
|
sections = models.TextField(blank=True)
|
||||||
revisions = models.CharField(max_length=16,blank=True) # allows strings like 01-07
|
revisions = models.CharField(max_length=16,blank=True) # allows strings like 01-07
|
||||||
|
|
||||||
|
@ -175,21 +176,21 @@ class IprDocRel(models.Model):
|
||||||
return u"%s which applies to %s" % (self.disclosure, self.document.name)
|
return u"%s which applies to %s" % (self.disclosure, self.document.name)
|
||||||
|
|
||||||
class RelatedIpr(models.Model):
|
class RelatedIpr(models.Model):
|
||||||
source = models.ForeignKey(IprDisclosureBase,related_name='relatedipr_source_set')
|
source = ForeignKey(IprDisclosureBase,related_name='relatedipr_source_set')
|
||||||
target = models.ForeignKey(IprDisclosureBase,related_name='relatedipr_target_set')
|
target = ForeignKey(IprDisclosureBase,related_name='relatedipr_target_set')
|
||||||
relationship = models.ForeignKey(DocRelationshipName) # Re-use; change to a dedicated RelName if needed
|
relationship = ForeignKey(DocRelationshipName) # Re-use; change to a dedicated RelName if needed
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u"%s %s %s" % (self.source.title, self.relationship.name.lower(), self.target.title)
|
return u"%s %s %s" % (self.source.title, self.relationship.name.lower(), self.target.title)
|
||||||
|
|
||||||
class IprEvent(models.Model):
|
class IprEvent(models.Model):
|
||||||
time = models.DateTimeField(auto_now_add=True)
|
time = models.DateTimeField(auto_now_add=True)
|
||||||
type = models.ForeignKey(IprEventTypeName)
|
type = ForeignKey(IprEventTypeName)
|
||||||
by = models.ForeignKey(Person)
|
by = ForeignKey(Person)
|
||||||
disclosure = models.ForeignKey(IprDisclosureBase)
|
disclosure = ForeignKey(IprDisclosureBase)
|
||||||
desc = models.TextField()
|
desc = models.TextField()
|
||||||
message = models.ForeignKey(Message, null=True, blank=True,related_name='msgevents')
|
message = ForeignKey(Message, null=True, blank=True,related_name='msgevents')
|
||||||
in_reply_to = models.ForeignKey(Message, null=True, blank=True,related_name='irtoevents')
|
in_reply_to = ForeignKey(Message, null=True, blank=True,related_name='irtoevents')
|
||||||
response_due= models.DateTimeField(blank=True,null=True)
|
response_due= models.DateTimeField(blank=True,null=True)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
|
|
|
@ -10,7 +10,7 @@ from django.core.exceptions import ObjectDoesNotExist
|
||||||
from django.db.models.query import QuerySet
|
from django.db.models.query import QuerySet
|
||||||
from django.forms.utils import ErrorList
|
from django.forms.utils import ErrorList
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.forms.widgets import RadioFieldRenderer
|
#from django.forms.widgets import RadioFieldRenderer
|
||||||
from django.core.validators import validate_email, ValidationError
|
from django.core.validators import validate_email, ValidationError
|
||||||
from django.utils.html import format_html
|
from django.utils.html import format_html
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
|
@ -122,18 +122,18 @@ class AddCommentForm(forms.Form):
|
||||||
comment = forms.CharField(required=True, widget=forms.Textarea, strip=False)
|
comment = forms.CharField(required=True, widget=forms.Textarea, strip=False)
|
||||||
private = forms.BooleanField(label="Private comment", required=False,help_text="If this box is checked the comment will not appear in the statement's public history view.")
|
private = forms.BooleanField(label="Private comment", required=False,help_text="If this box is checked the comment will not appear in the statement's public history view.")
|
||||||
|
|
||||||
class RadioRenderer(RadioFieldRenderer):
|
# class RadioRenderer(RadioFieldRenderer):
|
||||||
def render(self):
|
# def render(self):
|
||||||
output = []
|
# output = []
|
||||||
for widget in self:
|
# for widget in self:
|
||||||
output.append(format_html(force_text(widget)))
|
# output.append(format_html(force_text(widget)))
|
||||||
return mark_safe('\n'.join(output))
|
# return mark_safe('\n'.join(output))
|
||||||
|
|
||||||
|
|
||||||
class SearchLiaisonForm(forms.Form):
|
class SearchLiaisonForm(forms.Form):
|
||||||
'''Expects initial keyword argument queryset which then gets filtered based on form data'''
|
'''Expects initial keyword argument queryset which then gets filtered based on form data'''
|
||||||
text = forms.CharField(required=False)
|
text = forms.CharField(required=False)
|
||||||
scope = forms.ChoiceField(choices=(("all", "All text fields"), ("title", "Title field")), required=False, initial='title', widget=forms.RadioSelect(renderer=RadioRenderer))
|
# scope = forms.ChoiceField(choices=(("all", "All text fields"), ("title", "Title field")), required=False, initial='title')
|
||||||
source = forms.CharField(required=False)
|
source = forms.CharField(required=False)
|
||||||
destination = forms.CharField(required=False)
|
destination = forms.CharField(required=False)
|
||||||
start_date = DatepickerDateField(date_format="yyyy-mm-dd", picker_settings={"autoclose": "1" }, label='Start date', required=False)
|
start_date = DatepickerDateField(date_format="yyyy-mm-dd", picker_settings={"autoclose": "1" }, label='Start date', required=False)
|
||||||
|
|
|
@ -11,6 +11,7 @@ from ietf.name.models import (LiaisonStatementPurposeName, LiaisonStatementState
|
||||||
DocRelationshipName)
|
DocRelationshipName)
|
||||||
from ietf.doc.models import Document
|
from ietf.doc.models import Document
|
||||||
from ietf.group.models import Group
|
from ietf.group.models import Group
|
||||||
|
from ietf.utils.models import ForeignKey, OneToOneField
|
||||||
|
|
||||||
# maps (previous state id, new state id) to event type id
|
# maps (previous state id, new state id) to event type id
|
||||||
STATE_EVENT_MAPPING = {
|
STATE_EVENT_MAPPING = {
|
||||||
|
@ -26,7 +27,7 @@ STATE_EVENT_MAPPING = {
|
||||||
class LiaisonStatement(models.Model):
|
class LiaisonStatement(models.Model):
|
||||||
title = models.CharField(max_length=255)
|
title = models.CharField(max_length=255)
|
||||||
from_groups = models.ManyToManyField(Group, blank=True, related_name='liaisonstatement_from_set')
|
from_groups = models.ManyToManyField(Group, blank=True, related_name='liaisonstatement_from_set')
|
||||||
from_contact = models.ForeignKey(Email, blank=True, null=True)
|
from_contact = ForeignKey(Email, blank=True, null=True)
|
||||||
to_groups = models.ManyToManyField(Group, blank=True, related_name='liaisonstatement_to_set')
|
to_groups = models.ManyToManyField(Group, blank=True, related_name='liaisonstatement_to_set')
|
||||||
to_contacts = models.CharField(max_length=2000, help_text="Contacts at recipient group")
|
to_contacts = models.CharField(max_length=2000, help_text="Contacts at recipient group")
|
||||||
|
|
||||||
|
@ -35,14 +36,14 @@ class LiaisonStatement(models.Model):
|
||||||
action_holder_contacts = models.CharField(blank=True, max_length=255, help_text="Who makes sure action is completed") # incoming only?
|
action_holder_contacts = models.CharField(blank=True, max_length=255, help_text="Who makes sure action is completed") # incoming only?
|
||||||
cc_contacts = models.TextField(blank=True)
|
cc_contacts = models.TextField(blank=True)
|
||||||
|
|
||||||
purpose = models.ForeignKey(LiaisonStatementPurposeName)
|
purpose = ForeignKey(LiaisonStatementPurposeName)
|
||||||
deadline = models.DateField(null=True, blank=True)
|
deadline = models.DateField(null=True, blank=True)
|
||||||
other_identifiers = models.TextField(blank=True, null=True) # Identifiers from other bodies
|
other_identifiers = models.TextField(blank=True, null=True) # Identifiers from other bodies
|
||||||
body = models.TextField(blank=True)
|
body = models.TextField(blank=True)
|
||||||
|
|
||||||
tags = models.ManyToManyField(LiaisonStatementTagName, blank=True)
|
tags = models.ManyToManyField(LiaisonStatementTagName, blank=True)
|
||||||
attachments = models.ManyToManyField(Document, through='LiaisonStatementAttachment', blank=True)
|
attachments = models.ManyToManyField(Document, through='LiaisonStatementAttachment', blank=True)
|
||||||
state = models.ForeignKey(LiaisonStatementState, default='pending')
|
state = ForeignKey(LiaisonStatementState, default='pending')
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.title or u"<no title>"
|
return self.title or u"<no title>"
|
||||||
|
@ -194,8 +195,8 @@ class LiaisonStatement(models.Model):
|
||||||
return list(set([ r.email.address for r in approval_set ]))
|
return list(set([ r.email.address for r in approval_set ]))
|
||||||
|
|
||||||
class LiaisonStatementAttachment(models.Model):
|
class LiaisonStatementAttachment(models.Model):
|
||||||
statement = models.ForeignKey(LiaisonStatement)
|
statement = ForeignKey(LiaisonStatement)
|
||||||
document = models.ForeignKey(Document)
|
document = ForeignKey(Document)
|
||||||
removed = models.BooleanField(default=False)
|
removed = models.BooleanField(default=False)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
|
@ -203,16 +204,16 @@ class LiaisonStatementAttachment(models.Model):
|
||||||
|
|
||||||
|
|
||||||
class RelatedLiaisonStatement(models.Model):
|
class RelatedLiaisonStatement(models.Model):
|
||||||
source = models.ForeignKey(LiaisonStatement, related_name='source_of_set')
|
source = ForeignKey(LiaisonStatement, related_name='source_of_set')
|
||||||
target = models.ForeignKey(LiaisonStatement, related_name='target_of_set')
|
target = ForeignKey(LiaisonStatement, related_name='target_of_set')
|
||||||
relationship = models.ForeignKey(DocRelationshipName)
|
relationship = ForeignKey(DocRelationshipName)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u"%s %s %s" % (self.source.title, self.relationship.name.lower(), self.target.title)
|
return u"%s %s %s" % (self.source.title, self.relationship.name.lower(), self.target.title)
|
||||||
|
|
||||||
|
|
||||||
class LiaisonStatementGroupContacts(models.Model):
|
class LiaisonStatementGroupContacts(models.Model):
|
||||||
group = models.ForeignKey(Group, unique=True, null=True)
|
group = ForeignKey(Group, unique=True, null=True)
|
||||||
contacts = models.CharField(max_length=255,blank=True)
|
contacts = models.CharField(max_length=255,blank=True)
|
||||||
cc_contacts = models.CharField(max_length=255,blank=True)
|
cc_contacts = models.CharField(max_length=255,blank=True)
|
||||||
|
|
||||||
|
@ -222,9 +223,9 @@ class LiaisonStatementGroupContacts(models.Model):
|
||||||
|
|
||||||
class LiaisonStatementEvent(models.Model):
|
class LiaisonStatementEvent(models.Model):
|
||||||
time = models.DateTimeField(auto_now_add=True)
|
time = models.DateTimeField(auto_now_add=True)
|
||||||
type = models.ForeignKey(LiaisonStatementEventTypeName)
|
type = ForeignKey(LiaisonStatementEventTypeName)
|
||||||
by = models.ForeignKey(Person)
|
by = ForeignKey(Person)
|
||||||
statement = models.ForeignKey(LiaisonStatement)
|
statement = ForeignKey(LiaisonStatement)
|
||||||
desc = models.TextField()
|
desc = models.TextField()
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
|
|
|
@ -6,6 +6,7 @@ from django.core.validators import validate_email
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
from ietf.person.models import Person
|
from ietf.person.models import Person
|
||||||
|
from ietf.utils.models import ForeignKey, OneToOneField
|
||||||
|
|
||||||
class List(models.Model):
|
class List(models.Model):
|
||||||
name = models.CharField(max_length=32)
|
name = models.CharField(max_length=32)
|
||||||
|
@ -28,7 +29,7 @@ class Subscribed(models.Model):
|
||||||
class Whitelisted(models.Model):
|
class Whitelisted(models.Model):
|
||||||
time = models.DateTimeField(auto_now_add=True)
|
time = models.DateTimeField(auto_now_add=True)
|
||||||
email = models.CharField("Email address", max_length=64, validators=[validate_email])
|
email = models.CharField("Email address", max_length=64, validators=[validate_email])
|
||||||
by = models.ForeignKey(Person)
|
by = ForeignKey(Person)
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return "<Whitelisted: %s at %s>" % (self.email, self.time)
|
return "<Whitelisted: %s at %s>" % (self.email, self.time)
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
|
@ -10,6 +10,7 @@ from ietf.person.models import Email
|
||||||
import debug # pyflakes:ignore
|
import debug # pyflakes:ignore
|
||||||
|
|
||||||
from ietf.group.models import Role
|
from ietf.group.models import Role
|
||||||
|
from ietf.utils.models import ForeignKey, OneToOneField
|
||||||
|
|
||||||
def clean_duplicates(addrlist):
|
def clean_duplicates(addrlist):
|
||||||
address_info = {}
|
address_info = {}
|
||||||
|
|
|
@ -27,6 +27,7 @@ from ietf.person.models import Person
|
||||||
from ietf.utils.storage import NoLocationMigrationFileSystemStorage
|
from ietf.utils.storage import NoLocationMigrationFileSystemStorage
|
||||||
from ietf.utils.text import xslugify
|
from ietf.utils.text import xslugify
|
||||||
from ietf.utils.timezone import date2datetime
|
from ietf.utils.timezone import date2datetime
|
||||||
|
from ietf.utils.models import ForeignKey, OneToOneField
|
||||||
|
|
||||||
countries = pytz.country_names.items()
|
countries = pytz.country_names.items()
|
||||||
countries.sort(lambda x,y: cmp(x[1], y[1]))
|
countries.sort(lambda x,y: cmp(x[1], y[1]))
|
||||||
|
@ -49,7 +50,7 @@ class Meeting(models.Model):
|
||||||
# number is either the number for IETF meetings, or some other
|
# number is either the number for IETF meetings, or some other
|
||||||
# identifier for interim meetings/IESG retreats/liaison summits/...
|
# identifier for interim meetings/IESG retreats/liaison summits/...
|
||||||
number = models.CharField(unique=True, max_length=64)
|
number = models.CharField(unique=True, max_length=64)
|
||||||
type = models.ForeignKey(MeetingTypeName)
|
type = ForeignKey(MeetingTypeName)
|
||||||
# Date is useful when generating a set of timeslot for this meeting, but
|
# Date is useful when generating a set of timeslot for this meeting, but
|
||||||
# is not used to determine date for timeslot instances thereafter, as
|
# is not used to determine date for timeslot instances thereafter, as
|
||||||
# they have their own datetime field.
|
# they have their own datetime field.
|
||||||
|
@ -88,11 +89,11 @@ class Meeting(models.Model):
|
||||||
break_area = models.CharField(blank=True, max_length=255)
|
break_area = models.CharField(blank=True, max_length=255)
|
||||||
reg_area = models.CharField(blank=True, max_length=255)
|
reg_area = models.CharField(blank=True, max_length=255)
|
||||||
agenda_note = models.TextField(blank=True, help_text="Text in this field will be placed at the top of the html agenda page for the meeting. HTML can be used, but will not be validated.")
|
agenda_note = models.TextField(blank=True, help_text="Text in this field will be placed at the top of the html agenda page for the meeting. HTML can be used, but will not be validated.")
|
||||||
agenda = models.ForeignKey('Schedule',null=True,blank=True, related_name='+')
|
agenda = ForeignKey('Schedule',null=True,blank=True, related_name='+')
|
||||||
session_request_lock_message = models.CharField(blank=True,max_length=255) # locked if not empty
|
session_request_lock_message = models.CharField(blank=True,max_length=255) # locked if not empty
|
||||||
proceedings_final = models.BooleanField(default=False, help_text=u"Are the proceedings for this meeting complete?")
|
proceedings_final = models.BooleanField(default=False, help_text=u"Are the proceedings for this meeting complete?")
|
||||||
acknowledgements = models.TextField(blank=True, help_text="Acknowledgements for use in meeting proceedings. Use ReStructuredText markup.")
|
acknowledgements = models.TextField(blank=True, help_text="Acknowledgements for use in meeting proceedings. Use ReStructuredText markup.")
|
||||||
overview = models.ForeignKey(DBTemplate, related_name='overview', null=True, editable=False)
|
overview = ForeignKey(DBTemplate, related_name='overview', null=True, editable=False)
|
||||||
show_important_dates = models.BooleanField(default=False)
|
show_important_dates = models.BooleanField(default=False)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
|
@ -284,7 +285,7 @@ class Meeting(models.Model):
|
||||||
# === Rooms, Resources, Floorplans =============================================
|
# === Rooms, Resources, Floorplans =============================================
|
||||||
|
|
||||||
class ResourceAssociation(models.Model):
|
class ResourceAssociation(models.Model):
|
||||||
name = models.ForeignKey(RoomResourceName)
|
name = ForeignKey(RoomResourceName)
|
||||||
icon = models.CharField(max_length=64) # icon to be found in /static/img
|
icon = models.CharField(max_length=64) # icon to be found in /static/img
|
||||||
desc = models.CharField(max_length=256)
|
desc = models.CharField(max_length=256)
|
||||||
|
|
||||||
|
@ -300,7 +301,7 @@ class ResourceAssociation(models.Model):
|
||||||
return res1
|
return res1
|
||||||
|
|
||||||
class Room(models.Model):
|
class Room(models.Model):
|
||||||
meeting = models.ForeignKey(Meeting)
|
meeting = ForeignKey(Meeting)
|
||||||
time = models.DateTimeField(default=datetime.datetime.now)
|
time = models.DateTimeField(default=datetime.datetime.now)
|
||||||
name = models.CharField(max_length=255)
|
name = models.CharField(max_length=255)
|
||||||
functional_name = models.CharField(max_length=255, blank = True)
|
functional_name = models.CharField(max_length=255, blank = True)
|
||||||
|
@ -308,7 +309,7 @@ class Room(models.Model):
|
||||||
resources = models.ManyToManyField(ResourceAssociation, blank = True)
|
resources = models.ManyToManyField(ResourceAssociation, blank = True)
|
||||||
session_types = models.ManyToManyField(TimeSlotTypeName, blank = True)
|
session_types = models.ManyToManyField(TimeSlotTypeName, blank = True)
|
||||||
# floorplan-related properties
|
# floorplan-related properties
|
||||||
floorplan = models.ForeignKey('FloorPlan', null=True, blank=True, default=None)
|
floorplan = ForeignKey('FloorPlan', null=True, blank=True, default=None)
|
||||||
# floorplan: room pixel position : (0,0) is top left of image, (xd, yd)
|
# floorplan: room pixel position : (0,0) is top left of image, (xd, yd)
|
||||||
# is room width, height.
|
# is room width, height.
|
||||||
x1 = models.SmallIntegerField(null=True, blank=True, default=None)
|
x1 = models.SmallIntegerField(null=True, blank=True, default=None)
|
||||||
|
@ -380,8 +381,8 @@ class Room(models.Model):
|
||||||
|
|
||||||
class UrlResource(models.Model):
|
class UrlResource(models.Model):
|
||||||
"For things like audio stream urls, meetecho stream urls"
|
"For things like audio stream urls, meetecho stream urls"
|
||||||
name = models.ForeignKey(RoomResourceName)
|
name = ForeignKey(RoomResourceName)
|
||||||
room = models.ForeignKey(Room)
|
room = ForeignKey(Room)
|
||||||
url = models.URLField(null=True, blank=True)
|
url = models.URLField(null=True, blank=True)
|
||||||
|
|
||||||
def floorplan_path(instance, filename):
|
def floorplan_path(instance, filename):
|
||||||
|
@ -392,7 +393,7 @@ class FloorPlan(models.Model):
|
||||||
name = models.CharField(max_length=255)
|
name = models.CharField(max_length=255)
|
||||||
short = models.CharField(max_length=2, default='')
|
short = models.CharField(max_length=2, default='')
|
||||||
time = models.DateTimeField(default=datetime.datetime.now)
|
time = models.DateTimeField(default=datetime.datetime.now)
|
||||||
meeting = models.ForeignKey(Meeting)
|
meeting = ForeignKey(Meeting)
|
||||||
order = models.SmallIntegerField()
|
order = models.SmallIntegerField()
|
||||||
image = models.ImageField(storage=NoLocationMigrationFileSystemStorage(), upload_to=floorplan_path, blank=True, default=None)
|
image = models.ImageField(storage=NoLocationMigrationFileSystemStorage(), upload_to=floorplan_path, blank=True, default=None)
|
||||||
#
|
#
|
||||||
|
@ -407,12 +408,12 @@ class TimeSlot(models.Model):
|
||||||
mapped to a time slot, including breaks. Sessions are connected to
|
mapped to a time slot, including breaks. Sessions are connected to
|
||||||
TimeSlots during scheduling.
|
TimeSlots during scheduling.
|
||||||
"""
|
"""
|
||||||
meeting = models.ForeignKey(Meeting)
|
meeting = ForeignKey(Meeting)
|
||||||
type = models.ForeignKey(TimeSlotTypeName)
|
type = ForeignKey(TimeSlotTypeName)
|
||||||
name = models.CharField(max_length=255)
|
name = models.CharField(max_length=255)
|
||||||
time = models.DateTimeField()
|
time = models.DateTimeField()
|
||||||
duration = models.DurationField(default=datetime.timedelta(0))
|
duration = models.DurationField(default=datetime.timedelta(0))
|
||||||
location = models.ForeignKey(Room, blank=True, null=True)
|
location = ForeignKey(Room, blank=True, null=True)
|
||||||
show_location = models.BooleanField(default=True, help_text="Show location in agenda.")
|
show_location = models.BooleanField(default=True, help_text="Show location in agenda.")
|
||||||
sessions = models.ManyToManyField('Session', related_name='slots', through='SchedTimeSessAssignment', blank=True, help_text=u"Scheduled session, if any.")
|
sessions = models.ManyToManyField('Session', related_name='slots', through='SchedTimeSessAssignment', blank=True, help_text=u"Scheduled session, if any.")
|
||||||
modified = models.DateTimeField(auto_now=True)
|
modified = models.DateTimeField(auto_now=True)
|
||||||
|
@ -578,13 +579,13 @@ class Schedule(models.Model):
|
||||||
Secretariat to IESG members for review. Only the owner may edit the
|
Secretariat to IESG members for review. Only the owner may edit the
|
||||||
agenda, others may copy it
|
agenda, others may copy it
|
||||||
"""
|
"""
|
||||||
meeting = models.ForeignKey(Meeting, null=True)
|
meeting = ForeignKey(Meeting, null=True)
|
||||||
name = models.CharField(max_length=16, blank=False)
|
name = models.CharField(max_length=16, blank=False)
|
||||||
owner = models.ForeignKey(Person)
|
owner = ForeignKey(Person)
|
||||||
visible = models.BooleanField(default=True, help_text=u"Make this agenda available to those who know about it.")
|
visible = models.BooleanField(default=True, help_text=u"Make this agenda available to those who know about it.")
|
||||||
public = models.BooleanField(default=True, help_text=u"Make this agenda publically available.")
|
public = models.BooleanField(default=True, help_text=u"Make this agenda publically available.")
|
||||||
badness = models.IntegerField(null=True, blank=True)
|
badness = models.IntegerField(null=True, blank=True)
|
||||||
# considering copiedFrom = models.ForeignKey('Schedule', blank=True, null=True)
|
# considering copiedFrom = ForeignKey('Schedule', blank=True, null=True)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u"%s:%s(%s)" % (self.meeting, self.name, self.owner)
|
return u"%s:%s(%s)" % (self.meeting, self.name, self.owner)
|
||||||
|
@ -683,10 +684,10 @@ class SchedTimeSessAssignment(models.Model):
|
||||||
Each relationship is attached to the named agenda, which is owned by
|
Each relationship is attached to the named agenda, which is owned by
|
||||||
a specific person/user.
|
a specific person/user.
|
||||||
"""
|
"""
|
||||||
timeslot = models.ForeignKey('TimeSlot', null=False, blank=False, related_name='sessionassignments')
|
timeslot = ForeignKey('TimeSlot', null=False, blank=False, related_name='sessionassignments')
|
||||||
session = models.ForeignKey('Session', null=True, default=None, related_name='timeslotassignments', help_text=u"Scheduled session.")
|
session = ForeignKey('Session', null=True, default=None, related_name='timeslotassignments', help_text=u"Scheduled session.")
|
||||||
schedule = models.ForeignKey('Schedule', null=False, blank=False, related_name='assignments')
|
schedule = ForeignKey('Schedule', null=False, blank=False, related_name='assignments')
|
||||||
extendedfrom = models.ForeignKey('self', null=True, default=None, help_text=u"Timeslot this session is an extension of.")
|
extendedfrom = ForeignKey('self', null=True, default=None, help_text=u"Timeslot this session is an extension of.")
|
||||||
modified = models.DateTimeField(auto_now=True)
|
modified = models.DateTimeField(auto_now=True)
|
||||||
notes = models.TextField(blank=True)
|
notes = models.TextField(blank=True)
|
||||||
badness = models.IntegerField(default=0, blank=True, null=True)
|
badness = models.IntegerField(default=0, blank=True, null=True)
|
||||||
|
@ -789,12 +790,12 @@ class Constraint(models.Model):
|
||||||
A third type (name=avoidday) of constraint is between source WG and
|
A third type (name=avoidday) of constraint is between source WG and
|
||||||
a particular day of the week, specified in day.
|
a particular day of the week, specified in day.
|
||||||
"""
|
"""
|
||||||
meeting = models.ForeignKey(Meeting)
|
meeting = ForeignKey(Meeting)
|
||||||
source = models.ForeignKey(Group, related_name="constraint_source_set")
|
source = ForeignKey(Group, related_name="constraint_source_set")
|
||||||
target = models.ForeignKey(Group, related_name="constraint_target_set", null=True)
|
target = ForeignKey(Group, related_name="constraint_target_set", null=True)
|
||||||
person = models.ForeignKey(Person, null=True, blank=True)
|
person = ForeignKey(Person, null=True, blank=True)
|
||||||
day = models.DateTimeField(null=True, blank=True)
|
day = models.DateTimeField(null=True, blank=True)
|
||||||
name = models.ForeignKey(ConstraintName)
|
name = ForeignKey(ConstraintName)
|
||||||
|
|
||||||
active_status = None
|
active_status = None
|
||||||
|
|
||||||
|
@ -828,8 +829,8 @@ class Constraint(models.Model):
|
||||||
|
|
||||||
|
|
||||||
class SessionPresentation(models.Model):
|
class SessionPresentation(models.Model):
|
||||||
session = models.ForeignKey('Session')
|
session = ForeignKey('Session')
|
||||||
document = models.ForeignKey(Document)
|
document = ForeignKey(Document)
|
||||||
rev = models.CharField(verbose_name="revision", max_length=16, null=True, blank=True)
|
rev = models.CharField(verbose_name="revision", max_length=16, null=True, blank=True)
|
||||||
order = models.PositiveSmallIntegerField(default=0)
|
order = models.PositiveSmallIntegerField(default=0)
|
||||||
|
|
||||||
|
@ -849,18 +850,18 @@ class Session(models.Model):
|
||||||
timeslots are needed, multiple sessions will have to be created.
|
timeslots are needed, multiple sessions will have to be created.
|
||||||
Training sessions and similar are modeled by filling in a
|
Training sessions and similar are modeled by filling in a
|
||||||
responsible group (e.g. Edu team) and filling in the name."""
|
responsible group (e.g. Edu team) and filling in the name."""
|
||||||
meeting = models.ForeignKey(Meeting)
|
meeting = ForeignKey(Meeting)
|
||||||
name = models.CharField(blank=True, max_length=255, help_text="Name of session, in case the session has a purpose rather than just being a group meeting.")
|
name = models.CharField(blank=True, max_length=255, help_text="Name of session, in case the session has a purpose rather than just being a group meeting.")
|
||||||
short = models.CharField(blank=True, max_length=32, help_text="Short version of 'name' above, for use in filenames.")
|
short = models.CharField(blank=True, max_length=32, help_text="Short version of 'name' above, for use in filenames.")
|
||||||
type = models.ForeignKey(TimeSlotTypeName)
|
type = ForeignKey(TimeSlotTypeName)
|
||||||
group = models.ForeignKey(Group) # The group type historically determined the session type. BOFs also need to be added as a group. Note that not all meeting requests have a natural group to associate with.
|
group = ForeignKey(Group) # The group type historically determined the session type. BOFs also need to be added as a group. Note that not all meeting requests have a natural group to associate with.
|
||||||
attendees = models.IntegerField(null=True, blank=True)
|
attendees = models.IntegerField(null=True, blank=True)
|
||||||
agenda_note = models.CharField(blank=True, max_length=255)
|
agenda_note = models.CharField(blank=True, max_length=255)
|
||||||
requested = models.DateTimeField(default=datetime.datetime.now)
|
requested = models.DateTimeField(default=datetime.datetime.now)
|
||||||
requested_by = models.ForeignKey(Person)
|
requested_by = ForeignKey(Person)
|
||||||
requested_duration = models.DurationField(default=datetime.timedelta(0))
|
requested_duration = models.DurationField(default=datetime.timedelta(0))
|
||||||
comments = models.TextField(blank=True)
|
comments = models.TextField(blank=True)
|
||||||
status = models.ForeignKey(SessionStatusName)
|
status = ForeignKey(SessionStatusName)
|
||||||
scheduled = models.DateTimeField(null=True, blank=True)
|
scheduled = models.DateTimeField(null=True, blank=True)
|
||||||
modified = models.DateTimeField(auto_now=True)
|
modified = models.DateTimeField(auto_now=True)
|
||||||
remote_instructions = models.CharField(blank=True,max_length=1024)
|
remote_instructions = models.CharField(blank=True,max_length=1024)
|
||||||
|
@ -1111,8 +1112,8 @@ class Session(models.Model):
|
||||||
return self._agenda_file
|
return self._agenda_file
|
||||||
|
|
||||||
class ImportantDate(models.Model):
|
class ImportantDate(models.Model):
|
||||||
meeting = models.ForeignKey(Meeting)
|
meeting = ForeignKey(Meeting)
|
||||||
date = models.DateField()
|
date = models.DateField()
|
||||||
name = models.ForeignKey(ImportantDateName)
|
name = ForeignKey(ImportantDateName)
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ["-meeting","date", ]
|
ordering = ["-meeting","date", ]
|
||||||
|
|
|
@ -9,10 +9,11 @@ from ietf.person.models import Person
|
||||||
from ietf.group.models import Group
|
from ietf.group.models import Group
|
||||||
from ietf.doc.models import Document
|
from ietf.doc.models import Document
|
||||||
from ietf.name.models import RoleName
|
from ietf.name.models import RoleName
|
||||||
|
from ietf.utils.models import ForeignKey, OneToOneField
|
||||||
|
|
||||||
class Message(models.Model):
|
class Message(models.Model):
|
||||||
time = models.DateTimeField(default=datetime.datetime.now)
|
time = models.DateTimeField(default=datetime.datetime.now)
|
||||||
by = models.ForeignKey(Person)
|
by = ForeignKey(Person)
|
||||||
|
|
||||||
subject = models.CharField(max_length=255)
|
subject = models.CharField(max_length=255)
|
||||||
frm = models.CharField(max_length=255)
|
frm = models.CharField(max_length=255)
|
||||||
|
@ -35,7 +36,7 @@ class Message(models.Model):
|
||||||
|
|
||||||
|
|
||||||
class MessageAttachment(models.Model):
|
class MessageAttachment(models.Model):
|
||||||
message = models.ForeignKey(Message)
|
message = ForeignKey(Message)
|
||||||
filename = models.CharField(max_length=255, db_index=True, blank=True)
|
filename = models.CharField(max_length=255, db_index=True, blank=True)
|
||||||
content_type = models.CharField(max_length=255, blank=True)
|
content_type = models.CharField(max_length=255, blank=True)
|
||||||
encoding = models.CharField(max_length=255, blank=True)
|
encoding = models.CharField(max_length=255, blank=True)
|
||||||
|
@ -48,9 +49,9 @@ class MessageAttachment(models.Model):
|
||||||
|
|
||||||
class SendQueue(models.Model):
|
class SendQueue(models.Model):
|
||||||
time = models.DateTimeField(default=datetime.datetime.now)
|
time = models.DateTimeField(default=datetime.datetime.now)
|
||||||
by = models.ForeignKey(Person)
|
by = ForeignKey(Person)
|
||||||
|
|
||||||
message = models.ForeignKey(Message)
|
message = ForeignKey(Message)
|
||||||
|
|
||||||
send_at = models.DateTimeField(blank=True, null=True)
|
send_at = models.DateTimeField(blank=True, null=True)
|
||||||
sent_at = models.DateTimeField(blank=True, null=True)
|
sent_at = models.DateTimeField(blank=True, null=True)
|
||||||
|
@ -65,8 +66,8 @@ class SendQueue(models.Model):
|
||||||
|
|
||||||
|
|
||||||
class AnnouncementFrom(models.Model):
|
class AnnouncementFrom(models.Model):
|
||||||
name = models.ForeignKey(RoleName)
|
name = ForeignKey(RoleName)
|
||||||
group = models.ForeignKey(Group)
|
group = ForeignKey(Group)
|
||||||
address = models.CharField(max_length=255)
|
address = models.CharField(max_length=255)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
|
from ietf.utils.models import ForeignKey, OneToOneField
|
||||||
|
|
||||||
class NameModel(models.Model):
|
class NameModel(models.Model):
|
||||||
slug = models.CharField(max_length=32, primary_key=True)
|
slug = models.CharField(max_length=32, primary_key=True)
|
||||||
name = models.CharField(max_length=255)
|
name = models.CharField(max_length=255)
|
||||||
|
@ -105,7 +107,7 @@ class ContinentName(NameModel):
|
||||||
"Africa, Antarctica, Asia, ..."
|
"Africa, Antarctica, Asia, ..."
|
||||||
class CountryName(NameModel):
|
class CountryName(NameModel):
|
||||||
"Afghanistan, Aaland Islands, Albania, ..."
|
"Afghanistan, Aaland Islands, Albania, ..."
|
||||||
continent = models.ForeignKey(ContinentName)
|
continent = ForeignKey(ContinentName)
|
||||||
in_eu = models.BooleanField(verbose_name="In EU", default=False)
|
in_eu = models.BooleanField(verbose_name="In EU", default=False)
|
||||||
class ImportantDateName(NameModel):
|
class ImportantDateName(NameModel):
|
||||||
"Registration Opens, Scheduling Opens, ID Cutoff, ..."
|
"Registration Opens, Scheduling Opens, ID Cutoff, ..."
|
||||||
|
|
|
@ -23,7 +23,7 @@ from ietf.nomcom.utils import (initialize_templates_for_group,
|
||||||
initialize_requirements_for_position,
|
initialize_requirements_for_position,
|
||||||
initialize_description_for_topic,
|
initialize_description_for_topic,
|
||||||
delete_nomcom_templates)
|
delete_nomcom_templates)
|
||||||
|
from ietf.utils.models import ForeignKey, OneToOneField
|
||||||
from ietf.utils.storage import NoLocationMigrationFileSystemStorage
|
from ietf.utils.storage import NoLocationMigrationFileSystemStorage
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,14 +33,14 @@ def upload_path_handler(instance, filename):
|
||||||
|
|
||||||
class ReminderDates(models.Model):
|
class ReminderDates(models.Model):
|
||||||
date = models.DateField()
|
date = models.DateField()
|
||||||
nomcom = models.ForeignKey('NomCom')
|
nomcom = ForeignKey('NomCom')
|
||||||
|
|
||||||
|
|
||||||
class NomCom(models.Model):
|
class NomCom(models.Model):
|
||||||
public_key = models.FileField(storage=NoLocationMigrationFileSystemStorage(location=settings.NOMCOM_PUBLIC_KEYS_DIR),
|
public_key = models.FileField(storage=NoLocationMigrationFileSystemStorage(location=settings.NOMCOM_PUBLIC_KEYS_DIR),
|
||||||
upload_to=upload_path_handler, blank=True, null=True)
|
upload_to=upload_path_handler, blank=True, null=True)
|
||||||
|
|
||||||
group = models.ForeignKey(Group)
|
group = ForeignKey(Group)
|
||||||
send_questionnaire = models.BooleanField(verbose_name='Send questionnaires automatically', default=False,
|
send_questionnaire = models.BooleanField(verbose_name='Send questionnaires automatically', default=False,
|
||||||
help_text='If you check this box, questionnaires are sent automatically after nominations.')
|
help_text='If you check this box, questionnaires are sent automatically after nominations.')
|
||||||
reminder_interval = models.PositiveIntegerField(help_text='If the nomcom user sets the interval field then a cron command will '
|
reminder_interval = models.PositiveIntegerField(help_text='If the nomcom user sets the interval field then a cron command will '
|
||||||
|
@ -83,14 +83,14 @@ post_delete.connect(delete_nomcom, sender=NomCom)
|
||||||
|
|
||||||
|
|
||||||
class Nomination(models.Model):
|
class Nomination(models.Model):
|
||||||
position = models.ForeignKey('Position')
|
position = ForeignKey('Position')
|
||||||
candidate_name = models.CharField(verbose_name='Candidate name', max_length=255)
|
candidate_name = models.CharField(verbose_name='Candidate name', max_length=255)
|
||||||
candidate_email = models.EmailField(verbose_name='Candidate email', max_length=255)
|
candidate_email = models.EmailField(verbose_name='Candidate email', max_length=255)
|
||||||
candidate_phone = models.CharField(verbose_name='Candidate phone', blank=True, max_length=255)
|
candidate_phone = models.CharField(verbose_name='Candidate phone', blank=True, max_length=255)
|
||||||
nominee = models.ForeignKey('Nominee')
|
nominee = ForeignKey('Nominee')
|
||||||
comments = models.ForeignKey('Feedback')
|
comments = ForeignKey('Feedback')
|
||||||
nominator_email = models.EmailField(verbose_name='Nominator Email', blank=True)
|
nominator_email = models.EmailField(verbose_name='Nominator Email', blank=True)
|
||||||
user = models.ForeignKey(User, editable=False)
|
user = ForeignKey(User, editable=False)
|
||||||
time = models.DateTimeField(auto_now_add=True)
|
time = models.DateTimeField(auto_now_add=True)
|
||||||
share_nominator = models.BooleanField(verbose_name='Share nominator name with candidate', default=False,
|
share_nominator = models.BooleanField(verbose_name='Share nominator name with candidate', default=False,
|
||||||
help_text='Check this box to allow the NomCom to let the '
|
help_text='Check this box to allow the NomCom to let the '
|
||||||
|
@ -108,11 +108,11 @@ class Nomination(models.Model):
|
||||||
|
|
||||||
class Nominee(models.Model):
|
class Nominee(models.Model):
|
||||||
|
|
||||||
email = models.ForeignKey(Email)
|
email = ForeignKey(Email)
|
||||||
person = models.ForeignKey(Person, blank=True, null=True)
|
person = ForeignKey(Person, blank=True, null=True)
|
||||||
nominee_position = models.ManyToManyField('Position', through='NomineePosition')
|
nominee_position = models.ManyToManyField('Position', through='NomineePosition')
|
||||||
duplicated = models.ForeignKey('Nominee', blank=True, null=True)
|
duplicated = ForeignKey('Nominee', blank=True, null=True)
|
||||||
nomcom = models.ForeignKey('NomCom')
|
nomcom = ForeignKey('NomCom')
|
||||||
|
|
||||||
objects = NomineeManager()
|
objects = NomineeManager()
|
||||||
|
|
||||||
|
@ -136,9 +136,9 @@ class Nominee(models.Model):
|
||||||
|
|
||||||
class NomineePosition(models.Model):
|
class NomineePosition(models.Model):
|
||||||
|
|
||||||
position = models.ForeignKey('Position')
|
position = ForeignKey('Position')
|
||||||
nominee = models.ForeignKey('Nominee')
|
nominee = ForeignKey('Nominee')
|
||||||
state = models.ForeignKey(NomineePositionStateName)
|
state = ForeignKey(NomineePositionStateName)
|
||||||
time = models.DateTimeField(auto_now_add=True)
|
time = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
objects = NomineePositionManager()
|
objects = NomineePositionManager()
|
||||||
|
@ -164,10 +164,10 @@ class NomineePosition(models.Model):
|
||||||
|
|
||||||
|
|
||||||
class Position(models.Model):
|
class Position(models.Model):
|
||||||
nomcom = models.ForeignKey('NomCom')
|
nomcom = ForeignKey('NomCom')
|
||||||
name = models.CharField(verbose_name='Name', max_length=255, help_text='This short description will appear on the Nomination and Feedback pages. Be as descriptive as necessary. Past examples: "Transport AD", "IAB Member"')
|
name = models.CharField(verbose_name='Name', max_length=255, help_text='This short description will appear on the Nomination and Feedback pages. Be as descriptive as necessary. Past examples: "Transport AD", "IAB Member"')
|
||||||
requirement = models.ForeignKey(DBTemplate, related_name='requirement', null=True, editable=False)
|
requirement = ForeignKey(DBTemplate, related_name='requirement', null=True, editable=False)
|
||||||
questionnaire = models.ForeignKey(DBTemplate, related_name='questionnaire', null=True, editable=False)
|
questionnaire = ForeignKey(DBTemplate, related_name='questionnaire', null=True, editable=False)
|
||||||
is_open = models.BooleanField(verbose_name='Is open', default=False, help_text="Set is_open when the nomcom is working on a position. Clear it when an appointment is confirmed.")
|
is_open = models.BooleanField(verbose_name='Is open', default=False, help_text="Set is_open when the nomcom is working on a position. Clear it when an appointment is confirmed.")
|
||||||
accepting_nominations = models.BooleanField(verbose_name='Is accepting nominations', default=False)
|
accepting_nominations = models.BooleanField(verbose_name='Is accepting nominations', default=False)
|
||||||
accepting_feedback = models.BooleanField(verbose_name='Is accepting feedback', default=False)
|
accepting_feedback = models.BooleanField(verbose_name='Is accepting feedback', default=False)
|
||||||
|
@ -210,11 +210,11 @@ class Position(models.Model):
|
||||||
return rendered
|
return rendered
|
||||||
|
|
||||||
class Topic(models.Model):
|
class Topic(models.Model):
|
||||||
nomcom = models.ForeignKey('NomCom')
|
nomcom = ForeignKey('NomCom')
|
||||||
subject = models.CharField(verbose_name='Name', max_length=255, help_text='This short description will appear on the Feedback pages.')
|
subject = models.CharField(verbose_name='Name', max_length=255, help_text='This short description will appear on the Feedback pages.')
|
||||||
description = models.ForeignKey(DBTemplate, related_name='description', null=True, editable=False)
|
description = ForeignKey(DBTemplate, related_name='description', null=True, editable=False)
|
||||||
accepting_feedback = models.BooleanField(verbose_name='Is accepting feedback', default=False)
|
accepting_feedback = models.BooleanField(verbose_name='Is accepting feedback', default=False)
|
||||||
audience = models.ForeignKey(TopicAudienceName)
|
audience = ForeignKey(TopicAudienceName)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name_plural = 'Topics'
|
verbose_name_plural = 'Topics'
|
||||||
|
@ -239,15 +239,15 @@ class Topic(models.Model):
|
||||||
return rendered
|
return rendered
|
||||||
|
|
||||||
class Feedback(models.Model):
|
class Feedback(models.Model):
|
||||||
nomcom = models.ForeignKey('NomCom')
|
nomcom = ForeignKey('NomCom')
|
||||||
author = models.EmailField(verbose_name='Author', blank=True)
|
author = models.EmailField(verbose_name='Author', blank=True)
|
||||||
positions = models.ManyToManyField('Position', blank=True)
|
positions = models.ManyToManyField('Position', blank=True)
|
||||||
nominees = models.ManyToManyField('Nominee', blank=True)
|
nominees = models.ManyToManyField('Nominee', blank=True)
|
||||||
topics = models.ManyToManyField('Topic', blank=True)
|
topics = models.ManyToManyField('Topic', blank=True)
|
||||||
subject = models.TextField(verbose_name='Subject', blank=True)
|
subject = models.TextField(verbose_name='Subject', blank=True)
|
||||||
comments = EncryptedTextField(verbose_name='Comments')
|
comments = EncryptedTextField(verbose_name='Comments')
|
||||||
type = models.ForeignKey(FeedbackTypeName, blank=True, null=True)
|
type = ForeignKey(FeedbackTypeName, blank=True, null=True)
|
||||||
user = models.ForeignKey(User, editable=False, blank=True, null=True)
|
user = ForeignKey(User, editable=False, blank=True, null=True)
|
||||||
time = models.DateTimeField(auto_now_add=True)
|
time = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
objects = FeedbackManager()
|
objects = FeedbackManager()
|
||||||
|
@ -259,12 +259,12 @@ class Feedback(models.Model):
|
||||||
ordering = ['time']
|
ordering = ['time']
|
||||||
|
|
||||||
class FeedbackLastSeen(models.Model):
|
class FeedbackLastSeen(models.Model):
|
||||||
reviewer = models.ForeignKey(Person)
|
reviewer = ForeignKey(Person)
|
||||||
nominee = models.ForeignKey(Nominee)
|
nominee = ForeignKey(Nominee)
|
||||||
time = models.DateTimeField(auto_now=True)
|
time = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
class TopicFeedbackLastSeen(models.Model):
|
class TopicFeedbackLastSeen(models.Model):
|
||||||
reviewer = models.ForeignKey(Person)
|
reviewer = ForeignKey(Person)
|
||||||
topic = models.ForeignKey(Topic)
|
topic = ForeignKey(Topic)
|
||||||
time = models.DateTimeField(auto_now=True)
|
time = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ from ietf.utils.mail import send_mail_preformatted
|
||||||
from ietf.utils.storage import NoLocationMigrationFileSystemStorage
|
from ietf.utils.storage import NoLocationMigrationFileSystemStorage
|
||||||
from ietf.utils.mail import formataddr
|
from ietf.utils.mail import formataddr
|
||||||
from ietf.person.name import unidecode_name
|
from ietf.person.name import unidecode_name
|
||||||
|
from ietf.utils.models import ForeignKey, OneToOneField
|
||||||
|
|
||||||
|
|
||||||
class PersonInfo(models.Model):
|
class PersonInfo(models.Model):
|
||||||
|
@ -157,7 +158,7 @@ class PersonInfo(models.Model):
|
||||||
abstract = True
|
abstract = True
|
||||||
|
|
||||||
class Person(PersonInfo):
|
class Person(PersonInfo):
|
||||||
user = models.OneToOneField(User, blank=True, null=True)
|
user = OneToOneField(User, blank=True, null=True)
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
created = not self.pk
|
created = not self.pk
|
||||||
|
@ -197,8 +198,8 @@ class Person(PersonInfo):
|
||||||
return ct1
|
return ct1
|
||||||
|
|
||||||
class PersonHistory(PersonInfo):
|
class PersonHistory(PersonInfo):
|
||||||
person = models.ForeignKey(Person, related_name="history_set")
|
person = ForeignKey(Person, related_name="history_set")
|
||||||
user = models.ForeignKey(User, blank=True, null=True)
|
user = ForeignKey(User, blank=True, null=True)
|
||||||
|
|
||||||
class Alias(models.Model):
|
class Alias(models.Model):
|
||||||
"""This is used for alternative forms of a name. This is the
|
"""This is used for alternative forms of a name. This is the
|
||||||
|
@ -206,7 +207,7 @@ class Alias(models.Model):
|
||||||
unicode form (and ascii form, if different) of a name which is
|
unicode form (and ascii form, if different) of a name which is
|
||||||
recorded in the Person record.
|
recorded in the Person record.
|
||||||
"""
|
"""
|
||||||
person = models.ForeignKey(Person)
|
person = ForeignKey(Person)
|
||||||
name = models.CharField(max_length=255, db_index=True)
|
name = models.CharField(max_length=255, db_index=True)
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
|
@ -229,7 +230,7 @@ class Alias(models.Model):
|
||||||
|
|
||||||
class Email(models.Model):
|
class Email(models.Model):
|
||||||
address = models.CharField(max_length=64, primary_key=True, validators=[validate_email])
|
address = models.CharField(max_length=64, primary_key=True, validators=[validate_email])
|
||||||
person = models.ForeignKey(Person, null=True)
|
person = ForeignKey(Person, null=True)
|
||||||
time = models.DateTimeField(auto_now_add=True)
|
time = models.DateTimeField(auto_now_add=True)
|
||||||
primary = models.BooleanField(default=False)
|
primary = models.BooleanField(default=False)
|
||||||
active = models.BooleanField(default=True) # Old email addresses are *not* purged, as history
|
active = models.BooleanField(default=True) # Old email addresses are *not* purged, as history
|
||||||
|
@ -290,7 +291,7 @@ PERSON_API_KEY_ENDPOINTS = [
|
||||||
]
|
]
|
||||||
|
|
||||||
class PersonalApiKey(models.Model):
|
class PersonalApiKey(models.Model):
|
||||||
person = models.ForeignKey(Person, related_name='apikeys')
|
person = ForeignKey(Person, related_name='apikeys')
|
||||||
endpoint = models.CharField(max_length=128, null=False, blank=False, choices=PERSON_API_KEY_ENDPOINTS)
|
endpoint = models.CharField(max_length=128, null=False, blank=False, choices=PERSON_API_KEY_ENDPOINTS)
|
||||||
created = models.DateTimeField(default=datetime.datetime.now, null=False)
|
created = models.DateTimeField(default=datetime.datetime.now, null=False)
|
||||||
valid = models.BooleanField(default=True)
|
valid = models.BooleanField(default=True)
|
||||||
|
@ -331,7 +332,7 @@ PERSON_EVENT_CHOICES = [
|
||||||
]
|
]
|
||||||
|
|
||||||
class PersonEvent(models.Model):
|
class PersonEvent(models.Model):
|
||||||
person = models.ForeignKey(Person)
|
person = ForeignKey(Person)
|
||||||
time = models.DateTimeField(default=datetime.datetime.now, help_text="When the event happened")
|
time = models.DateTimeField(default=datetime.datetime.now, help_text="When the event happened")
|
||||||
type = models.CharField(max_length=50, choices=PERSON_EVENT_CHOICES)
|
type = models.CharField(max_length=50, choices=PERSON_EVENT_CHOICES)
|
||||||
desc = models.TextField()
|
desc = models.TextField()
|
||||||
|
@ -343,5 +344,5 @@ class PersonEvent(models.Model):
|
||||||
ordering = ['-time', '-id']
|
ordering = ['-time', '-id']
|
||||||
|
|
||||||
class PersonApiKeyEvent(PersonEvent):
|
class PersonApiKeyEvent(PersonEvent):
|
||||||
key = models.ForeignKey(PersonalApiKey)
|
key = ForeignKey(PersonalApiKey)
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
|
from ietf.utils.models import ForeignKey, OneToOneField
|
||||||
|
|
||||||
class Redirect(models.Model):
|
class Redirect(models.Model):
|
||||||
"""Mapping of CGI script to url. The "rest" is a
|
"""Mapping of CGI script to url. The "rest" is a
|
||||||
sprintf-style string with %(param)s entries to insert
|
sprintf-style string with %(param)s entries to insert
|
||||||
|
@ -42,8 +44,8 @@ class Command(models.Model):
|
||||||
"""
|
"""
|
||||||
command = models.CharField(max_length=50)
|
command = models.CharField(max_length=50)
|
||||||
url = models.CharField(max_length=50, blank=True)
|
url = models.CharField(max_length=50, blank=True)
|
||||||
script = models.ForeignKey(Redirect, related_name='commands', editable=False)
|
script = ForeignKey(Redirect, related_name='commands', editable=False)
|
||||||
suffix = models.ForeignKey(Suffix, null=True, blank=True)
|
suffix = ForeignKey(Suffix, null=True, blank=True)
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
ret = "%s?command=%s" % (self.script.cgi, self.command)
|
ret = "%s?command=%s" % (self.script.cgi, self.command)
|
||||||
if self.suffix_id:
|
if self.suffix_id:
|
||||||
|
|
|
@ -7,11 +7,12 @@ from ietf.group.models import Group
|
||||||
from ietf.person.models import Person, Email
|
from ietf.person.models import Person, Email
|
||||||
from ietf.name.models import ReviewTypeName, ReviewRequestStateName, ReviewResultName
|
from ietf.name.models import ReviewTypeName, ReviewRequestStateName, ReviewResultName
|
||||||
from ietf.utils.validators import validate_regular_expression_string
|
from ietf.utils.validators import validate_regular_expression_string
|
||||||
|
from ietf.utils.models import ForeignKey, OneToOneField
|
||||||
|
|
||||||
class ReviewerSettings(models.Model):
|
class ReviewerSettings(models.Model):
|
||||||
"""Keeps track of admin data associated with a reviewer in a team."""
|
"""Keeps track of admin data associated with a reviewer in a team."""
|
||||||
team = models.ForeignKey(Group, limit_choices_to=~models.Q(reviewteamsettings=None))
|
team = ForeignKey(Group, limit_choices_to=~models.Q(reviewteamsettings=None))
|
||||||
person = models.ForeignKey(Person)
|
person = ForeignKey(Person)
|
||||||
INTERVALS = [
|
INTERVALS = [
|
||||||
(7, "Once per week"),
|
(7, "Once per week"),
|
||||||
(14, "Once per fortnight"),
|
(14, "Once per fortnight"),
|
||||||
|
@ -35,8 +36,8 @@ class ReviewerSettings(models.Model):
|
||||||
|
|
||||||
class ReviewSecretarySettings(models.Model):
|
class ReviewSecretarySettings(models.Model):
|
||||||
"""Keeps track of admin data associated with a secretary in a team."""
|
"""Keeps track of admin data associated with a secretary in a team."""
|
||||||
team = models.ForeignKey(Group, limit_choices_to=~models.Q(reviewteamsettings=None))
|
team = ForeignKey(Group, limit_choices_to=~models.Q(reviewteamsettings=None))
|
||||||
person = models.ForeignKey(Person)
|
person = ForeignKey(Person)
|
||||||
remind_days_before_deadline = models.IntegerField(null=True, blank=True, help_text="To get an email reminder in case a reviewer forgets to do an assigned review, enter the number of days before review deadline you want to receive it. Clear the field if you don't want a reminder.")
|
remind_days_before_deadline = models.IntegerField(null=True, blank=True, help_text="To get an email reminder in case a reviewer forgets to do an assigned review, enter the number of days before review deadline you want to receive it. Clear the field if you don't want a reminder.")
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
|
@ -46,8 +47,8 @@ class ReviewSecretarySettings(models.Model):
|
||||||
verbose_name_plural = "review secretary settings"
|
verbose_name_plural = "review secretary settings"
|
||||||
|
|
||||||
class UnavailablePeriod(models.Model):
|
class UnavailablePeriod(models.Model):
|
||||||
team = models.ForeignKey(Group, limit_choices_to=~models.Q(reviewteamsettings=None))
|
team = ForeignKey(Group, limit_choices_to=~models.Q(reviewteamsettings=None))
|
||||||
person = models.ForeignKey(Person)
|
person = ForeignKey(Person)
|
||||||
start_date = models.DateField(default=datetime.date.today, null=True, help_text="Choose the start date so that you can still do a review if it's assigned just before the start date - this usually means you should mark yourself unavailable for assignment some time before you are actually away.")
|
start_date = models.DateField(default=datetime.date.today, null=True, help_text="Choose the start date so that you can still do a review if it's assigned just before the start date - this usually means you should mark yourself unavailable for assignment some time before you are actually away.")
|
||||||
end_date = models.DateField(blank=True, null=True, help_text="Leaving the end date blank means that the period continues indefinitely. You can end it later.")
|
end_date = models.DateField(blank=True, null=True, help_text="Leaving the end date blank means that the period continues indefinitely. You can end it later.")
|
||||||
AVAILABILITY_CHOICES = [
|
AVAILABILITY_CHOICES = [
|
||||||
|
@ -77,9 +78,9 @@ class UnavailablePeriod(models.Model):
|
||||||
class ReviewWish(models.Model):
|
class ReviewWish(models.Model):
|
||||||
"""Reviewer wishes to review a document when it becomes available for review."""
|
"""Reviewer wishes to review a document when it becomes available for review."""
|
||||||
time = models.DateTimeField(default=datetime.datetime.now)
|
time = models.DateTimeField(default=datetime.datetime.now)
|
||||||
team = models.ForeignKey(Group, limit_choices_to=~models.Q(reviewteamsettings=None))
|
team = ForeignKey(Group, limit_choices_to=~models.Q(reviewteamsettings=None))
|
||||||
person = models.ForeignKey(Person)
|
person = ForeignKey(Person)
|
||||||
doc = models.ForeignKey(Document)
|
doc = ForeignKey(Document)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u"{} wishes to review {} in {}".format(self.person, self.doc.name, self.team.acronym)
|
return u"{} wishes to review {} in {}".format(self.person, self.doc.name, self.team.acronym)
|
||||||
|
@ -89,8 +90,8 @@ class ReviewWish(models.Model):
|
||||||
|
|
||||||
|
|
||||||
class NextReviewerInTeam(models.Model):
|
class NextReviewerInTeam(models.Model):
|
||||||
team = models.ForeignKey(Group, limit_choices_to=~models.Q(reviewteamsettings=None))
|
team = ForeignKey(Group, limit_choices_to=~models.Q(reviewteamsettings=None))
|
||||||
next_reviewer = models.ForeignKey(Person)
|
next_reviewer = ForeignKey(Person)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u"{} next in {}".format(self.next_reviewer, self.team)
|
return u"{} next in {}".format(self.next_reviewer, self.team)
|
||||||
|
@ -103,18 +104,18 @@ class ReviewRequest(models.Model):
|
||||||
"""Represents a request for a review and the process it goes through.
|
"""Represents a request for a review and the process it goes through.
|
||||||
There should be one ReviewRequest entered for each combination of
|
There should be one ReviewRequest entered for each combination of
|
||||||
document, rev, and reviewer."""
|
document, rev, and reviewer."""
|
||||||
state = models.ForeignKey(ReviewRequestStateName)
|
state = ForeignKey(ReviewRequestStateName)
|
||||||
|
|
||||||
old_id = models.IntegerField(blank=True, null=True, help_text="ID in previous review system") # FIXME: remove this when everything has been migrated
|
old_id = models.IntegerField(blank=True, null=True, help_text="ID in previous review system") # FIXME: remove this when everything has been migrated
|
||||||
|
|
||||||
# Fields filled in on the initial record creation - these
|
# Fields filled in on the initial record creation - these
|
||||||
# constitute the request part.
|
# constitute the request part.
|
||||||
time = models.DateTimeField(default=datetime.datetime.now)
|
time = models.DateTimeField(default=datetime.datetime.now)
|
||||||
type = models.ForeignKey(ReviewTypeName)
|
type = ForeignKey(ReviewTypeName)
|
||||||
doc = models.ForeignKey(Document, related_name='reviewrequest_set')
|
doc = ForeignKey(Document, related_name='reviewrequest_set')
|
||||||
team = models.ForeignKey(Group, limit_choices_to=~models.Q(reviewteamsettings=None))
|
team = ForeignKey(Group, limit_choices_to=~models.Q(reviewteamsettings=None))
|
||||||
deadline = models.DateField()
|
deadline = models.DateField()
|
||||||
requested_by = models.ForeignKey(Person)
|
requested_by = ForeignKey(Person)
|
||||||
requested_rev = models.CharField(verbose_name="requested revision", max_length=16, blank=True, help_text="Fill in if a specific revision is to be reviewed, e.g. 02")
|
requested_rev = models.CharField(verbose_name="requested revision", max_length=16, blank=True, help_text="Fill in if a specific revision is to be reviewed, e.g. 02")
|
||||||
comment = models.TextField(verbose_name="Requester's comments and instructions", max_length=2048, blank=True, help_text="Provide any additional information to show to the review team secretary and reviewer", default='')
|
comment = models.TextField(verbose_name="Requester's comments and instructions", max_length=2048, blank=True, help_text="Provide any additional information to show to the review team secretary and reviewer", default='')
|
||||||
|
|
||||||
|
@ -123,11 +124,11 @@ class ReviewRequest(models.Model):
|
||||||
# requested/assigned, any changes to the assignment happens by
|
# requested/assigned, any changes to the assignment happens by
|
||||||
# closing down the current request and making a new one, copying
|
# closing down the current request and making a new one, copying
|
||||||
# the request-part fields above.
|
# the request-part fields above.
|
||||||
reviewer = models.ForeignKey(Email, blank=True, null=True)
|
reviewer = ForeignKey(Email, blank=True, null=True)
|
||||||
|
|
||||||
review = models.OneToOneField(Document, blank=True, null=True)
|
review = OneToOneField(Document, blank=True, null=True)
|
||||||
reviewed_rev = models.CharField(verbose_name="reviewed revision", max_length=16, blank=True)
|
reviewed_rev = models.CharField(verbose_name="reviewed revision", max_length=16, blank=True)
|
||||||
result = models.ForeignKey(ReviewResultName, blank=True, null=True)
|
result = ForeignKey(ReviewResultName, blank=True, null=True)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u"%s review on %s by %s %s" % (self.type, self.doc, self.team, self.state)
|
return u"%s review on %s by %s %s" % (self.type, self.doc, self.team, self.state)
|
||||||
|
@ -155,7 +156,7 @@ def get_default_review_results():
|
||||||
|
|
||||||
class ReviewTeamSettings(models.Model):
|
class ReviewTeamSettings(models.Model):
|
||||||
"""Holds configuration specific to groups that are review teams"""
|
"""Holds configuration specific to groups that are review teams"""
|
||||||
group = models.OneToOneField(Group)
|
group = OneToOneField(Group)
|
||||||
autosuggest = models.BooleanField(default=True, verbose_name="Automatically suggest possible review requests")
|
autosuggest = models.BooleanField(default=True, verbose_name="Automatically suggest possible review requests")
|
||||||
review_types = models.ManyToManyField(ReviewTypeName, default=get_default_review_types)
|
review_types = models.ManyToManyField(ReviewTypeName, default=get_default_review_types)
|
||||||
review_results = models.ManyToManyField(ReviewResultName, default=get_default_review_results)
|
review_results = models.ManyToManyField(ReviewResultName, default=get_default_review_results)
|
||||||
|
|
|
@ -11,7 +11,7 @@ class GeneralInfo(models.Model):
|
||||||
db_table = u'general_info'
|
db_table = u'general_info'
|
||||||
|
|
||||||
class MeetingVenue(models.Model):
|
class MeetingVenue(models.Model):
|
||||||
meeting_num = models.ForeignKey(Meeting, db_column='meeting_num', unique=True, editable=False)
|
meeting_num = ForeignKey(Meeting, db_column='meeting_num', unique=True, editable=False)
|
||||||
break_area_name = models.CharField(max_length=255)
|
break_area_name = models.CharField(max_length=255)
|
||||||
reg_area_name = models.CharField(max_length=255)
|
reg_area_name = models.CharField(max_length=255)
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
@ -32,8 +32,8 @@ class NonSessionRef(models.Model):
|
||||||
class NonSession(models.Model):
|
class NonSession(models.Model):
|
||||||
non_session_id = models.AutoField(primary_key=True, editable=False)
|
non_session_id = models.AutoField(primary_key=True, editable=False)
|
||||||
day_id = models.IntegerField(blank=True, null=True, editable=False)
|
day_id = models.IntegerField(blank=True, null=True, editable=False)
|
||||||
non_session_ref = models.ForeignKey(NonSessionRef, editable=False)
|
non_session_ref = ForeignKey(NonSessionRef, editable=False)
|
||||||
meeting = models.ForeignKey(Meeting, db_column='meeting_num', editable=False)
|
meeting = ForeignKey(Meeting, db_column='meeting_num', editable=False)
|
||||||
time_desc = models.CharField(blank=True, max_length=75, default='0')
|
time_desc = models.CharField(blank=True, max_length=75, default='0')
|
||||||
show_break_location = models.BooleanField(editable=False, default=True)
|
show_break_location = models.BooleanField(editable=False, default=True)
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
@ -50,4 +50,4 @@ class NonSession(models.Model):
|
||||||
db_table = 'non_session'
|
db_table = 'non_session'
|
||||||
verbose_name = "Meeting non-session slot"
|
verbose_name = "Meeting non-session slot"
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -4,6 +4,7 @@ from django.conf import settings
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
from ietf.meeting.models import Meeting
|
from ietf.meeting.models import Meeting
|
||||||
|
from ietf.utils.models import ForeignKey, OneToOneField
|
||||||
|
|
||||||
|
|
||||||
class InterimManager(models.Manager):
|
class InterimManager(models.Manager):
|
||||||
|
|
|
@ -1,7 +1,13 @@
|
||||||
|
# Copyright The IETF Trust 2017, All Rights Reserved
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
|
import debug # pyflakes:ignore
|
||||||
|
|
||||||
from ietf.meeting.models import Meeting
|
from ietf.meeting.models import Meeting
|
||||||
from ietf.name.models import CountryName
|
from ietf.name.models import CountryName
|
||||||
from ietf.person.models import Person
|
from ietf.person.models import Person
|
||||||
|
from ietf.utils.models import ForeignKey, OneToOneField
|
||||||
|
|
||||||
|
|
||||||
class AffiliationAlias(models.Model):
|
class AffiliationAlias(models.Model):
|
||||||
|
@ -34,7 +40,7 @@ class CountryAlias(models.Model):
|
||||||
purposes."""
|
purposes."""
|
||||||
|
|
||||||
alias = models.CharField(max_length=255, help_text="Note that lower-case aliases are matched case-insensitive while aliases with at least one uppercase letter is matched case-sensitive. So 'United States' is best entered as 'united states' so it both matches 'United States' and 'United states' and 'UNITED STATES', whereas 'US' is best entered as 'US' so it doesn't accidentally match an ordinary word like 'us'.")
|
alias = models.CharField(max_length=255, help_text="Note that lower-case aliases are matched case-insensitive while aliases with at least one uppercase letter is matched case-sensitive. So 'United States' is best entered as 'united states' so it both matches 'United States' and 'United states' and 'UNITED STATES', whereas 'US' is best entered as 'US' so it doesn't accidentally match an ordinary word like 'us'.")
|
||||||
country = models.ForeignKey(CountryName, max_length=255)
|
country = ForeignKey(CountryName, max_length=255)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u"{} -> {}".format(self.alias, self.country.name)
|
return u"{} -> {}".format(self.alias, self.country.name)
|
||||||
|
@ -44,12 +50,12 @@ class CountryAlias(models.Model):
|
||||||
|
|
||||||
class MeetingRegistration(models.Model):
|
class MeetingRegistration(models.Model):
|
||||||
"""Registration attendee records from the IETF registration system"""
|
"""Registration attendee records from the IETF registration system"""
|
||||||
meeting = models.ForeignKey(Meeting)
|
meeting = ForeignKey(Meeting)
|
||||||
first_name = models.CharField(max_length=255)
|
first_name = models.CharField(max_length=255)
|
||||||
last_name = models.CharField(max_length=255)
|
last_name = models.CharField(max_length=255)
|
||||||
affiliation = models.CharField(blank=True, max_length=255)
|
affiliation = models.CharField(blank=True, max_length=255)
|
||||||
country_code = models.CharField(max_length=2) # ISO 3166
|
country_code = models.CharField(max_length=2) # ISO 3166
|
||||||
person = models.ForeignKey(Person, blank=True, null=True)
|
person = ForeignKey(Person, blank=True, null=True)
|
||||||
email = models.EmailField(blank=True, null=True)
|
email = models.EmailField(blank=True, null=True)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
|
|
|
@ -12,6 +12,7 @@ from ietf.group.models import Group
|
||||||
from ietf.message.models import Message
|
from ietf.message.models import Message
|
||||||
from ietf.name.models import DraftSubmissionStateName, FormalLanguageName
|
from ietf.name.models import DraftSubmissionStateName, FormalLanguageName
|
||||||
from ietf.utils.accesstoken import generate_random_key, generate_access_token
|
from ietf.utils.accesstoken import generate_random_key, generate_access_token
|
||||||
|
from ietf.utils.models import ForeignKey, OneToOneField
|
||||||
|
|
||||||
|
|
||||||
def parse_email_line(line):
|
def parse_email_line(line):
|
||||||
|
@ -23,7 +24,7 @@ def parse_email_line(line):
|
||||||
return dict(name=name, email=addr)
|
return dict(name=name, email=addr)
|
||||||
|
|
||||||
class Submission(models.Model):
|
class Submission(models.Model):
|
||||||
state = models.ForeignKey(DraftSubmissionStateName)
|
state = ForeignKey(DraftSubmissionStateName)
|
||||||
remote_ip = models.CharField(max_length=100, blank=True)
|
remote_ip = models.CharField(max_length=100, blank=True)
|
||||||
|
|
||||||
access_key = models.CharField(max_length=255, default=generate_random_key)
|
access_key = models.CharField(max_length=255, default=generate_random_key)
|
||||||
|
@ -31,7 +32,7 @@ class Submission(models.Model):
|
||||||
|
|
||||||
# draft metadata
|
# draft metadata
|
||||||
name = models.CharField(max_length=255, db_index=True)
|
name = models.CharField(max_length=255, db_index=True)
|
||||||
group = models.ForeignKey(Group, null=True, blank=True)
|
group = ForeignKey(Group, null=True, blank=True)
|
||||||
title = models.CharField(max_length=255, blank=True)
|
title = models.CharField(max_length=255, blank=True)
|
||||||
abstract = models.TextField(blank=True)
|
abstract = models.TextField(blank=True)
|
||||||
rev = models.CharField(max_length=3, blank=True)
|
rev = models.CharField(max_length=3, blank=True)
|
||||||
|
@ -51,7 +52,7 @@ class Submission(models.Model):
|
||||||
|
|
||||||
submitter = models.CharField(max_length=255, blank=True, help_text="Name and email of submitter, e.g. \"John Doe <john@example.org>\".")
|
submitter = models.CharField(max_length=255, blank=True, help_text="Name and email of submitter, e.g. \"John Doe <john@example.org>\".")
|
||||||
|
|
||||||
draft = models.ForeignKey(Document, null=True, blank=True)
|
draft = ForeignKey(Document, null=True, blank=True)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u"%s-%s" % (self.name, self.rev)
|
return u"%s-%s" % (self.name, self.rev)
|
||||||
|
@ -71,7 +72,7 @@ class Submission(models.Model):
|
||||||
|
|
||||||
class SubmissionCheck(models.Model):
|
class SubmissionCheck(models.Model):
|
||||||
time = models.DateTimeField(default=datetime.datetime.now)
|
time = models.DateTimeField(default=datetime.datetime.now)
|
||||||
submission = models.ForeignKey(Submission, related_name='checks')
|
submission = ForeignKey(Submission, related_name='checks')
|
||||||
checker = models.CharField(max_length=256, blank=True)
|
checker = models.CharField(max_length=256, blank=True)
|
||||||
passed = models.NullBooleanField(default=False)
|
passed = models.NullBooleanField(default=False)
|
||||||
message = models.TextField(null=True, blank=True)
|
message = models.TextField(null=True, blank=True)
|
||||||
|
@ -88,9 +89,9 @@ class SubmissionCheck(models.Model):
|
||||||
return self.errors != '[]'
|
return self.errors != '[]'
|
||||||
|
|
||||||
class SubmissionEvent(models.Model):
|
class SubmissionEvent(models.Model):
|
||||||
submission = models.ForeignKey(Submission)
|
submission = ForeignKey(Submission)
|
||||||
time = models.DateTimeField(default=datetime.datetime.now)
|
time = models.DateTimeField(default=datetime.datetime.now)
|
||||||
by = models.ForeignKey(Person, null=True, blank=True)
|
by = ForeignKey(Person, null=True, blank=True)
|
||||||
desc = models.TextField()
|
desc = models.TextField()
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
|
@ -103,16 +104,16 @@ class SubmissionEvent(models.Model):
|
||||||
class Preapproval(models.Model):
|
class Preapproval(models.Model):
|
||||||
"""Pre-approved draft submission name."""
|
"""Pre-approved draft submission name."""
|
||||||
name = models.CharField(max_length=255, db_index=True)
|
name = models.CharField(max_length=255, db_index=True)
|
||||||
by = models.ForeignKey(Person)
|
by = ForeignKey(Person)
|
||||||
time = models.DateTimeField(default=datetime.datetime.now)
|
time = models.DateTimeField(default=datetime.datetime.now)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
class SubmissionEmailEvent(SubmissionEvent):
|
class SubmissionEmailEvent(SubmissionEvent):
|
||||||
message = models.ForeignKey(Message, null=True, blank=True,related_name='manualevents')
|
message = ForeignKey(Message, null=True, blank=True,related_name='manualevents')
|
||||||
msgtype = models.CharField(max_length=25)
|
msgtype = models.CharField(max_length=25)
|
||||||
in_reply_to = models.ForeignKey(Message, null=True, blank=True,related_name='irtomanual')
|
in_reply_to = ForeignKey(Message, null=True, blank=True,related_name='irtomanual')
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u"%s %s by %s at %s" % (self.submission.name, self.desc, self.by.plain_name() if self.by else "(unknown)", self.time)
|
return u"%s %s by %s at %s" % (self.submission.name, self.desc, self.by.plain_name() if self.by else "(unknown)", self.time)
|
||||||
|
|
|
@ -37,7 +37,7 @@ sitemaps = {
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^$', views_search.frontpage),
|
url(r'^$', views_search.frontpage),
|
||||||
url(r'^accounts/', include('ietf.ietfauth.urls')),
|
url(r'^accounts/', include('ietf.ietfauth.urls')),
|
||||||
url(r'^admin/', include(admin.site.urls)),
|
url(r'^admin/', admin.site.urls),
|
||||||
url(r'^admin/docs/', include('django.contrib.admindocs.urls')),
|
url(r'^admin/docs/', include('django.contrib.admindocs.urls')),
|
||||||
url(r'^ann/', include('ietf.nomcom.redirect_ann_urls')),
|
url(r'^ann/', include('ietf.nomcom.redirect_ann_urls')),
|
||||||
url(r'^api/', include('ietf.api.urls')),
|
url(r'^api/', include('ietf.api.urls')),
|
||||||
|
|
|
@ -5,7 +5,7 @@ import html5lib
|
||||||
import bleach
|
import bleach
|
||||||
from html5lib import sanitizer, serializer, tokenizer, treebuilders, treewalkers
|
from html5lib import sanitizer, serializer, tokenizer, treebuilders, treewalkers
|
||||||
|
|
||||||
from django.utils.functional import allow_lazy
|
from django.utils.functional import keep_lazy
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
|
|
||||||
acceptable_elements = ('a', 'abbr', 'acronym', 'address', 'b', 'big',
|
acceptable_elements = ('a', 'abbr', 'acronym', 'address', 'b', 'big',
|
||||||
|
@ -67,7 +67,7 @@ def remove_tags(html, tags):
|
||||||
"""Returns the given HTML sanitized, and with the given tags removed."""
|
"""Returns the given HTML sanitized, and with the given tags removed."""
|
||||||
allowed = set(acceptable_elements) - set([ t.lower() for t in tags ])
|
allowed = set(acceptable_elements) - set([ t.lower() for t in tags ])
|
||||||
return bleach.clean(html, tags=allowed)
|
return bleach.clean(html, tags=allowed)
|
||||||
remove_tags = allow_lazy(remove_tags, six.text_type)
|
remove_tags = keep_lazy(remove_tags, six.text_type)
|
||||||
|
|
||||||
def clean_html(html):
|
def clean_html(html):
|
||||||
return bleach.clean(html)
|
return bleach.clean(html)
|
||||||
|
|
|
@ -5,7 +5,7 @@ import textwrap
|
||||||
import types
|
import types
|
||||||
import unicodedata
|
import unicodedata
|
||||||
|
|
||||||
from django.utils.functional import allow_lazy
|
from django.utils.functional import keep_lazy
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ def xslugify(value):
|
||||||
value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore').decode('ascii')
|
value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore').decode('ascii')
|
||||||
value = re.sub('[^\w\s/-]', '', value).strip().lower()
|
value = re.sub('[^\w\s/-]', '', value).strip().lower()
|
||||||
return mark_safe(re.sub('[-\s/]+', '-', value))
|
return mark_safe(re.sub('[-\s/]+', '-', value))
|
||||||
xslugify = allow_lazy(xslugify, six.text_type)
|
xslugify = keep_lazy(xslugify, six.text_type)
|
||||||
|
|
||||||
def strip_prefix(text, prefix):
|
def strip_prefix(text, prefix):
|
||||||
if text.startswith(prefix):
|
if text.startswith(prefix):
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
--- django/db/models/fields/__init__.py.old 2017-06-14 08:43:21.665812000 -0700
|
--- django/db/models/fields/__init__.py.old 2017-06-14 08:43:21.665812000 -0700
|
||||||
+++ django/db/models/fields/__init__.py 2017-12-17 14:34:03.023976702 -0800
|
+++ django/db/models/fields/__init__.py 2017-12-17 14:34:03.023976702 -0800
|
||||||
@@ -2323,7 +2323,7 @@
|
@@ -2344,7 +2344,7 @@
|
||||||
if self.has_default() and not callable(self.default):
|
if self.has_default() and not callable(self.default):
|
||||||
return self.default
|
return self.default
|
||||||
default = super(BinaryField, self).get_default()
|
default = super(BinaryField, self).get_default()
|
||||||
|
|
Loading…
Reference in a new issue