diff --git a/django/contrib/auth/__init__.py b/django/contrib/auth/__init__.py
index 9d24cc4f9..5244f5619 100644
--- a/django/contrib/auth/__init__.py
+++ b/django/contrib/auth/__init__.py
@@ -64,11 +64,15 @@ def login(request, user):
Persist a user id and a backend in the request. This way a user doesn't
have to reauthenticate on every request.
"""
+ from MySQLdb import OperationalError
if user is None:
user = request.user
# TODO: It would be nice to support different login methods, like signed cookies.
user.last_login = datetime.datetime.now()
- user.save()
+ try:
+ user.save()
+ except OperationalError:
+ pass
if SESSION_KEY in request.session:
if request.session[SESSION_KEY] != user.id:
diff --git a/django/contrib/auth/forms.py b/django/contrib/auth/forms.py
index ee09a626a..711dba529 100644
--- a/django/contrib/auth/forms.py
+++ b/django/contrib/auth/forms.py
@@ -11,8 +11,8 @@ class UserCreationForm(forms.ModelForm):
"""
A form that creates a user, with no privileges, from the given username and password.
"""
- username = forms.RegexField(label=_("Username"), max_length=30, regex=r'^[\w.@+-]+$',
- help_text = _("Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only."),
+ username = forms.RegexField(label=_("Username"), max_length=64, regex=r'^[\w.@+-]+$',
+ help_text = _("Required. 64 characters or fewer. Letters, digits and @/./+/-/_ only."),
error_messages = {'invalid': _("This value may contain only letters, numbers and @/./+/-/_ characters.")})
password1 = forms.CharField(label=_("Password"), widget=forms.PasswordInput)
password2 = forms.CharField(label=_("Password confirmation"), widget=forms.PasswordInput,
@@ -45,8 +45,8 @@ class UserCreationForm(forms.ModelForm):
return user
class UserChangeForm(forms.ModelForm):
- username = forms.RegexField(label=_("Username"), max_length=30, regex=r'^[\w.@+-]+$',
- help_text = _("Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only."),
+ username = forms.RegexField(label=_("Username"), max_length=64, regex=r'^[\w.@+-]+$',
+ help_text = _("Required. 64 characters or fewer. Letters, digits and @/./+/-/_ only."),
error_messages = {'invalid': _("This value may contain only letters, numbers and @/./+/-/_ characters.")})
class Meta:
@@ -63,7 +63,7 @@ class AuthenticationForm(forms.Form):
Base class for authenticating users. Extend this to get a form that accepts
username/password logins.
"""
- username = forms.CharField(label=_("Username"), max_length=30)
+ username = forms.CharField(label=_("Username"), max_length=64)
password = forms.CharField(label=_("Password"), widget=forms.PasswordInput)
def __init__(self, request=None, *args, **kwargs):
diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py
index ed5349453..e3e947700 100644
--- a/django/contrib/auth/models.py
+++ b/django/contrib/auth/models.py
@@ -189,7 +189,7 @@ class User(models.Model):
Username and password are required. Other fields are optional.
"""
- username = models.CharField(_('username'), max_length=64, unique=True, help_text=_("Required. 30 characters or fewer. Letters, numbers and @/./+/-/_ characters"))
+ username = models.CharField(_('username'), max_length=64, unique=True, help_text=_("Required. 64 characters or fewer. Letters, numbers and @/./+/-/_ characters"))
first_name = models.CharField(_('first name'), max_length=30, blank=True)
last_name = models.CharField(_('last name'), max_length=30, blank=True)
email = models.EmailField(_('e-mail address'), blank=True)
diff --git a/ietf/doc/admin.py b/ietf/doc/admin.py
index ddc721e11..88c341a0e 100644
--- a/ietf/doc/admin.py
+++ b/ietf/doc/admin.py
@@ -111,14 +111,15 @@ class DocAliasAdmin(admin.ModelAdmin):
list_display = [ 'name', 'document_link', ]
search_fields = [ 'name', 'document__name', ]
raw_id_fields = ['document']
- document_link = admin_link("document")
admin.site.register(DocAlias, DocAliasAdmin)
# events
class DocEventAdmin(admin.ModelAdmin):
- list_display = ["doc", "type", "by", "time"]
+ def rev(obj):
+ return obj.doc.rev
+ list_display = ["doc", "type", "rev", "by", "time"]
search_fields = ["doc__name", "by__name"]
raw_id_fields = ["doc", "by"]
diff --git a/ietf/doc/models.py b/ietf/doc/models.py
index 7693a4671..52afb5dba 100644
--- a/ietf/doc/models.py
+++ b/ietf/doc/models.py
@@ -7,6 +7,7 @@ from django.conf import settings
from ietf.group.models import *
from ietf.name.models import *
from ietf.person.models import Email, Person
+from ietf.utils.admin import admin_link
import datetime, os
@@ -266,6 +267,7 @@ class DocAlias(models.Model):
name = models.CharField(max_length=255, db_index=True)
def __unicode__(self):
return "%s-->%s" % (self.name, self.document.name)
+ document_link = admin_link("document")
class Meta:
verbose_name = "document alias"
verbose_name_plural = "document aliases"
diff --git a/ietf/idrfc/mails.py b/ietf/idrfc/mails.py
index 19592b138..4b7bcb78f 100644
--- a/ietf/idrfc/mails.py
+++ b/ietf/idrfc/mails.py
@@ -11,8 +11,6 @@ from django.core.urlresolvers import reverse as urlreverse
from ietf.utils.mail import send_mail, send_mail_text
from ietf.idtracker.models import *
from ietf.ipr.search import iprs_from_docs
-from ietf.ietfworkflows.streams import (get_stream_from_draft)
-from ietf.ietfworkflows.models import (Stream)
from ietf.doc.models import WriteupDocEvent, BallotPositionDocEvent, LastCallDocEvent, DocAlias
from ietf.person.models import Person
from ietf.group.models import Group
@@ -258,7 +256,8 @@ def generate_approval_mail_rfc_editor(request, doc):
status = full_status.replace("a ", "").replace("an ", "")
disapproved = doc.idinternal.cur_state_id in IDState.DO_NOT_PUBLISH_STATES
doc_type = "RFC" if type(doc) == Rfc else "Internet Draft"
-
+
+ from ietf.ietfworkflows.streams import get_stream_from_draft
stream = get_stream_from_draft(doc)
to = ", ".join([u"%s <%s>" % x.email() for x in stream.get_chairs_for_document(doc) ])
if stream.name == "IRTF":
diff --git a/ietf/idrfc/mirror_rfc_editor_queue.py b/ietf/idrfc/mirror_rfc_editor_queue.py
index af030f54d..a3912e58f 100644
--- a/ietf/idrfc/mirror_rfc_editor_queue.py
+++ b/ietf/idrfc/mirror_rfc_editor_queue.py
@@ -231,7 +231,7 @@ def insert_into_databaseREDESIGN(drafts, refs):
from ietf.name.models import DocTagName
tags = get_rfc_tag_mapping()
- states = get_rfc_state_mapping()
+ state_map = get_rfc_state_mapping()
rfc_editor_tags = tags.values()
@@ -242,20 +242,25 @@ def insert_into_databaseREDESIGN(drafts, refs):
log("inserting new data...")
- for name, date_received, state, stream_id in drafts:
+ for name, date_received, state_info, stream_id in drafts:
try:
d = Document.objects.get(name=name)
except Document.DoesNotExist:
log("unknown document %s" % name)
continue
- s = state.split(" ")
- if s:
+ state_list = state_info.split(" ")
+ if state_list:
+ state = state_list[0]
+ # For now, ignore the '*R...' that's appeared for some states.
+ # FIXME : see if we need to add some refinement for this.
+ if '*' in state:
+ state = state.split("*")[0]
# first is state
- d.set_state(states[s[0]])
+ d.set_state(state_map[state])
# remainding are tags
- for x in s[1:]:
+ for x in state_list[1:]:
d.tags.add(tags[x])
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
diff --git a/ietf/idrfc/mirror_rfc_index.py b/ietf/idrfc/mirror_rfc_index.py
index cca52f658..afb81cec0 100644
--- a/ietf/idrfc/mirror_rfc_index.py
+++ b/ietf/idrfc/mirror_rfc_index.py
@@ -53,6 +53,10 @@ def log(line):
else:
log_data += line + "\n"
+# python before 2.7 doesn't have the total_seconds method on datetime.timedelta.
+def total_seconds(td):
+ return (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6
+
def parse(response):
def getChildText(parentNode, tagName):
for node in parentNode.childNodes:
@@ -262,7 +266,7 @@ def insert_to_databaseREDESIGN(data):
if abs(pubdate - synthesized) > timedelta(days=60):
synthesized = pubdate
else:
- direction = -1 if (pubdate - synthesized).total_seconds() < 0 else +1
+ direction = -1 if total_seconds(pubdate - synthesized) < 0 else +1
while synthesized.month != pubdate.month or synthesized.year != pubdate.year:
synthesized += timedelta(days=direction)
e.time = synthesized
diff --git a/ietf/idrfc/views_doc.py b/ietf/idrfc/views_doc.py
index b6cf8df58..e6c4aab47 100644
--- a/ietf/idrfc/views_doc.py
+++ b/ietf/idrfc/views_doc.py
@@ -84,7 +84,7 @@ def include_text(request):
return include_text
def document_main_rfc(request, rfc_number, tab):
- rfci = get_object_or_404(RfcIndex, rfc_number=rfc_number)
+ rfci = get_object_or_404(RfcIndex, rfc_number=rfc_number, states__type="draft", states__slug="rfc")
rfci.viewing_as_rfc = True
doc = RfcWrapper(rfci)
diff --git a/ietf/name/utils.py b/ietf/name/utils.py
index 6480c8773..25b85ba4f 100644
--- a/ietf/name/utils.py
+++ b/ietf/name/utils.py
@@ -1,10 +1,11 @@
def name(name_class, slug, name, desc="", order=0, **kwargs):
# create if it doesn't exist, set name and desc
- obj, _ = name_class.objects.get_or_create(slug=slug)
- obj.name = name
- obj.desc = desc
- obj.order = order
- for k, v in kwargs.iteritems():
- setattr(obj, k, v)
- obj.save()
+ obj, created = name_class.objects.get_or_create(slug=slug)
+ if created:
+ obj.name = name
+ obj.desc = desc
+ obj.order = order
+ for k, v in kwargs.iteritems():
+ setattr(obj, k, v)
+ obj.save()
return obj
diff --git a/ietf/settings.py b/ietf/settings.py
index 94e82b569..2c69d5281 100644
--- a/ietf/settings.py
+++ b/ietf/settings.py
@@ -233,9 +233,9 @@ IDSUBMIT_ANNOUNCE_FROM_EMAIL = 'internet-drafts@ietf.org'
IDSUBMIT_ANNOUNCE_LIST_EMAIL = 'i-d-announce@ietf.org'
# Days from meeting to cut off dates on submit
-FIRST_CUTOFF_DAYS = 20
-SECOND_CUTOFF_DAYS = 13
-CUTOFF_HOUR = 24 # midnight UTC
+FIRST_CUTOFF_DAYS = 19
+SECOND_CUTOFF_DAYS = 12
+CUTOFF_HOUR = 00 # midnight UTC
SUBMISSION_START_DAYS = -90
SUBMISSION_CUTOFF_DAYS = 33
SUBMISSION_CORRECTION_DAYS = 52
diff --git a/ietf/submit/forms.py b/ietf/submit/forms.py
index 3f8efc91b..e2878f19b 100644
--- a/ietf/submit/forms.py
+++ b/ietf/submit/forms.py
@@ -66,7 +66,7 @@ class UploadForm(forms.Form):
self.cutoff_warning = 'The pre-meeting cutoff date for new documents (i.e., version -00 Internet-Drafts) was %s at %02sh UTC. You will not be able to submit a new document until %s, at %02sh UTC.
The I-D submission tool will be shut down at %02sh UTC today, and reopened at %02sh UTC on %s' % (first_cut_off, settings.CUTOFF_HOUR, ietf_monday, settings.CUTOFF_HOUR, settings.CUTOFF_HOUR, settings.CUTOFF_HOUR, ietf_monday)
self.in_first_cut_off = True
else: # Completely shut down of the tool
- self.cutoff_warning = 'The cut off time for the I-D submission was %02sh, %s.
The I-D submission tool will be reopened at %02sh, %s' % (settings.CUTOFF_HOUR, second_cut_off, settings.CUTOFF_HOUR, ietf_monday)
+ self.cutoff_warning = 'The cut off time for the I-D submission was %02dh UTC, %s.
The I-D submission tool will be reopened at %02dh UTC, %s.' % (settings.CUTOFF_HOUR, second_cut_off, settings.CUTOFF_HOUR, ietf_monday)
self.shutdown = True
def __unicode__(self):