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:
Ole Laursen 2011-01-10 12:01:05 +00:00
parent 644c7fc496
commit 380c24d302
7 changed files with 254 additions and 78 deletions

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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):

View file

@ -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

View file

@ -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)

View file

@ -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)