Fix some import/proxy bugs that have turned up after a comparison test between non-proxied and proxied JSON generation, mostly relating to ballots registered by the Secretariat
- Legacy-Id: 2740
This commit is contained in:
parent
644c7fc496
commit
380c24d302
|
@ -406,7 +406,7 @@ class IetfProcessData:
|
|||
# don't call this unless has_[active_]iesg_ballot returns True
|
||||
def iesg_ballot_needed( self ):
|
||||
standardsTrack = 'Standard' in self.intended_maturity_level() or \
|
||||
self.intended_maturity_level() == "BCP"
|
||||
self.intended_maturity_level() in ("BCP", "Best Current Practice")
|
||||
return self.iesg_ballot().ballot.needed( standardsTrack )
|
||||
|
||||
def ad_name(self):
|
||||
|
@ -424,6 +424,17 @@ class IetfProcessData:
|
|||
|
||||
def state_date(self):
|
||||
try:
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
return self._idinternal.event_set.filter(
|
||||
Q(desc__istartswith="Draft Added by ")|
|
||||
Q(desc__istartswith="Draft Added in state ")|
|
||||
Q(desc__istartswith="Draft added in state ")|
|
||||
Q(desc__istartswith="State changed to ")|
|
||||
Q(desc__istartswith="State Changes to ")|
|
||||
Q(desc__istartswith="Sub state has been changed to ")|
|
||||
Q(desc__istartswith="State has been changed to ")|
|
||||
Q(desc__istartswith="IESG has approved and state has been changed to")).order_by('-time')[0].time.date()
|
||||
|
||||
return self._idinternal.comments().filter(
|
||||
Q(comment_text__istartswith="Draft Added by ")|
|
||||
Q(comment_text__istartswith="Draft Added in state ")|
|
||||
|
@ -625,8 +636,8 @@ class BallotWrapper:
|
|||
positions = []
|
||||
seen = {}
|
||||
|
||||
for pos in self.ballot.event_set.filter(type="changed_ballot_position").select_related('pos', 'ad').order_by("-time", '-id'):
|
||||
pos = pos.ballotposition
|
||||
from doc.models import BallotPosition
|
||||
for pos in BallotPosition.objects.filter(doc=self.ballot, type="changed_ballot_position").select_related('ad').order_by("-time", '-id'):
|
||||
if pos.ad not in seen:
|
||||
p = dict(ad_name=pos.ad.get_name(),
|
||||
ad_username="", # FIXME: don't seem to have username at the moment
|
||||
|
|
|
@ -100,4 +100,5 @@ class DraftVersions(models.Model):
|
|||
|
||||
from django.conf import settings
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
RfcIndexOld = RfcIndex
|
||||
from redesign.doc.proxy import RfcIndex
|
||||
|
|
|
@ -150,7 +150,7 @@ def _get_history(doc, versions):
|
|||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
versions = [] # clear versions
|
||||
event_holder = doc._draft if hasattr(doc, "_draft") else doc._rfcindex
|
||||
for e in event_holder.event_set.all().select_related('by').order_by('-time'):
|
||||
for e in event_holder.event_set.all().select_related('by').order_by('-time', '-id'):
|
||||
info = {}
|
||||
if e.type == "new_revision":
|
||||
filename = u"%s-%s" % (e.doc.name, e.newrevision.rev)
|
||||
|
@ -166,6 +166,9 @@ def _get_history(doc, versions):
|
|||
results.append({'comment':e, 'info':info, 'date':e.time, 'is_com':True})
|
||||
|
||||
prev_rev = "00"
|
||||
# actually, we're already sorted and this ruins the sort from
|
||||
# the ids which is sometimes needed, so the function should be
|
||||
# rewritten to not rely on a resort
|
||||
results.sort(key=lambda x: x['date'])
|
||||
for o in results:
|
||||
e = o["comment"]
|
||||
|
@ -236,6 +239,19 @@ def _get_versions(draft, include_replaced=True):
|
|||
def get_ballot(name):
|
||||
r = re.compile("^rfc([1-9][0-9]*)$")
|
||||
m = r.match(name)
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
from doc.models import DocAlias
|
||||
alias = get_object_or_404(DocAlias, name=name)
|
||||
d = get_object_or_404(InternetDraft, name=alias.document.name)
|
||||
try:
|
||||
if not d.ballot.ballot_issued:
|
||||
raise Http404
|
||||
except BallotInfo.DoesNotExist:
|
||||
raise Http404
|
||||
|
||||
return (BallotWrapper(d), RfcWrapper(d) if m else IdWrapper(d))
|
||||
|
||||
if m:
|
||||
rfc_number = int(m.group(1))
|
||||
rfci = get_object_or_404(RfcIndex, rfc_number=rfc_number)
|
||||
|
|
|
@ -46,7 +46,7 @@ class DocumentInfo(models.Model):
|
|||
while d.latest_event(Status, type="xyz") returns a Status
|
||||
event."""
|
||||
model = args[0] if args else Event
|
||||
e = model.objects.filter(doc=self).filter(**filter_args).order_by('-time')[:1]
|
||||
e = model.objects.filter(doc=self).filter(**filter_args).order_by('-time', '-id')[:1]
|
||||
return e[0] if e else None
|
||||
|
||||
class RelatedDocument(models.Model):
|
||||
|
|
|
@ -10,8 +10,10 @@ import glob, os
|
|||
class InternetDraft(Document):
|
||||
objects = TranslatingManager(dict(filename="name",
|
||||
id_document_tag="id",
|
||||
status="state",
|
||||
rfc_number=lambda v: ("docalias__name", "rfc%s" % v)))
|
||||
status=lambda v: ("state", { 1: 'active', 2: 'expired', 3: 'rfc', 4: 'auth-rm', 5: 'repl', 6: 'ietf-rm'}),
|
||||
job_owner="ad",
|
||||
rfc_number=lambda v: ("docalias__name", "rfc%s" % v),
|
||||
))
|
||||
|
||||
DAYS_TO_EXPIRE=185
|
||||
|
||||
|
@ -94,7 +96,7 @@ class InternetDraft(Document):
|
|||
@property
|
||||
def lc_sent_date(self):
|
||||
e = self.latest_event(type="sent_last_call")
|
||||
return e.time if e else None
|
||||
return e.time.date() if e else None
|
||||
|
||||
#lc_changes = models.CharField(max_length=3) # used in DB, unused in Django code?
|
||||
|
||||
|
@ -108,7 +110,7 @@ class InternetDraft(Document):
|
|||
@property
|
||||
def b_sent_date(self):
|
||||
e = self.latest_event(type="sent_ballot_announcement")
|
||||
return e.time if e else None
|
||||
return e.time.date() if e else None
|
||||
|
||||
#b_discussion_date = models.DateField(null=True, blank=True) # unused
|
||||
|
||||
|
@ -142,7 +144,7 @@ class InternetDraft(Document):
|
|||
#replaces = FKAsOneToOne('replaces', reverse=True)
|
||||
@property
|
||||
def replaces(self):
|
||||
r = self.replaces_set()
|
||||
r = self.replaces_set
|
||||
return r[0] if r else None
|
||||
|
||||
@property
|
||||
|
@ -242,7 +244,12 @@ class InternetDraft(Document):
|
|||
#ballot = models.ForeignKey(BallotInfo, related_name='drafts', db_column="ballot_id")
|
||||
@property
|
||||
def ballot(self):
|
||||
return self # FIXME: raise BallotInfo.DoesNotExist?
|
||||
if not self.idinternal:
|
||||
raise BallotInfo.DoesNotExist()
|
||||
return self
|
||||
@property
|
||||
def ballot_id(self):
|
||||
return self.ballot.name
|
||||
|
||||
#primary_flag = models.IntegerField(blank=True, null=True)
|
||||
@property
|
||||
|
@ -402,7 +409,7 @@ class InternetDraft(Document):
|
|||
return self
|
||||
|
||||
def comments(self):
|
||||
return self.event_set.all().order_by('-time')
|
||||
return DocumentComment.objects.filter(doc=self).order_by('-time')
|
||||
|
||||
def ballot_set(self):
|
||||
return [self]
|
||||
|
@ -579,22 +586,22 @@ class InternetDraft(Document):
|
|||
#updates = models.CharField(max_length=200,blank=True,null=True)
|
||||
@property
|
||||
def updates(self):
|
||||
return ",".join(sorted("RFC%s" % d.rfc_number for d in InternetDraft.objects.filter(docalias__relateddocument__document=self, docalias__relateddocument__relationship="updates")))
|
||||
return ",".join("RFC%s" % n for n in sorted(d.rfc_number for d in InternetDraft.objects.filter(docalias__relateddocument__document=self, docalias__relateddocument__relationship="updates")))
|
||||
|
||||
#updated_by = models.CharField(max_length=200,blank=True,null=True)
|
||||
@property
|
||||
def updated_by(self):
|
||||
return ",".join(sorted("RFC%s" % d.rfc_number for d in InternetDraft.objects.filter(relateddocument__doc_alias__document=self, relateddocument__relationship="updates")))
|
||||
return ",".join("RFC%s" % n for n in sorted(d.rfc_number for d in InternetDraft.objects.filter(relateddocument__doc_alias__document=self, relateddocument__relationship="updates")))
|
||||
|
||||
#obsoletes = models.CharField(max_length=200,blank=True,null=True)
|
||||
@property
|
||||
def obsoletes(self):
|
||||
return ",".join(sorted("RFC%s" % d.rfc_number for d in InternetDraft.objects.filter(docalias__relateddocument__document=self, docalias__relateddocument__relationship="obs")))
|
||||
return ",".join("RFC%s" % n for n in sorted(d.rfc_number for d in InternetDraft.objects.filter(docalias__relateddocument__document=self, docalias__relateddocument__relationship="obs")))
|
||||
|
||||
#obsoleted_by = models.CharField(max_length=200,blank=True,null=True)
|
||||
@property
|
||||
def obsoleted_by(self):
|
||||
return ",".join(sorted("RFC%s" % d.rfc_number for d in InternetDraft.objects.filter(relateddocument__doc_alias__document=self, relateddocument__relationship="obs")))
|
||||
return ",".join("RFC%s" % n for n in sorted(d.rfc_number for d in InternetDraft.objects.filter(relateddocument__doc_alias__document=self, relateddocument__relationship="obs")))
|
||||
|
||||
#also = models.CharField(max_length=50,blank=True,null=True)
|
||||
@property
|
||||
|
@ -655,3 +662,44 @@ class IDAuthor(DocumentAuthor):
|
|||
class Meta:
|
||||
proxy = True
|
||||
|
||||
class DocumentComment(Event):
|
||||
objects = TranslatingManager(dict(comment_text="desc",
|
||||
))
|
||||
|
||||
BALLOT_DISCUSS = 1
|
||||
BALLOT_COMMENT = 2
|
||||
BALLOT_CHOICES = (
|
||||
(BALLOT_DISCUSS, 'discuss'),
|
||||
(BALLOT_COMMENT, 'comment'),
|
||||
)
|
||||
#document = models.ForeignKey(IDInternal)
|
||||
@property
|
||||
def document(self):
|
||||
return self.doc
|
||||
#rfc_flag = models.IntegerField(null=True, blank=True)
|
||||
#public_flag = models.BooleanField() #unused
|
||||
#date = models.DateField(db_column='comment_date', default=datetime.date.today)
|
||||
@property
|
||||
def date(self):
|
||||
return self.time.date()
|
||||
#time = models.CharField(db_column='comment_time', max_length=20, default=lambda: datetime.datetime.now().strftime("%H:%M:%S"))
|
||||
#version = models.CharField(blank=True, max_length=3)
|
||||
#comment_text = models.TextField(blank=True)
|
||||
#created_by = BrokenForeignKey(IESGLogin, db_column='created_by', null=True, null_values=(0, 999))
|
||||
#result_state = BrokenForeignKey(IDState, db_column='result_state', null=True, related_name="comments_leading_to_state", null_values=(0, 99))
|
||||
#origin_state = models.ForeignKey(IDState, db_column='origin_state', null=True, related_name="comments_coming_from_state")
|
||||
#ballot = models.IntegerField(null=True, choices=BALLOT_CHOICES)
|
||||
def get_absolute_url(self):
|
||||
return "/idtracker/%d/comment/%d/" % (self.doc.name, self.id)
|
||||
def get_author(self):
|
||||
return unicode(self.by)
|
||||
def get_username(self):
|
||||
return unicode(self.by)
|
||||
def get_fullname(self):
|
||||
return unicode(self.by)
|
||||
def datetime(self):
|
||||
return self.time
|
||||
|
||||
class Meta:
|
||||
proxy = True
|
||||
|
||||
|
|
|
@ -23,6 +23,14 @@ document_name_to_import = None
|
|||
if len(sys.argv) > 1:
|
||||
document_name_to_import = sys.argv[1]
|
||||
|
||||
# prevent memory from leaking when settings.DEBUG=True
|
||||
from django.db import connection
|
||||
class DummyQueries(object):
|
||||
def append(self, x):
|
||||
pass
|
||||
connection.queries = DummyQueries()
|
||||
|
||||
|
||||
# assumptions:
|
||||
# - groups have been imported
|
||||
# - IESG login emails/roles have been imported
|
||||
|
@ -207,6 +215,10 @@ def iesg_login_to_email(l):
|
|||
print "MISSING IESG LOGIN", l.person.email()
|
||||
return None
|
||||
|
||||
def iesg_login_is_secretary(l):
|
||||
# Amy has two users, for some reason
|
||||
return l.user_level == IESGLogin.SECRETARIAT_LEVEL or l.first_name == "Amy" and l.last_name == "Vezza"
|
||||
|
||||
# regexps for parsing document comments
|
||||
|
||||
date_re_str = "(?P<year>[0-9][0-9][0-9][0-9])-(?P<month>[0-9][0-9]?)-(?P<day>[0-9][0-9]?)"
|
||||
|
@ -237,6 +249,7 @@ re_intended_status_changed = re.compile(r"Intended [sS]tatus has been changed to
|
|||
re_state_change_notice = re.compile(r"State Change Notice email list (have been change|has been changed) (<b>)?")
|
||||
re_area_acronym_changed = re.compile(r"Area acronymn? has been changed to \w+ from \w+(<b>)?")
|
||||
|
||||
re_comment_discuss_by_tag = re.compile(r" by [\w-]+ [\w-]+$")
|
||||
|
||||
def import_from_idinternal(d, idinternal):
|
||||
d.time = idinternal.event_date
|
||||
|
@ -244,12 +257,14 @@ def import_from_idinternal(d, idinternal):
|
|||
d.ad = iesg_login_to_email(idinternal.job_owner)
|
||||
d.notify = idinternal.state_change_notice_to or ""
|
||||
d.note = idinternal.note or ""
|
||||
d.note = d.note.replace('<br>', '\n').strip().replace('\n', '<br>')
|
||||
d.save()
|
||||
|
||||
# extract events
|
||||
last_note_change_text = ""
|
||||
|
||||
for c in DocumentComment.objects.filter(document=idinternal.draft_id).order_by('date', 'time', 'id'):
|
||||
|
||||
document_comments = DocumentComment.objects.filter(document=idinternal.draft_id).order_by('date', 'time', 'id')
|
||||
for c in document_comments:
|
||||
handled = False
|
||||
|
||||
# telechat agenda schedulings
|
||||
|
@ -269,21 +284,24 @@ def import_from_idinternal(d, idinternal):
|
|||
e = Event()
|
||||
e.type = "sent_ballot_announcement"
|
||||
save_event(d, e, c)
|
||||
|
||||
# when you issue a ballot, you also vote yes; add that vote
|
||||
e = BallotPosition()
|
||||
e.type = "changed_ballot_position"
|
||||
e.ad = iesg_login_to_email(c.created_by)
|
||||
e.desc = "[Ballot Position Update] New position, Yes, has been recorded by %s" % e.ad.get_name()
|
||||
last_pos = d.latest_event(type="changed_ballot_position", ballotposition__ad=e.ad)
|
||||
e.pos = ballot_position_mapping["Yes"]
|
||||
e.discuss = last_pos.ballotposition.discuss if last_pos else ""
|
||||
e.discuss_time = last_pos.ballotposition.discuss_time if last_pos else None
|
||||
e.comment = last_pos.ballotposition.comment if last_pos else ""
|
||||
e.comment_time = last_pos.ballotposition.comment_time if last_pos else None
|
||||
save_event(d, e, c)
|
||||
handled = True
|
||||
|
||||
ad = iesg_login_to_email(c.created_by)
|
||||
last_pos = d.latest_event(BallotPosition, type="changed_ballot_position", ad=ad)
|
||||
if not last_pos and not iesg_login_is_secretary(c.created_by):
|
||||
# when you issue a ballot, you also vote yes; add that vote
|
||||
e = BallotPosition()
|
||||
e.type = "changed_ballot_position"
|
||||
e.ad = ad
|
||||
e.desc = "[Ballot Position Update] New position, Yes, has been recorded by %s" % e.ad.get_name()
|
||||
|
||||
e.pos = ballot_position_mapping["Yes"]
|
||||
e.discuss = last_pos.discuss if last_pos else ""
|
||||
e.discuss_time = last_pos.discuss_time if last_pos else None
|
||||
e.comment = last_pos.comment if last_pos else ""
|
||||
e.comment_time = last_pos.comment_time if last_pos else None
|
||||
save_event(d, e, c)
|
||||
|
||||
# ballot positions
|
||||
match = re_ballot_position.search(c.comment_text)
|
||||
if match:
|
||||
|
@ -291,7 +309,7 @@ def import_from_idinternal(d, idinternal):
|
|||
ad_name = match.group('for') or match.group('for2') or match.group('by') # some of the old positions don't specify who it's for, in that case assume it's "by", the person who entered the position
|
||||
ad_first, ad_last = ad_name.split(' ')
|
||||
login = IESGLogin.objects.filter(first_name=ad_first, last_name=ad_last).order_by('user_level')[0]
|
||||
if login.user_level == IESGLogin.SECRETARIAT_LEVEL:
|
||||
if iesg_login_is_secretary(login):
|
||||
# now we're in trouble, a secretariat person isn't an
|
||||
# AD, instead try to find a position object that
|
||||
# matches and that we haven't taken yet
|
||||
|
@ -307,12 +325,33 @@ def import_from_idinternal(d, idinternal):
|
|||
elif position.slug == "discuss":
|
||||
positions = positions.filter(models.Q(discuss=1)|models.Q(discuss=2))
|
||||
assert position.slug != "norecord"
|
||||
|
||||
|
||||
found = False
|
||||
for p in positions:
|
||||
if not d.event_set.filter(type="changed_ballot_position", ballotposition__pos=position, ballotposition__ad=iesg_login_to_email(p.ad)):
|
||||
login = p.ad
|
||||
found = True
|
||||
break
|
||||
|
||||
if not found:
|
||||
# in even more trouble, we can try and see if it
|
||||
# belongs to a nearby discuss
|
||||
if position.slug == "discuss":
|
||||
index_c = list(document_comments).index(c)
|
||||
start = c.datetime()
|
||||
end = c.datetime() + datetime.timedelta(seconds=30 * 60)
|
||||
for i, x in enumerate(document_comments):
|
||||
if (x.ballot == DocumentComment.BALLOT_DISCUSS
|
||||
and (c.datetime() <= x.datetime() <= end
|
||||
or abs(index_c - i) <= 2)
|
||||
and not iesg_login_is_secretary(x.created_by)):
|
||||
login = x.created_by
|
||||
found = True
|
||||
|
||||
if not found:
|
||||
print "BALLOT BY SECRETARIAT", login
|
||||
|
||||
|
||||
e = BallotPosition()
|
||||
e.type = "changed_ballot_position"
|
||||
e.ad = iesg_login_to_email(login)
|
||||
|
@ -320,6 +359,10 @@ def import_from_idinternal(d, idinternal):
|
|||
e.pos = position
|
||||
e.discuss = last_pos.discuss if last_pos else ""
|
||||
e.discuss_time = last_pos.discuss_time if last_pos else None
|
||||
if e.pos_id == "discuss" and not e.discuss_time:
|
||||
# in a few cases, we don't have the discuss
|
||||
# text/time, fudge the time so it's not null
|
||||
e.discuss_time = c.datetime()
|
||||
e.comment = last_pos.comment if last_pos else ""
|
||||
e.comment_time = last_pos.comment_time if last_pos else None
|
||||
save_event(d, e, c)
|
||||
|
@ -330,23 +373,35 @@ def import_from_idinternal(d, idinternal):
|
|||
e = BallotPosition()
|
||||
e.type = "changed_ballot_position"
|
||||
e.ad = iesg_login_to_email(c.created_by)
|
||||
last_pos = d.latest_event(type="changed_ballot_position", ballotposition__ad=e.ad)
|
||||
e.pos = last_pos.ballotposition.pos if last_pos else ballot_position_mapping[None]
|
||||
last_pos = d.latest_event(BallotPosition, type="changed_ballot_position", ad=e.ad)
|
||||
e.pos = last_pos.pos if last_pos else ballot_position_mapping[None]
|
||||
c.comment_text = re_comment_discuss_by_tag.sub("", c.comment_text)
|
||||
if c.ballot == DocumentComment.BALLOT_DISCUSS:
|
||||
e.discuss = c.comment_text
|
||||
e.discuss_time = c.datetime()
|
||||
e.comment = last_pos.ballotposition.comment if last_pos else ""
|
||||
e.comment_time = last_pos.ballotposition.comment_time if last_pos else None
|
||||
e.comment = last_pos.comment if last_pos else ""
|
||||
e.comment_time = last_pos.comment_time if last_pos else None
|
||||
# put header into description
|
||||
c.comment_text = "[Ballot discuss]\n" + c.comment_text
|
||||
else:
|
||||
e.discuss = last_pos.ballotposition.discuss if last_pos else ""
|
||||
e.discuss_time = last_pos.ballotposition.discuss_time if last_pos else None
|
||||
e.discuss = last_pos.discuss if last_pos else ""
|
||||
e.discuss_time = last_pos.discuss_time if last_pos else None
|
||||
if e.pos_id == "discuss" and not e.discuss_time:
|
||||
# in a few cases, we don't have the discuss
|
||||
# text/time, fudge the time so it's not null
|
||||
e.discuss_time = c.datetime()
|
||||
e.comment = c.comment_text
|
||||
e.comment_time = c.datetime()
|
||||
# put header into description
|
||||
c.comment_text = "[Ballot comment]\n" + c.comment_text
|
||||
save_event(d, e, c)
|
||||
|
||||
# there are some bogus copies where a secretary has the
|
||||
# same discuss comment as an AD, skip saving if this is
|
||||
# one of those
|
||||
if not (iesg_login_is_secretary(c.created_by)
|
||||
and DocumentComment.objects.filter(ballot=c.ballot, document=c.document).exclude(created_by=c.created_by)):
|
||||
save_event(d, e, c)
|
||||
|
||||
handled = True
|
||||
|
||||
# last call requested
|
||||
|
@ -564,10 +619,13 @@ def import_from_idinternal(d, idinternal):
|
|||
position_date = made_up_date
|
||||
|
||||
# make sure we got all the positions
|
||||
existing = BallotPosition.objects.filter(doc=d, type="changed_ballot_position").order_by("-time")
|
||||
existing = BallotPosition.objects.filter(doc=d, type="changed_ballot_position").order_by("-time", '-id')
|
||||
|
||||
for p in Position.objects.filter(ballot=ballot):
|
||||
found = False
|
||||
# there are some bogus ones
|
||||
if iesg_login_is_secretary(p.ad):
|
||||
continue
|
||||
|
||||
ad = iesg_login_to_email(p.ad)
|
||||
if p.noobj > 0:
|
||||
pos = ballot_position_mapping["No Objection"]
|
||||
|
@ -581,6 +639,8 @@ def import_from_idinternal(d, idinternal):
|
|||
pos = ballot_position_mapping["Discuss"]
|
||||
else:
|
||||
pos = ballot_position_mapping[None]
|
||||
|
||||
found = False
|
||||
for x in existing:
|
||||
if x.ad == ad and x.pos == pos:
|
||||
found = True
|
||||
|
@ -597,6 +657,10 @@ def import_from_idinternal(d, idinternal):
|
|||
e.pos = pos
|
||||
e.discuss = last_pos.discuss if last_pos else ""
|
||||
e.discuss_time = last_pos.discuss_time if last_pos else None
|
||||
if e.pos_id == "discuss" and not e.discuss_time:
|
||||
# in a few cases, we don't have the discuss
|
||||
# text/time, fudge the time so it's not null
|
||||
e.discuss_time = e.time
|
||||
e.comment = last_pos.comment if last_pos else ""
|
||||
e.comment_time = last_pos.comment_time if last_pos else None
|
||||
if last_pos:
|
||||
|
@ -607,7 +671,7 @@ def import_from_idinternal(d, idinternal):
|
|||
|
||||
# make sure we got the ballot issued event
|
||||
if ballot.ballot_issued and not d.event_set.filter(type="sent_ballot_announcement"):
|
||||
position = d.event_set.filter(type=("changed_ballot_position")).order_by('time')[:1]
|
||||
position = d.event_set.filter(type=("changed_ballot_position")).order_by('time', 'id')[:1]
|
||||
if position:
|
||||
sent_date = position[0].time
|
||||
else:
|
||||
|
@ -622,8 +686,8 @@ def import_from_idinternal(d, idinternal):
|
|||
e.save()
|
||||
|
||||
# make sure the comments and discusses are updated
|
||||
positions = list(BallotPosition.objects.filter(doc=d).order_by("-time"))
|
||||
for c in IESGComment.objects.filter(ballot=idinternal.ballot):
|
||||
positions = list(BallotPosition.objects.filter(doc=d).order_by("-time", '-id'))
|
||||
for c in IESGComment.objects.filter(ballot=ballot):
|
||||
ad = iesg_login_to_email(c.ad)
|
||||
for p in positions:
|
||||
if p.ad == ad:
|
||||
|
@ -633,7 +697,7 @@ def import_from_idinternal(d, idinternal):
|
|||
p.save()
|
||||
break
|
||||
|
||||
for c in IESGDiscuss.objects.filter(ballot=idinternal.ballot):
|
||||
for c in IESGDiscuss.objects.filter(ballot=ballot):
|
||||
ad = iesg_login_to_email(c.ad)
|
||||
for p in positions:
|
||||
if p.ad == ad:
|
||||
|
@ -689,16 +753,13 @@ def import_from_idinternal(d, idinternal):
|
|||
|
||||
all_drafts = InternetDraft.objects.all().select_related()
|
||||
if document_name_to_import:
|
||||
all_drafts = all_drafts.filter(filename=document_name_to_import)
|
||||
if document_name_to_import.startswith("rfc"):
|
||||
all_drafts = all_drafts.filter(rfc_number=document_name_to_import[3:])
|
||||
else:
|
||||
all_drafts = all_drafts.filter(filename=document_name_to_import)
|
||||
#all_drafts = all_drafts[all_drafts.count() - 1000:]
|
||||
#all_drafts = all_drafts.none()
|
||||
|
||||
# prevent memory from leaking from debug setting
|
||||
from django.db import connection
|
||||
class DummyQueries(object):
|
||||
def append(self, x):
|
||||
pass
|
||||
connection.queries = DummyQueries()
|
||||
|
||||
for index, o in enumerate(all_drafts.iterator()):
|
||||
print "importing", o.filename, index
|
||||
|
||||
|
@ -717,9 +778,9 @@ for index, o in enumerate(all_drafts.iterator()):
|
|||
elif o.filename.startswith("draft-irtf-"):
|
||||
d.stream = stream_mapping["IRTF"]
|
||||
elif o.idinternal and o.idinternal.via_rfc_editor:
|
||||
d.stream = stream_mapping["INDEPENDENT"] # FIXME: correct?
|
||||
d.stream = stream_mapping["INDEPENDENT"]
|
||||
else:
|
||||
d.stream = stream_mapping["IETF"] # FIXME: correct?
|
||||
d.stream = stream_mapping["IETF"]
|
||||
d.wg_state = None
|
||||
d.iesg_state = iesg_state_mapping[None]
|
||||
d.iana_state = None
|
||||
|
@ -739,6 +800,10 @@ for index, o in enumerate(all_drafts.iterator()):
|
|||
# make sure our alias is updated
|
||||
d_alias = alias_doc(d.name, d)
|
||||
|
||||
# RFC alias
|
||||
if o.rfc_number:
|
||||
alias_doc("rfc%s" % o.rfc_number, d)
|
||||
|
||||
d.authors.clear()
|
||||
for i, a in enumerate(o.authors.all().select_related("person").order_by('author_order', 'person')):
|
||||
try:
|
||||
|
@ -807,13 +872,10 @@ for index, o in enumerate(all_drafts.iterator()):
|
|||
# tags
|
||||
sync_tag(d, o.review_by_rfc_editor, tag_review_by_rfc_editor)
|
||||
sync_tag(d, o.expired_tombstone, tag_expired_tombstone)
|
||||
|
||||
# RFC alias
|
||||
if o.rfc_number:
|
||||
alias_doc("rfc%s" % o.rfc_number, d)
|
||||
|
||||
|
||||
# replacements
|
||||
if o.replaced_by:
|
||||
replacement, _ = Document.objects.get_or_create(name=o.replaced_by.filename)
|
||||
replacement, _ = Document.objects.get_or_create(name=o.replaced_by.filename, defaults=dict(time=datetime.datetime(1970, 1, 1, 0, 0, 0)))
|
||||
RelatedDocument.objects.get_or_create(document=replacement, doc_alias=d_alias, relationship=relationship_replaces)
|
||||
|
||||
# the RFC-related attributes are imported when we handle the RFCs below
|
||||
|
@ -878,7 +940,7 @@ for index, o in enumerate(all_rfcs.iterator()):
|
|||
if rfcs:
|
||||
r = rfcs[0]
|
||||
l = intended_std_level_mapping[r.intended_status.status]
|
||||
if l:
|
||||
if l: # skip some bogus None values
|
||||
d.intended_std_level = l
|
||||
d.save()
|
||||
|
||||
|
@ -901,9 +963,6 @@ for index, o in enumerate(all_rfcs.iterator()):
|
|||
|
||||
# import obsoletes/updates
|
||||
def make_relation(other_rfc, rel_type, reverse):
|
||||
if other_rfc.startswith("NIC") or other_rfc.startswith("IEN") or other_rfc.startswith("STD") or other_rfc.startswith("RTR"):
|
||||
return # we currently have no good way of importing these
|
||||
|
||||
other_number = int(other_rfc.replace("RFC", ""))
|
||||
other, other_alias = get_or_create_rfc_document(other_number)
|
||||
if reverse:
|
||||
|
@ -911,18 +970,35 @@ for index, o in enumerate(all_rfcs.iterator()):
|
|||
else:
|
||||
RelatedDocument.objects.get_or_create(document=d, doc_alias=other_alias, relationship=rel_type)
|
||||
|
||||
if o.obsoletes:
|
||||
for x in o.obsoletes.split(','):
|
||||
make_relation(x, relationship_obsoletes, False)
|
||||
if o.obsoleted_by:
|
||||
for x in o.obsoleted_by.split(','):
|
||||
make_relation(x, relationship_obsoletes, True)
|
||||
if o.updates:
|
||||
for x in o.updates.split(','):
|
||||
make_relation(x, relationship_updates, False)
|
||||
if o.updated_by:
|
||||
for x in o.updated_by.split(','):
|
||||
make_relation(x, relationship_updates, True)
|
||||
def parse_relation_list(s):
|
||||
if not s:
|
||||
return []
|
||||
res = []
|
||||
for x in s.split(","):
|
||||
if x[:3] in ("NIC", "IEN", "STD", "RTR"):
|
||||
# try translating this to RFC numbers that we can
|
||||
# handle sensibly; otherwise we'll have to ignore them
|
||||
l = ["RFC%s" % y.rfc_number for y in RfcIndex.objects.filter(also=x).order_by('rfc_number')]
|
||||
if l:
|
||||
print "translated", x, "to", ", ".join(l)
|
||||
for y in l:
|
||||
if y not in res:
|
||||
res.append(y)
|
||||
else:
|
||||
print "SKIPPED relation to", x
|
||||
else:
|
||||
res.append(x)
|
||||
return res
|
||||
|
||||
RelatedDocument.objects.filter(document=d).delete()
|
||||
for x in parse_relation_list(o.obsoletes):
|
||||
make_relation(x, relationship_obsoletes, False)
|
||||
for x in parse_relation_list(o.obsoleted_by):
|
||||
make_relation(x, relationship_obsoletes, True)
|
||||
for x in parse_relation_list(o.updates):
|
||||
make_relation(x, relationship_updates, False)
|
||||
for x in parse_relation_list(o.updated_by):
|
||||
make_relation(x, relationship_updates, True)
|
||||
|
||||
if o.also:
|
||||
alias_doc(o.also.lower(), d)
|
||||
|
|
|
@ -2,6 +2,27 @@ from django.db.models.manager import Manager
|
|||
from django.db.models.query import QuerySet
|
||||
|
||||
class TranslatingQuerySet(QuerySet):
|
||||
def translated_args(self, args):
|
||||
trans = self.translated_attrs
|
||||
res = []
|
||||
for a in args:
|
||||
if a.startswith("-"):
|
||||
prefix = "-"
|
||||
a = a[1:]
|
||||
else:
|
||||
prefix = ""
|
||||
|
||||
if a in trans:
|
||||
t = trans[a]
|
||||
if callable(t):
|
||||
t, _ = t(None)
|
||||
|
||||
if t:
|
||||
res.append(prefix + t)
|
||||
else:
|
||||
res.append(prefix + a)
|
||||
return res
|
||||
|
||||
def translated_kwargs(self, kwargs):
|
||||
trans = self.translated_attrs
|
||||
res = dict()
|
||||
|
@ -80,6 +101,7 @@ class TranslatingQuerySet(QuerySet):
|
|||
return super(self.__class__, self).latest(*args, **kwargs)
|
||||
|
||||
def order_by(self, *args, **kwargs):
|
||||
args = self.translated_args(args)
|
||||
kwargs = self.translated_kwargs(kwargs)
|
||||
return super(self.__class__, self).order_by(*args, **kwargs)
|
||||
|
||||
|
@ -88,10 +110,12 @@ class TranslatingQuerySet(QuerySet):
|
|||
return super(self.__class__, self).select_related(*args, **kwargs)
|
||||
|
||||
def values(self, *args, **kwargs):
|
||||
args = self.translated_args(args)
|
||||
kwargs = self.translated_kwargs(kwargs)
|
||||
return super(self.__class__, self).values(*args, **kwargs)
|
||||
|
||||
def values_list(self, *args, **kwargs):
|
||||
args = self.translated_args(args)
|
||||
kwargs = self.translated_kwargs(kwargs)
|
||||
return super(self.__class__, self).values_list(*args, **kwargs)
|
||||
|
||||
|
|
Loading…
Reference in a new issue