diff --git a/ietf/doc/proxy.py b/ietf/doc/proxy.py deleted file mode 100644 index 889307495..000000000 --- a/ietf/doc/proxy.py +++ /dev/null @@ -1,1038 +0,0 @@ -import glob -import os -import math - -from ietf.doc.models import * -from ietf.person.models import Email -from ietf.utils.proxy import TranslatingManager -from ietf.name.proxy import * - -from django.conf import settings - -class InternetDraft(Document): - objects = TranslatingManager(dict(filename="name", - filename__contains="name__contains", - id_document_tag="pk", - status=lambda v: ("states__slug", { 1: 'active', 2: 'expired', 3: 'rfc', 4: 'auth-rm', 5: 'repl', 6: 'ietf-rm'}[v], "states__type", "draft"), - job_owner="ad", - rfc_number=lambda v: ("docalias__name", "rfc%s" % v), - cur_state=lambda v: ("states__order", v, 'states__type', 'draft-iesg'), - idinternal__primary_flag=None, - idinternal__cur_state__state=lambda v: ("states__name", v, 'states__type', 'draft-iesg'), - ), always_filter=dict(type="draft")) - - DAYS_TO_EXPIRE=185 - - # things from InternetDraft - - #id_document_tag = models.AutoField(primary_key=True) - @property - def id_document_tag(self): - return self.name # Will only work for some use cases - #title = models.CharField(max_length=255, db_column='id_document_name') # same name - #id_document_key = models.CharField(max_length=255, editable=False) - @property - def id_document_key(self): - return self.title.upper() - #group = models.ForeignKey(Acronym, db_column='group_acronym_id') - @property - def group(self): - from ietf.group.proxy import Acronym as AcronymProxy - g = super(InternetDraft, self).group - return AcronymProxy().from_object(g) if g else None - #filename = models.CharField(max_length=255, unique=True) - @property - def filename(self): - return self.name - #revision = models.CharField(max_length=2) - @property - def revision(self): - return self.rev - #revision_date = models.DateField() - @property - def revision_date(self): - if hasattr(self, "new_revision"): - e = self.new_revision - else: - e = self.latest_event(type="new_revision") - return e.time.date() if e else None - # helper function - def get_file_type_matches_from(self, base_path): - possible_types = [".txt", ".pdf", ".xml", ".ps"] - res = [] - for m in glob.glob(base_path + '.*'): - for t in possible_types: - if base_path + t == m: - res.append(t) - return ",".join(res) - #file_type = models.CharField(max_length=20) - @property - def file_type(self): - return self.get_file_type_matches_from(os.path.join(settings.INTERNET_DRAFT_PATH, self.name + "-" + self.rev)) or ".txt" - #txt_page_count = models.IntegerField() - @property - def txt_page_count(self): - return self.pages - #local_path = models.CharField(max_length=255, blank=True) # unused - #start_date = models.DateField() - @property - def start_date(self): - e = NewRevisionDocEvent.objects.filter(doc=self).order_by("time")[:1] - return e[0].time.date() if e else None - #expiration_date = models.DateField() - @property - def expiration_date(self): - e = self.latest_event(type__in=('expired_document', 'new_revision', "completed_resurrect")) - return e.time.date() if e and e.type == "expired_document" else None - #abstract = models.TextField() # same name - #dunn_sent_date = models.DateField(null=True, blank=True) # unused - #extension_date = models.DateField(null=True, blank=True) # unused - #status = models.ForeignKey(IDStatus) - @property - def status(self): - s = self.get_state() - return IDStatus().from_object(s) if s else None - - @property - def status_id(self): - return { 'active': 1, 'repl': 5, 'expired': 2, 'rfc': 3, 'auth-rm': 4, 'ietf-rm': 6 }[self.get_state_slug()] - - #intended_status = models.ForeignKey(IDIntendedStatus) - @property - def intended_status(self): - return self.intended_std_level - - #lc_sent_date = models.DateField(null=True, blank=True) - @property - def lc_sent_date(self): - e = self.latest_event(type="sent_last_call") - return e.time.date() if e else None - - #lc_changes = models.CharField(max_length=3) # used in DB, unused in Django code? - - #lc_expiration_date = models.DateField(null=True, blank=True) - @property - def lc_expiration_date(self): - e = self.latest_event(LastCallDocEvent, type="sent_last_call") - return e.expires.date() if e else None - - #b_sent_date = models.DateField(null=True, blank=True) - @property - def b_sent_date(self): - e = self.latest_event(type="sent_ballot_announcement") - return e.time.date() if e else None - - #b_discussion_date = models.DateField(null=True, blank=True) # unused - - #b_approve_date = models.DateField(null=True, blank=True) - @property - def b_approve_date(self): - e = self.latest_event(type="iesg_approved") - return e.time.date() if e else None - - #wgreturn_date = models.DateField(null=True, blank=True) # unused - - #rfc_number = models.IntegerField(null=True, blank=True, db_index=True) - @property - def rfc_number(self): - n = self.canonical_name() - return int(n[3:]) if n.startswith("rfc") else None - - #comments = models.TextField(blank=True) # unused - - #last_modified_date = models.DateField() - @property - def last_modified_date(self): - return self.time.date() - - #replaced_by = models.ForeignKey('self', db_column='replaced_by', blank=True, null=True, related_name='replaces_set') - @property - def replaced_by(self): - r = InternetDraft.objects.filter(relateddocument__target__document=self, relateddocument__relationship="replaces") - return r[0] if r else None - - @property - def replaced_by_id(self): - r = self.replaced_by - return r.id_document_tag if r else None - - #replaces = FKAsOneToOne('replaces', reverse=True) - @property - def replaces(self): - r = self.replaces_set - return r[0] if r else None - - @property - def replaces_set(self): - return InternetDraft.objects.filter(docalias__relateddocument__source=self, docalias__relateddocument__relationship="replaces") - - #review_by_rfc_editor = models.BooleanField() - @property - def review_by_rfc_editor(self): - return bool(self.tags.filter(slug='rfc-rev')) - - #expired_tombstone = models.BooleanField() - @property - def expired_tombstone(self): - return False - - #shepherd = BrokenForeignKey('PersonOrOrgInfo', null=True, blank=True, null_values=(0, )) # same name - - #idinternal = FKAsOneToOne('idinternal', reverse=True, query=models.Q(rfc_flag = 0)) - @property - def idinternal(self): - # since IDInternal is now merged into the document, we try to - # guess here - if hasattr(self, "changed_ballot_position"): - e = self.changed_ballot_position - else: - e = self.latest_event(type="changed_ballot_position") - return self if e or self.get_state("draft-iesg") else None - - # reverse relationship - @property - def authors(self): - return IDAuthor.objects.filter(document=self) - - # methods from InternetDraft - def displayname(self): - return self.name - def file_tag(self): - return "<%s>" % self.filename_with_rev() - def filename_with_rev(self): - return "%s-%s.txt" % (self.filename, self.revision_display()) - def group_acronym(self): - g = super(Document, self).group - if g.type_id == "area": - return "none" - else: - return g.acronym - def group_ml_archive(self): - return self.group.list_archive - def idstate(self): - return self.docstate() - def revision_display(self): - return self.rev - def expiration(self): - return self.expires.date() - def can_expire(self): - # Copying the logic from expire-ids-1 without thinking - # much about it. - if self.review_by_rfc_editor: - return False - idinternal = self.idinternal - if idinternal: - cur_state_id = idinternal.cur_state_id - # 42 is "AD is Watching"; this matches what's in the - # expire-ids-1 perl script. - # A better way might be to add a column to the table - # saying whether or not a document is prevented from - # expiring. - if cur_state_id < 42: - return False - return True - - def clean_abstract(self): - # Cleaning based on what "id-abstracts-text" script does - import re - a = self.abstract - a = re.sub(" *\r\n *", "\n", a) # get rid of DOS line endings - a = re.sub(" *\r *", "\n", a) # get rid of MAC line endings - a = re.sub("(\n *){3,}", "\n\n", a) # get rid of excessive vertical whitespace - a = re.sub("\f[\n ]*[^\n]*\n", "", a) # get rid of page headers - # Get rid of 'key words' boilerplate and anything which follows it: - # (No way that is part of the abstract...) - a = re.sub("(?s)(Conventions [Uu]sed in this [Dd]ocument|Requirements [Ll]anguage)?[\n ]*The key words \"MUST\", \"MUST NOT\",.*$", "", a) - # Get rid of status/copyright boilerplate - a = re.sub("(?s)\nStatus of [tT]his Memo\n.*$", "", a) - # wrap long lines without messing up formatting of Ok paragraphs: - while re.match("([^\n]{72,}?) +", a): - a = re.sub("([^\n]{72,}?) +([^\n ]*)(\n|$)", "\\1\n\\2 ", a) - # Remove leading and trailing whitespace - a = a.strip() - return a - - - # things from IDInternal - - #draft = models.ForeignKey(InternetDraft, primary_key=True, unique=True, db_column='id_document_tag') - @property - def draft(self): - return self - - @property - def draft_id(self): - return self.name - - #rfc_flag = models.IntegerField(null=True) - @property - def rfc_flag(self): - return self.get_state_slug() == "rfc" - - #ballot = models.ForeignKey(BallotInfo, related_name='drafts', db_column="ballot_id") - @property - def ballot(self): - 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 - def primary_flag(self): - # left-over from multi-ballot documents which we don't really - # support anymore, just pretend we're always primary - return True - - #group_flag = models.IntegerField(blank=True, default=0) # not used anymore, contained the group acronym_id once upon a time (so it wasn't a flag) - - #token_name = models.CharField(blank=True, max_length=25) - @property - def token_name(self): - return self.ad.plain_name() - - #token_email = models.CharField(blank=True, max_length=255) - @property - def token_email(self): - return self.ad.role_email("ad") - - #note = models.TextField(blank=True) # same name - - #status_date = models.DateField(blank=True,null=True) - @property - def status_date(self): - return self.time.date() - - #email_display = models.CharField(blank=True, max_length=50) # unused - #agenda = models.IntegerField(null=True, blank=True) - @property - def agenda(self): - e = self.latest_event(TelechatDocEvent, type="scheduled_for_telechat") - return bool(e and e.telechat_date and e.telechat_date >= datetime.date.today()) - - #cur_state = models.ForeignKey(IDState, db_column='cur_state', related_name='docs') - @property - def cur_state(self): - s = self.get_state("draft-iesg") - return IDState().from_object(s) if s else None - - @property - def cur_state_id(self): - s = self.get_state("draft-iesg") - return s.order if s else None - - #prev_state = models.ForeignKey(IDState, db_column='prev_state', related_name='docs_prev') - @property - def prev_state(self): - ds = self.history_set.exclude(states=self.get_state("draft-iesg")).order_by('-time')[:1] - if ds: - s = ds[0].get_state("draft-iesg") - if s: - return IDState().from_object(s) if ds else None - return None - - #assigned_to = models.CharField(blank=True, max_length=25) # unused - - #mark_by = models.ForeignKey(IESGLogin, db_column='mark_by', related_name='marked') - @property - def mark_by(self): - e = self.latest_event() - from ietf.person.proxy import IESGLogin as IESGLoginProxy - return IESGLoginProxy().from_object(e.by) if e else None - - # job_owner = models.ForeignKey(IESGLogin, db_column='job_owner', related_name='documents') - @property - def job_owner(self): - from ietf.person.proxy import IESGLogin as IESGLoginProxy - return IESGLoginProxy().from_object(self.ad) if self.ad else None - - #event_date = models.DateField(null=True) - @property - def event_date(self): - e = self.latest_event() - return e.time if e else None - - #area_acronym = models.ForeignKey(Area) - @property - def area_acronym(self): - from ietf.group.proxy import Area - g = super(InternetDraft, self).group # be careful with group which is proxied - if g: - if g.type_id == "area": - return Area().from_object(g) - elif g.type_id != "individ": - return Area().from_object(g.parent) - else: - return None - - #cur_sub_state = BrokenForeignKey(IDSubState, related_name='docs', null=True, blank=True, null_values=(0, -1)) - @property - def cur_sub_state(self): - s = self.tags.filter(slug__in=['extpty', 'need-rev', 'ad-f-up', 'point']) - return IDSubState().from_object(s[0]) if s else None - @property - def cur_sub_state_id(self): - s = self.cur_sub_state - return s.order if s else None - - #prev_sub_state = BrokenForeignKey(IDSubState, related_name='docs_prev', null=True, blank=True, null_values=(0, -1)) - @property - def prev_sub_state(self): - ds = self.history_set.all().order_by('-time')[:1] - substates = ds[0].tags.filter(slug__in=['extpty', 'need-rev', 'ad-f-up', 'point']) if ds else None - return IDSubState().from_object(substates[0]) if substates else None - @property - def prev_sub_state_id(self): - s = self.prev_sub_state - return s.order if s else None - - #returning_item = models.IntegerField(null=True, blank=True) - @property - def returning_item(self): - e = self.latest_event(TelechatDocEvent, type="scheduled_for_telechat") - return e.returning_item if e else None - - #telechat_date = models.DateField(null=True, blank=True) - @property - def telechat_date(self): - e = self.latest_event(TelechatDocEvent, type="scheduled_for_telechat") - return e.telechat_date if e else None - - #via_rfc_editor = models.IntegerField(null=True, blank=True) - @property - def via_rfc_editor(self): - return self.stream_id in ('ise','irtf') - - #state_change_notice_to = models.CharField(blank=True, max_length=255) - @property - def state_change_notice_to(self): - return self.notify - - #dnp = models.IntegerField(null=True, blank=True) - @property - def dnp(self): - e = self.latest_event(type__in=("iesg_disapproved", "iesg_approved")) - return e != None and e.type == "iesg_disapproved" - - #dnp_date = models.DateField(null=True, blank=True) - @property - def dnp_date(self): - e = self.latest_event(type__in=("iesg_disapproved", "iesg_approved")) - return e.time.date() if e != None and e.type == "iesg_disapproved" else None - - #noproblem = models.IntegerField(null=True, blank=True) - @property - def noproblem(self): - e = self.latest_event(type__in=("iesg_disapproved", "iesg_approved")) - return e != None and e.type == "iesg_approved" - - #resurrect_requested_by = BrokenForeignKey(IESGLogin, db_column='resurrect_requested_by', related_name='docsresurrected', null=True, blank=True) - @property - def resurrect_requested_by(self): - e = self.latest_event(type__in=("requested_resurrect", "completed_resurrect")) - from ietf.person.proxy import IESGLogin as IESGLoginProxy - return IESGLoginProxy().from_object(e.by) if e and e.type == "requested_resurrect" else None - - #approved_in_minute = models.IntegerField(null=True, blank=True) - @property - def approved_in_minute(self): - return self.latest_event(type="approved_in_minute") - - - def get_absolute_url(self): - if self.rfc_flag and self.rfc_number: - return "/doc/rfc%d/" % self.rfc_number - else: - return "/doc/%s/" % self.name - - def document(self): - return self - - def comments(self): - return DocumentComment.objects.filter(doc=self).order_by('-time') - - def public_comments(self): - return self.comments() - - def ballot_set(self): - return [self] - def ballot_primary(self): - return [self] - def ballot_others(self): - return [] - def docstate(self): - s = self.get_state("draft-iesg") - if s: - subs = self.cur_sub_state - if subs: - return "%s::%s" % (s.name, subs) - return s.name - else: - return "I-D Exists" - - # things from BallotInfo - #active = models.BooleanField() - @property - def active(self): - # taken from BallotWrapper - s = self.get_state("draft-iesg") - return self.latest_event(type="sent_ballot_announcement") and s and s.name in ['In Last Call', 'Waiting for Writeup', 'Waiting for AD Go-Ahead', 'IESG Evaluation', 'IESG Evaluation - Defer'] and (self.get_state_slug() in ("rfc", "active")) - - #an_sent = models.BooleanField() - @property - def an_sent(self): - return bool(self.latest_event(type="iesg_approved")) - - #an_sent_date = models.DateField(null=True, blank=True) - @property - def an_sent_date(self): - e = self.latest_event(type="iesg_approved") - return e.time if e else None - - #an_sent_by = models.ForeignKey(IESGLogin, db_column='an_sent_by', related_name='ansent', null=True) - @property - def an_sent_by(self): - e = self.latest_event(type="iesg_approved") - from ietf.person.proxy import IESGLogin as IESGLoginProxy - return IESGLoginProxy().from_object(e.by) if e else None - - #defer = models.BooleanField() - @property - def defer(self): - # we're deferred if we're in the deferred state - return self.get_state_slug("draft-iesg") == "defer" - - #defer_by = models.ForeignKey(IESGLogin, db_column='defer_by', related_name='deferred', null=True) - @property - def defer_by(self): - e = self.latest_event(type="changed_document", desc__startswith="State changed to IESG Evaluation - Defer") - from ietf.person.proxy import IESGLogin as IESGLoginProxy - return IESGLoginProxy().from_object(e.by) if e else None - - #defer_date = models.DateField(null=True, blank=True) - @property - def defer_date(self): - e = self.latest_event(type="changed_document", desc__startswith="State changed to IESG Evaluation - Defer") - return e.time.date() if e else None - - #approval_text = models.TextField(blank=True) - @property - def approval_text(self): - e = self.latest_event(WriteupDocEvent, type="changed_ballot_approval_text") - return e.text if e else "" - - #last_call_text = models.TextField(blank=True) - @property - def last_call_text(self): - e = self.latest_event(WriteupDocEvent, type="changed_last_call_text") - return e.text if e else "" - - #ballot_writeup = models.TextField(blank=True) - @property - def ballot_writeup(self): - e = self.latest_event(WriteupDocEvent, type="changed_ballot_writeup_text") - return e.text if e else "" - - #ballot_issued = models.IntegerField(null=True, blank=True) - @property - def ballot_issued(self): - return bool(self.latest_event(type="sent_ballot_announcement")) - - # def remarks(self): # apparently not used - # remarks = list(self.discusses.all()) + list(self.comments.all()) - # return remarks - def active_positions(self): - """Returns a list of dicts, with AD and Position tuples""" - from ietf.person.proxy import IESGLogin as IESGLoginProxy - - res = [] - for ad, pos in self.active_ballot().active_ad_positions().iteritems(): - res.append(dict(ad=IESGLoginProxy().from_object(ad), pos=Position().from_object(pos) if pos else None)) - - res.sort(key=lambda x: x["ad"].last_name) - - return res - - def needed(self, standardsTrack=True): - """Returns text answering the question what does this document - need to pass?. The return value is only useful if the document - is currently in IESG evaluation.""" - tmp = self.active_positions() - positions = [x["pos"] for x in tmp if x["pos"]] - ads = [x["ad"] for x in tmp] - - yes = noobj = discuss = recuse = 0 - for position in positions: - p = position.pos_id - if p == "yes": - yes += 1 - if p == "noobj": - noobj += 1 - if p == "discuss": - discuss += 1 - if p == "recuse": - recuse += 1 - answer = '' - if yes < 1: - answer += "Needs a YES. " - if discuss > 0: - if discuss == 1: - answer += "Has a DISCUSS. " - else: - answer += "Has %d DISCUSSes. " % discuss - if standardsTrack: - # For standards-track, need positions from 2/3 of the - # non-recused current IESG. - needed = int(math.ceil((len(ads) - recuse) * 2.0/3.0)) - else: - # Info and experimental only need one position. - # Info and experimental without Yes have their full spec now. - if yes < 1: - return answer.rstrip() - else: - needed = 1 - have = yes + noobj - if have < needed: - more = needed - have - if more == 1: - answer += "Needs one more YES or NO OBJECTION position " - else: - answer += "Needs %d more YES or NO OBJECTION positions " % more - if discuss: - if discuss == 1: - answer += "once the DISCUSS is resolved." - else: - answer += "once %d DISCUSSes are resolved." % discuss - else: - answer += ". " - else: - answer += "Has enough positions to pass" - if discuss: - if discuss == 1: - answer += "once the DISCUSS is resolved" - else: - answer += "once %d DISCUSSes are resolved" % discuss - answer += ". " - - return answer.rstrip() - - - # things from RfcIndex - - #rfc_number = models.IntegerField(primary_key=True) # already taken care of - #title = models.CharField(max_length=250) # same name - #authors = models.CharField(max_length=250) # exists already - #rfc_published_date = models.DateField() - @property - def rfc_published_date(self): - if hasattr(self, 'published_rfc'): - e = self.published_rfc - else: - e = self.latest_event(type="published_rfc") - return e.time.date() if e else datetime.date(1990,1,1) - - #current_status = models.CharField(max_length=50,null=True) - @property - def current_status(self): - if self.std_level: - return self.std_level.name - else: - return u"(None)" - - #updates = models.CharField(max_length=200,blank=True,null=True) - @property - def updates(self): - return ",".join("RFC%s" % n for n in sorted(d.rfc_number for d in InternetDraft.objects.filter(docalias__relateddocument__source=self, docalias__relateddocument__relationship="updates"))) - - #updated_by = models.CharField(max_length=200,blank=True,null=True) - @property - def updated_by(self): - if not hasattr(self, "updated_by_list"): - self.updated_by_list = [d.rfc_number for d in InternetDraft.objects.filter(relateddocument__target__document=self, relateddocument__relationship="updates")] - return ",".join("RFC%s" % n for n in sorted(self.updated_by_list)) - - #obsoletes = models.CharField(max_length=200,blank=True,null=True) - @property - def obsoletes(self): - return ",".join("RFC%s" % n for n in sorted(d.rfc_number for d in InternetDraft.objects.filter(docalias__relateddocument__source=self, docalias__relateddocument__relationship="obs"))) - - #obsoleted_by = models.CharField(max_length=200,blank=True,null=True) - @property - def obsoleted_by(self): - if not hasattr(self, "obsoleted_by_list"): - self.obsoleted_by_list = [d.rfc_number for d in InternetDraft.objects.filter(relateddocument__target__document=self, relateddocument__relationship="obs")] - return ",".join("RFC%s" % n for n in sorted(self.obsoleted_by_list)) - - #also = models.CharField(max_length=50,blank=True,null=True) - @property - def also(self): - aliases = self.docalias_set.filter(models.Q(name__startswith="bcp") | - models.Q(name__startswith="std") | - models.Q(name__startswith="bcp")) - return aliases[0].name.upper() if aliases else None - - #draft = models.CharField(max_length=200,null=True) # have to ignore this, it's already implemented - - #has_errata = models.BooleanField() - @property - def has_errata(self): - return bool(self.tags.filter(slug="errata")) - - #stream = models.CharField(max_length=15,blank=True,null=True) - @property - def stream(self): - s = super(InternetDraft, self).stream - return s.name if s else None - - #wg = models.CharField(max_length=15,blank=True,null=True) - @property - def wg(self): - return self.group.acronym - - #file_formats = models.CharField(max_length=20,blank=True,null=True) - @property - def file_formats(self): - return self.get_file_type_matches_from(os.path.join(settings.RFC_PATH, "rfc" + str(self.rfc_number))).replace(".", "").replace("txt", "ascii") - - @property - def positions(self): - res = [] - found = set() - for pos in Position.objects.filter(doc=self, type="changed_ballot_position").select_related('ad').order_by("-time", "-id"): - if pos.ad not in found: - found.add(pos.ad) - res.append(pos) - - class Dummy: - def all(self): - return self.res - d = Dummy() - d.res = res - return d - - @property - def ipr(self): - return IprDraftProxy.objects.filter(doc_alias__document=self.pk) - - class Meta: - proxy = True - -IDInternal = InternetDraft -BallotInfo = InternetDraft -RfcIndex = InternetDraft -Rfc = InternetDraft - - -class IDAuthor(DocumentAuthor): - #document = models.ForeignKey(InternetDraft, db_column='id_document_tag', related_name='authors') # same name - #person = models.ForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag') - @property - def person(self): - return self.author.person - - #author_order = models.IntegerField() - @property - def author_order(self): - return self.order - - def email(self): - return None if self.author.address.startswith("unknown-email") else self.author.address - - def final_author_order(self): - return self.order - - class Meta: - proxy = True - -class DocumentComment(DocEvent): - objects = TranslatingManager(dict(comment_text="desc", - date="time" - )) - - 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) - @property - def version(self): - e = self.doc.latest_event(NewRevisionDocEvent, type="new_revision", time__lte=self.time) - return e.rev if e else "0" - #comment_text = models.TextField(blank=True) - @property - def comment_text(self): - return self.desc - #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 "/doc/%s/" % self.doc.name - def get_author(self): - return self.by.plain_name() - def get_username(self): - return unicode(self.by) - def get_fullname(self): - return self.by.plain_name() - def datetime(self): - return self.time - def doc_id(self): - return self.doc_id - def doc_name(self): - return self.doc.name - def __str__(self): - return "\"%s...\" by %s" % (self.comment_text[:20], self.get_author()) - - class Meta: - proxy = True - - -class Position(BallotPositionDocEvent): - def from_object(self, base): - for f in base._meta.fields: - if not f.name in ('discuss', 'ad', 'ballot', ): # don't overwrite properties - setattr(self, f.name, getattr(base, f.name)) - - self.orig = base - return self - - #ballot = models.ForeignKey(BallotInfo, related_name='positions') - @property - def ballot(self): - return self.doc # FIXME: doesn't emulate old interface - - # ad = models.ForeignKey(IESGLogin) # same name - @property - def ad(self): - from ietf.person.proxy import IESGLogin - return IESGLogin().from_object(self.orig.ad if hasattr(self, "orig") else super(Position, self).ad) - - #yes = models.IntegerField(db_column='yes_col') - @property - def yes(self): - return self.pos_id == "yes" - #noobj = models.IntegerField(db_column='no_col') - @property - def noobj(self): - return self.pos_id == "noobj" - #abstain = models.IntegerField() - @property - def abstain(self): - return self.pos_id == "abstain" - #approve = models.IntegerField(default=0) # unused - #discuss = models.IntegerField() - # needs special treatment because of clash with attribute on base class - def get_discuss(self): - return self.pos_id == "discuss" - def set_discuss(self, x): - pass - discuss = property(get_discuss, set_discuss) - #recuse = models.IntegerField() - @property - def recuse(self): - return self.pos_id == "recuse" - def __str__(self): - return "Position for %s on %s" % ( self.ad, self.ballot ) - def abstain_ind(self): - if self.recuse: - return 'R' - if self.abstain: - return 'X' - else: - return ' ' - def name(self): - return self.pos.name if self.pos else "No Record" - - class Meta: - proxy = True - -class DraftLikeDocAlias(DocAlias): - # this class is mostly useful for the IPR part - - def __str__(self): - return str(unicode(self)) - - def __unicode__(self): - if self.name.startswith("rfc"): - return "RFC%04d" % int(self.name[3:]) - else: - return self.name - - @property - def id_document_tag(self): - return self.name - - @property - def title(self): - return self.document.title - - @property - def filename(self): - return self.name - - @property - def ipr(self): - return IprDraftProxy.objects.filter(doc_alias=self.pk) - - class Meta: - proxy = True - -class ObjectHistoryEntryProxy(DocEvent): - #date = models.DateTimeField(_('Date'), auto_now_add=True) - @property - def date(self): - return self.time - #comment = models.TextField(_('Comment')) - @property - def comment(self): - return "" - #person = models.ForeignKey(PersonOrOrgInfo) - @property - def person(self): - return self.by - - def get_real_instance(self): - return self - - def describe_change(self): - return u"
%s
" % self.desc - - class Meta: - proxy = True - -class IDStatus(State): - def from_object(self, base): - for f in base._meta.fields: - setattr(self, f.name, getattr(base, f.name)) - return self - - #status_id = models.AutoField(primary_key=True) - - #status = models.CharField(max_length=25, db_column='status_value') - @property - def status(self): - return self.name - - def __unicode__(self): - return super(self.__class__, self).__unicode__() - - class Meta: - proxy = True - -class IDState(State): - PUBLICATION_REQUESTED = 10 - LAST_CALL_REQUESTED = 15 - IN_LAST_CALL = 16 - WAITING_FOR_WRITEUP = 18 - WAITING_FOR_AD_GO_AHEAD = 19 - IESG_EVALUATION = 20 - IESG_EVALUATION_DEFER = 21 - APPROVED_ANNOUNCEMENT_SENT = 30 - AD_WATCHING = 42 - DEAD = 99 - DO_NOT_PUBLISH_STATES = (33, 34) - - objects = TranslatingManager(dict(pk=lambda v: ("order", v, "type", "draft-iesg"), - document_state_id=lambda v: ("order", v, "type", "draft-iesg"), - document_state_id__in=lambda v: ("order__in", v, "type", "draft-iesg")), - always_filter=dict(type="draft-iesg")) - - def from_object(self, base): - for f in base._meta.fields: - setattr(self, f.name, getattr(base, f.name)) - return self - - #document_state_id = models.AutoField(primary_key=True) - @property - def document_state_id(self): - return self.order - - #state = models.CharField(max_length=50, db_column='document_state_val') - @property - def state(self): - return self.name - - #equiv_group_flag = models.IntegerField(null=True, blank=True) # unused - #description = models.TextField(blank=True, db_column='document_desc') - @property - def description(self): - return self.desc - - @property - def nextstate(self): - # simulate related queryset - return IDState.objects.filter(pk__in=[x.pk for x in self.next_states.all()]) - - @property - def next_state(self): - # simulate IDNextState - return self - - def __str__(self): - return self.state - - @staticmethod - def choices(): - return [(state.pk, state.name) for state in IDState.objects.all()] - - class Meta: - proxy = True - - - - -# proxy stuff for ipr -from ietf.ipr.models import IprDocAlias - -class IprDraftProxy(IprDocAlias): - objects = TranslatingManager(dict(document="doc_alias__name")) - - # document = models.ForeignKey(InternetDraft, db_column='id_document_tag', "ipr") - # document = models.ForeignKey(Rfc, db_column='rfc_number', related_name="ipr") - @property - def document(self): - return DraftLikeDocAlias.objects.get(pk=self.doc_alias_id) - - #revision = models.CharField(max_length=2) - @property - def revision(self): - return self.rev - - class Meta: - proxy = True - -IprDraft = IprDraftProxy - -class IprRfcProxy(IprDocAlias): - objects = TranslatingManager(dict(document=lambda v: ("doc_alias__name", "rfc%s" % v))) - - # document = models.ForeignKey(InternetDraft, db_column='id_document_tag', "ipr") - # document = models.ForeignKey(Rfc, db_column='rfc_number', related_name="ipr") - @property - def document(self): - return DraftLikeDocAlias.objects.get(pk=self.doc_alias_id) - - #revision = models.CharField(max_length=2) - @property - def revision(self): - return self.rev - - class Meta: - proxy = True - -IprRfc = IprRfcProxy diff --git a/ietf/group/proxy.py b/ietf/group/proxy.py deleted file mode 100644 index 52c5ce487..000000000 --- a/ietf/group/proxy.py +++ /dev/null @@ -1,271 +0,0 @@ -from ietf.utils.proxy import TranslatingManager, proxy_role_email - -from models import * - -class Acronym(Group): - class LazyIndividualSubmitter(object): - def __get__(self, obj, type=None): - return Group.objects.get(acronym="none").id - - INDIVIDUAL_SUBMITTER = LazyIndividualSubmitter() - - def from_object(self, base): - for f in base._meta.fields: - setattr(self, f.name, getattr(base, f.name)) - return self - - #acronym_id = models.AutoField(primary_key=True) - @property - def acronym_id(self): - return self.id - #acronym = models.CharField(max_length=12) # same name - #name = models.CharField(max_length=100) # same name - #name_key = models.CharField(max_length=50, editable=False) - @property - def name_key(self): - return self.name.upper() - - @property - def ietfwg(self): - return IETFWG().from_object(self) - - def __str__(self): - return self.acronym - - def __unicode__(self): - return self.acronym - - class Meta: - proxy = True - -class Area(Group): - objects = TranslatingManager(dict(area_acronym__acronym="acronym", - area_acronym__name="name", - status=lambda v: ("state", {1: "active", 2: "dormant", 3: "conclude"}[v] )), - always_filter=dict(type="area")) - - def from_object(self, base): - for f in base._meta.fields: - setattr(self, f.name, getattr(base, f.name)) - return self - - ACTIVE=1 - #area_acronym = models.OneToOneField(Acronym, primary_key=True) - @property - def area_acronym(self): - return Acronym().from_object(self) - - #start_date = models.DateField(auto_now_add=True) - #concluded_date = models.DateField(null=True, blank=True) - #status = models.ForeignKey(AreaStatus) - @property - def status_id(self): - return { "active": 1, "dormant": 2, "conclude": 3, "proposed": 4 }[self.state_id] - #comments = models.TextField(blank=True) - #last_modified_date = models.DateField(auto_now=True) - @property - def last_modified_date(self): - return self.time.date() - #extra_email_addresses = models.TextField(blank=True,null=True) - - #def additional_urls(self): - # return AreaWGURL.objects.filter(name=self.area_acronym.name) - def active_wgs(self): - return IETFWG.objects.filter(type="wg", state="active", parent=self).select_related('type', 'state', 'parent').order_by("acronym") - - @property - def areadirector_set(self): - return proxied_role_emails(Email.objects.filter(role__group=self, role__name="ad")) - - @staticmethod - def active_areas(): - return Area.objects.filter(type="area", state="active").select_related('type', 'state', 'parent').order_by('acronym') - - def __str__(self): - return self.acronym - def __unicode__(self): - return self.acronym - - class Meta: - proxy = True - -def proxied_role_emails(emails): - for e in emails: - proxy_role_email(e) - return emails - -class WGDelegateProxy(Role): - #person = models.ForeignKey(PersonOrOrgInfo) # same name - #wg = models.ForeignKey(IETFWG) - @property - def wg(self): - return self.group - - def __unicode__(self): - return u"%s" % self.person - - class Meta: - proxy = True - -class IETFWG(Group): - objects = TranslatingManager(dict(group_acronym="id", - group_acronym__acronym="acronym", - group_acronym__acronym__in="acronym__in", - group_acronym__acronym__contains="acronym__contains", - email_archive__startswith="list_archive__startswith", - group_type=lambda v: ("type__in", { 1: ("wg",), 2: ("wg", "rg") }[int(v)]), - status=lambda v: ("state__in", { 1: ("active", "bof") }[int(v)]), - areagroup__area__status=lambda v: ("parent__state", { 1: "active" }[v]), - start_date__isnull=lambda v: None if v else ("groupevent__changestategroupevent__state__slug", "active"), - ), - always_filter=dict(type__in=("wg", "rg", "individ", "area"))) - - def from_object(self, base): - for f in base._meta.fields: - setattr(self, f.name, getattr(base, f.name)) - return self - - ACTIVE=1 - #group_acronym = models.OneToOneField(Acronym, primary_key=True, editable=False) - @property - def group_acronym(self): - return Acronym().from_object(self) - - #group_type = models.ForeignKey(WGType) - #proposed_date = models.DateField(null=True, blank=True) - #start_date = models.DateField(null=True, blank=True) - @property - def start_date(self): - e = GroupEvent.objects.filter(group=self, type="changed_state", changestategroupevent__state="active").order_by('time')[:1] - return e[0].time.date() if e else None - - #dormant_date = models.DateField(null=True, blank=True) - #concluded_date = models.DateField(null=True, blank=True) - #status = models.ForeignKey(WGStatus) - @property - def status_id(self): - return { "active": 1, "dormant": 2, "conclude": 3, "bof-conc": 3, "proposed": 4, "bof": 4, "abandon": 4, "replaced": 4}[self.state_id] - #area_director = models.ForeignKey(AreaDirector, null=True) - #meeting_scheduled = models.CharField(blank=True, max_length=3) - @property - def meeting_scheduled(self): - from ietf.meeting.models import Meeting - latest_meeting = Meeting.objects.order_by('-date')[0] - return "YES" if self.session_set.filter(meeting=latest_meeting) else "NO" - #email_address = models.CharField(blank=True, max_length=60) - @property - def email_address(self): - return self.list_email - #email_subscribe = models.CharField(blank=True, max_length=120) - @property - def email_subscribe(self): - return self.list_subscribe - #email_keyword = models.CharField(blank=True, max_length=50) - #email_archive = models.CharField(blank=True, max_length=95) - @property - def email_archive(self): - return self.list_archive - #comments = models.TextField(blank=True) - #last_modified_date = models.DateField() - @property - def last_modified_date(self): - return self.time.date() - #meeting_scheduled_old = models.CharField(blank=True, max_length=3) - #area = FKAsOneToOne('areagroup', reverse=True) - @property - def area(self): - if self.parent: - areagroup = AreaGroup().from_object(self) - return areagroup - else: - return None - - def __str__(self): - return self.group_acronym.acronym - - def __unicode__(self): - return self.group_acronym.acronym - - def active_drafts(self): - from ietf.doc.proxy import InternetDraft - return InternetDraft.objects.filter(group=self, states__type="draft", states__slug="active") - # def choices(): - # return [(wg.group_acronym_id, wg.group_acronym.acronym) for wg in IETFWG.objects.all().filter(group_type__type='WG').select_related().order_by('acronym.acronym')] - # choices = staticmethod(choices) - def area_acronym(self): - return Area().from_object(self.parent) if self.parent else None - def area_directors(self): - if not self.parent: - return None - return proxied_role_emails(sorted(Email.objects.filter(role__group=self.parent, role__name="ad"), key=lambda e: e.person.name_parts()[3])) - def chairs(self): # return a set of WGChair objects for this work group - return proxied_role_emails(sorted(Email.objects.filter(role__group=self, role__name="chair"), key=lambda e: e.person.name_parts()[3])) - # def secretaries(self): # return a set of WGSecretary objects for this group - # return WGSecretary.objects.filter(group_acronym__exact=self.group_acronym) - # def milestones(self): # return a set of GoalMilestone objects for this group - # return GoalMilestone.objects.filter(group_acronym__exact=self.group_acronym) - # def rfcs(self): # return a set of Rfc objects for this group - # return Rfc.objects.filter(group_acronym__exact=self.group_acronym) - # def drafts(self): # return a set of Rfc objects for this group - # return InternetDraft.objects.filter(group__exact=self.group_acronym) - def charter_text(self): # return string containing WG description read from file - from ietf.group.utils import get_charter_text - return get_charter_text(self) - def additional_urls(self): - return self.groupurl_set.all().order_by("name") - def clean_email_archive(self): - return self.list_archive - @property - def wgchair_set(self): - # gross hack ... - class Dummy: pass - d = Dummy() - d.all = self.chairs - return d - @property - def wgdelegate_set(self): - return WGDelegateProxy.objects.filter(group=self, name="delegate") - - class Meta: - proxy = True - -class IRTF(Group): - objects = TranslatingManager(dict(), - always_filter=dict(type="rg")) - - #irtf_id = models.AutoField(primary_key=True) - @property - def irtf_id(self): - return self.pk - #acronym = models.CharField(blank=True, max_length=25, db_column='irtf_acronym') # same name - #name = models.CharField(blank=True, max_length=255, db_column='irtf_name') # same name - #charter_text = models.TextField(blank=True,null=True) - #meeting_scheduled = models.BooleanField(blank=True) - def __str__(self): - return self.acronym - def __unicode__(self): - return self.acronym - #def chairs(self): # return a set of IRTFChair objects for this work group - # return IRTFChair.objects.filter(irtf=self) - class Meta: - proxy = True - -class AreaGroup(Group): - objects = TranslatingManager(dict(group=lambda v: ("pk", v.pk)), - always_filter=dict(type="wg")) - - def from_object(self, base): - for f in base._meta.fields: - setattr(self, f.name, getattr(base, f.name)) - return self - - @property - def area(self): - return Area().from_object(self.parent) - - @property - def group(self): - return self - - class Meta: - proxy = True diff --git a/ietf/name/proxy.py b/ietf/name/proxy.py deleted file mode 100644 index dfe75371e..000000000 --- a/ietf/name/proxy.py +++ /dev/null @@ -1,63 +0,0 @@ -from ietf.utils.proxy import TranslatingManager -from models import * - -class IDSubStateManager(TranslatingManager): - def __init__(self, *args): - super(IDSubStateManager, self).__init__(*args) - - def all(self): - return self.filter(slug__in=['extpty', 'need-rev', 'ad-f-up', 'point']) - -class IDSubState(DocTagName): - objects = IDSubStateManager(dict(pk="order")) - - def from_object(self, base): - for f in base._meta.fields: - setattr(self, f.name, getattr(base, f.name)) - return self - - #sub_state_id = models.AutoField(primary_key=True) - @property - def sub_state_id(self): - return self.order - - #sub_state = models.CharField(max_length=55, db_column='sub_state_val') - @property - def sub_state(self): - return self.name - - #description = models.TextField(blank=True, db_column='sub_state_desc') - @property - def description(self): - return self.desc - - def __str__(self): - return self.sub_state - - class Meta: - proxy = True - - -class AnnotationTagObjectRelationProxy(DocTagName): - objects = TranslatingManager(dict(annotation_tag__name="name")) - - @property - def annotation_tag(self): - return self - - class Meta: - proxy = True - -class StreamProxy(StreamName): - def get_chairs(self): - from ietf.group.models import Role - from ietf.utils.proxy import proxy_personify_role - return [proxy_personify_role(r) for r in Role.objects.filter(group__acronym=self.slug, name="chair")] - - def get_delegates(self): - from ietf.group.models import Role - from ietf.utils.proxy import proxy_personify_role - return [proxy_personify_role(r) for r in Role.objects.filter(group__acronym=self.slug, name="delegate")] - - class Meta: - proxy = True diff --git a/ietf/person/proxy.py b/ietf/person/proxy.py deleted file mode 100644 index 50a8ef117..000000000 --- a/ietf/person/proxy.py +++ /dev/null @@ -1,55 +0,0 @@ -from ietf.utils.proxy import TranslatingManager - -from models import * - -class IESGLogin(Person): - objects = TranslatingManager(dict(user_level__in=None, - first_name="name" - )) - - def from_object(self, base): - for f in base._meta.fields: - setattr(self, f.name, getattr(base, f.name)) - return self - - SECRETARIAT_LEVEL = 0 - AD_LEVEL = 1 - INACTIVE_AD_LEVEL = 2 - - #login_name = models.CharField(blank=True, max_length=255) - @property - def login_name(self): raise NotImplemented - #password = models.CharField(max_length=25) - @property - def password(self): raise NotImplemented - #user_level = models.IntegerField(choices=USER_LEVEL_CHOICES) - @property - def user_level(self): raise NotImplemented - - #first_name = models.CharField(blank=True, max_length=25) - @property - def first_name(self): - return self.name_parts()[1] - - #last_name = models.CharField(blank=True, max_length=25) - @property - def last_name(self): - return self.name_parts()[3] - - # FIXME: person isn't wrapped yet - #person = BrokenForeignKey(PersonOrOrgInfo, db_column='person_or_org_tag', unique=True, null_values=(0, 888888), null=True) - - # apparently unused - #pgp_id = models.CharField(blank=True, null=True, max_length=20) - #default_search = models.NullBooleanField() - - def __str__(self): - return self.plain_name() - def is_current_ad(self): - return bool(self.role_set.filter(name="ad", group__state="active")) - @staticmethod - def active_iesg(): - return IESGLogin.objects.filter(role__name="ad", role__group__state="active").distinct().order_by('name') - - class Meta: - proxy = True diff --git a/ietf/utils/proxy.py b/ietf/utils/proxy.py deleted file mode 100644 index 3d445b738..000000000 --- a/ietf/utils/proxy.py +++ /dev/null @@ -1,282 +0,0 @@ -# some helpers for the proxy layer bridging the gap between the legacy -# and the redesigned schema, eventually this should all go - -from django.db.models.manager import Manager -from django.db.models.query import QuerySet - -def proxy_personify_role(role): - """Turn role into person with email() method using email from role.""" - p = role.person - p.email = lambda: (p.plain_name(), role.email.address) - return p - -def proxy_role_email(e): - """Add email() method to person on email.""" - e.person.email = lambda: (e.person.plain_name(), e.address) - return e - -def chunks(l, n): - """Split list l up in chunks of max size n.""" - return (l[i:i+n] for i in xrange(0, len(l), n)) - -class TranslatingQuerySet(QuerySet): - """Query set that can do some simple mappings of the filter args.""" - - 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() - for k, v in kwargs.iteritems(): - if k in trans: - t = trans[k] - if callable(t): - ts = t(v) - else: - ts = (t, v) - - for t, v in chunks(ts, 2): - if t: - res[t] = v - else: - res[k] = v - return res - - # overridden methods - def _clone(self, *args, **kwargs): - c = super(TranslatingQuerySet, self)._clone(*args, **kwargs) - c.translated_attrs = self.translated_attrs - return c - - def dates(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).dates(*args, **kwargs) - - def distinct(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).distinct(*args, **kwargs) - - def extra(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).extra(*args, **kwargs) - - def get(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).get(*args, **kwargs) - - def get_or_create(self, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).get_or_create(**kwargs) - - def create(self, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).create(**kwargs) - - def filter(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).filter(*args, **kwargs) - - def aggregate(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).aggregate(*args, **kwargs) - - def annotate(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).annotate(*args, **kwargs) - - def complex_filter(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).complex_filter(*args, **kwargs) - - def exclude(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).exclude(*args, **kwargs) - - def in_bulk(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).in_bulk(*args, **kwargs) - - def iterator(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).iterator(*args, **kwargs) - - def latest(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).latest(*args, **kwargs) - - def order_by(self, *args, **kwargs): - args = self.translated_args(args) - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).order_by(*args, **kwargs) - - def select_related(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).select_related(*args, **kwargs) - - def values(self, *args, **kwargs): - args = self.translated_args(args) - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).values(*args, **kwargs) - - def values_list(self, *args, **kwargs): - args = self.translated_args(args) - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).values_list(*args, **kwargs) - - def update(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).update(*args, **kwargs) - - def reverse(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).reverse(*args, **kwargs) - - def defer(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).defer(*args, **kwargs) - - def only(self, *args, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self).only(*args, **kwargs) - - def _insert(self, values, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return insert_query(self.model, values, **kwargs) - - def _update(self, values, **kwargs): - kwargs = self.translated_kwargs(kwargs) - return super(TranslatingQuerySet, self)._update(values, **kwargs) - -class TranslatingManager(Manager): - """Translates keyword arguments for the ORM, for use in proxy - wrapping, e.g. given trans={'foo': 'bar'} it will transform a - lookup of the field foo to a lookup on the field bar. The right - hand side can either be a string or a function which is called - with the right-hand side to transform it.""" - - def __init__(self, trans, always_filter=None): - super(TranslatingManager, self).__init__() - self.translated_attrs = trans - self.always_filter = always_filter - - def get_query_set(self): - qs = TranslatingQuerySet(self.model) - qs.translated_attrs = self.translated_attrs - if self.always_filter: - qs = qs.filter(**self.always_filter) - return qs - - # def dates(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().dates(*args, **kwargs) - - # def distinct(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().distinct(*args, **kwargs) - - # def extra(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().extra(*args, **kwargs) - - # def get(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().get(*args, **kwargs) - - # def get_or_create(self, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().get_or_create(**kwargs) - - # def create(self, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().create(**kwargs) - - # def filter(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().filter(*args, **kwargs) - - # def aggregate(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().aggregate(*args, **kwargs) - - # def annotate(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().annotate(*args, **kwargs) - - # def complex_filter(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().complex_filter(*args, **kwargs) - - # def exclude(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().exclude(*args, **kwargs) - - # def in_bulk(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().in_bulk(*args, **kwargs) - - # def iterator(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().iterator(*args, **kwargs) - - # def latest(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().latest(*args, **kwargs) - - # def order_by(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().order_by(*args, **kwargs) - - # def select_related(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().select_related(*args, **kwargs) - - # def values(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().values(*args, **kwargs) - - # def values_list(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().values_list(*args, **kwargs) - - # def update(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().update(*args, **kwargs) - - # def reverse(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().reverse(*args, **kwargs) - - # def defer(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().defer(*args, **kwargs) - - # def only(self, *args, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set().only(*args, **kwargs) - - # def _insert(self, values, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return insert_query(self.model, values, **kwargs) - - # def _update(self, values, **kwargs): - # kwargs = self.translated_kwargs(kwargs) - # return self.get_query_set()._update(values, **kwargs)