From cfb841190fd0bc31aab8c10c4ab5936c36ad5fb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20A=2E=20S=C3=A1nchez=20L=C3=B3pez?= Date: Thu, 26 May 2011 09:58:37 +0000 Subject: [PATCH 01/10] Remove workflow stuff from the document list template. Fixes #671 - Legacy-Id: 3154 --- ietf/templates/ietfworkflows/stream_state.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ietf/templates/ietfworkflows/stream_state.html b/ietf/templates/ietfworkflows/stream_state.html index f4ffbf4b3..80617b02b 100644 --- a/ietf/templates/ietfworkflows/stream_state.html +++ b/ietf/templates/ietfworkflows/stream_state.html @@ -2,7 +2,7 @@
{% if stream %} - {{ stream }} {% if state %}:: {{ state }}{% endif %} + {{ stream }} {% if state %}:: {{ state.name }}{% endif %} {% else %} No stream asigned {% endif %} From 8f196b450dee64764276995e90eddb871b177791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20A=2E=20S=C3=A1nchez=20L=C3=B3pez?= Date: Thu, 30 Jun 2011 09:44:40 +0000 Subject: [PATCH 02/10] Extend the query that search for allowed to login users. Fixes #681 - Legacy-Id: 3192 --- ietf/wgchairs/forms.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/ietf/wgchairs/forms.py b/ietf/wgchairs/forms.py index 7aca1291c..d75f4d2fc 100644 --- a/ietf/wgchairs/forms.py +++ b/ietf/wgchairs/forms.py @@ -1,6 +1,7 @@ from django import forms from django.conf import settings from django.core.mail import EmailMessage +from django.db.models import Q from django.forms.models import BaseModelFormSet from django.template.loader import render_to_string from django.utils.safestring import mark_safe @@ -191,7 +192,10 @@ class AddDelegateForm(RelatedWGForm): return self.next_form def get_person(self, email): - persons = PersonOrOrgInfo.objects.filter(emailaddress__address=email, iesglogin__isnull=False).distinct() + persons = PersonOrOrgInfo.objects.filter(emailaddress__address=email).filter( + Q(iesglogin__isnull=False)| + Q(legacywgpassword__isnull=False)| + Q(legacyliaisonuser__isnull=False)).distinct() if not persons: raise PersonOrOrgInfo.DoesNotExist if len(persons) > 1: @@ -244,7 +248,10 @@ class MultipleDelegateForm(AddDelegateForm): if not self.email: self.email = self.data.get('email', None) self.fields['email'].initial = self.email - self.fields['persons'].choices = [(i.pk, unicode(i)) for i in PersonOrOrgInfo.objects.filter(emailaddress__address=self.email, iesglogin__isnull=False).distinct().order_by('first_name')] + self.fields['persons'].choices = [(i.pk, unicode(i)) for i in PersonOrOrgInfo.objects.filter(emailaddress__address=self.email).filter( + Q(iesglogin__isnull=False)| + Q(legacywgpassword__isnull=False)| + Q(legacyliaisonuser__isnull=False)).distinct().order_by('first_name')] def save(self): person_id = self.cleaned_data.get('persons') From e7672a79c3603151431862dba7852efd4cc306ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20A=2E=20S=C3=A1nchez=20L=C3=B3pez?= Date: Tue, 2 Aug 2011 06:38:12 +0000 Subject: [PATCH 03/10] Removed duplicated group from model. See #694 - Legacy-Id: 3273 --- ietf/ietfworkflows/fixtures/initial_data.xml | 450 +----------------- .../0011_remove_group_from_stream.py | 205 ++++++++ .../0012_refactor_stream_group_descrition.py | 222 +++++++++ ietf/ietfworkflows/models.py | 39 +- 4 files changed, 468 insertions(+), 448 deletions(-) create mode 100644 ietf/ietfworkflows/migrations/0011_remove_group_from_stream.py create mode 100644 ietf/ietfworkflows/migrations/0012_refactor_stream_group_descrition.py diff --git a/ietf/ietfworkflows/fixtures/initial_data.xml b/ietf/ietfworkflows/fixtures/initial_data.xml index a8901f482..704815095 100644 --- a/ietf/ietfworkflows/fixtures/initial_data.xml +++ b/ietf/ietfworkflows/fixtures/initial_data.xml @@ -1,461 +1,27 @@ - - Default WG Workflow - 11 - - - IAB Workflow - - - - IRTF Workflow - - - - ISE Workflow - - - - Active IAB Document - 2 - - - - Active RG Document - 3 - - - - Adopted by a WG - 1 - - - - Adopted for WG Info Only - 1 - - - - Approved by IAB, To Be Sent to RFC Editor - 2 - - - - Awaiting IRSG Reviews - 3 - - - - Call For Adoption By WG Issued - 1 - - - - Candidate IAB Document - 2 - - - - Candidate RG Document - 3 - - - - Community Review - 2 - - - - Dead IAB Document - 2 - - - - Dead IRTF Document - 3 - - - - Dead WG Document - 1 - - - - Document on Hold Based On IESG Request - 3 - - - - Document on Hold Based On IESG Request - 4 - - - - Finding Reviewers - 4 - - - - IAB Review - 2 - - - - In IESG Review - 3 - - - - In IESG Review - 4 - - - - In IRSG Poll - 3 - - - - In ISE Review - 4 - - - - In RG Last Call - 3 - - - - In WG Last Call - 1 - - - - No Longer In Independent Submission Stream - 4 - - - - Parked IAB Document - 2 - - - - Parked RG Document - 3 - - - - Parked WG Document - 1 - - - - Published RFC - 3 - - - - Published RFC - 4 - - - - Published RFC - 2 - - - - Response to Review Needed - 4 - - - - Sent to a Different Organization for Publication - 2 - - - - Sent to the RFC Editor - 2 - - - - Sent to the RFC Editor - 4 - - - - Sent to the RFC Editor - 3 - - - - Submission Received - 4 - - - - Submitted to IESG for Publication - 1 - - - - Waiting for Document Shepherd - 3 - - - - Waiting for IRTF Chair - 3 - - - - Waiting for WG Chair Go-Ahead - 1 - - - - WG Consensus: Waiting for Write-Up - 1 - - - - WG Document - 1 - - - - Wait for go-ahead - 1 - 18 - - - - - Reach consensus - 1 - 19 - - - - - Adopt - 1 - 12 - - - - - Adopt for WG info only - 1 - 13 - - - - - Develop - 1 - 14 - - - - - Park - 1 - 15 - - - - - Die - 1 - 16 - - - - - Submit to IESG - 1 - 20 - - - - - Raise last call - 1 - 17 - - - - - Revised I-D Needed - 3 - - - - Shepherd Needed - 3 - - - - Waiting for Dependency on Other Document - 3 - - - - Revised I-D Needed - 2 - - - - Document Shepherd Followup - 2 - - - - Editor Needed - 3 - - - - Awaiting Reviews - 2 - - - - Waiting for Partner Feedback - 2 - - - - Other - see Comment Log - 1 - - - - Editor Needed - 2 - - - - Doc Shepherd Follow-Up Underway - 1 - - - - Revised I-D Needed - Issue raised by IESG - 1 - - - - Awaiting Expert Review/Resolution of Issues Raised - 1 - - - - Awaiting External Review/Resolution of Issues Raised - 1 - - - - Awaiting Merge with Other Document - 1 - - - - Author or Editor Needed - 1 - - - - Waiting for Referenced Document - 1 - - - - Revised I-D Needed - Issue raised by AD - 1 - - - - Revised I-D Needed - Issue raised by WGLC - 1 - - - - Waiting for Referencing Document - 1 - - - - IESG Review Completed - 3 - - - - Waiting for Dependency on Other Document - 4 - - - - Awaiting Reviews - 4 - - - - Revised I-D Needed - 4 - - - - IESG Review Completed - 4 - - - - - - - - - - - - - - - - - - IETF - True - idtracker.IETFWG - idtracker.WGChair + group.ietfwg + chairs 1 IAB - False - - + + 2 IRTF - True - idtracker.IRTF - idtracker.IRTFChair + + 3 ISE - False - - + + 4 diff --git a/ietf/ietfworkflows/migrations/0011_remove_group_from_stream.py b/ietf/ietfworkflows/migrations/0011_remove_group_from_stream.py new file mode 100644 index 000000000..5705f7ef8 --- /dev/null +++ b/ietf/ietfworkflows/migrations/0011_remove_group_from_stream.py @@ -0,0 +1,205 @@ + +from south.db import db +from django.db import models +from ietf.ietfworkflows.models import * + +class Migration: + + def forwards(self, orm): + + # Deleting field 'StreamedID.content_type' + db.delete_column('ietfworkflows_streamedid', 'content_type_id') + + # Deleting field 'StreamedID.content_id' + db.delete_column('ietfworkflows_streamedid', 'content_id') + + + + def backwards(self, orm): + + # Adding field 'StreamedID.content_type' + db.add_column('ietfworkflows_streamedid', 'content_type', orm['ietfworkflows.streamedid:content_type']) + + # Adding field 'StreamedID.content_id' + db.add_column('ietfworkflows_streamedid', 'content_id', orm['ietfworkflows.streamedid:content_id']) + + + + models = { + 'contenttypes.contenttype': { + 'Meta': {'unique_together': "(('app_label', 'model'),)", 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'idtracker.acronym': { + 'Meta': {'db_table': "'acronym'"}, + 'acronym': ('django.db.models.fields.CharField', [], {'max_length': '12'}), + 'acronym_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name_key': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'idtracker.idintendedstatus': { + 'Meta': {'db_table': "'id_intended_status'"}, + 'intended_status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), + 'intended_status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'idtracker.idstatus': { + 'Meta': {'db_table': "'id_status'"}, + 'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), + 'status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'idtracker.internetdraft': { + 'Meta': {'db_table': "'internet_drafts'"}, + 'abstract': ('django.db.models.fields.TextField', [], {}), + 'b_approve_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'b_discussion_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'b_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'dunn_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True'}), + 'expired_tombstone': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'extension_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'file_type': ('django.db.models.fields.CharField', [], {'max_length': '20'}), + 'filename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Acronym']", 'db_column': "'group_acronym_id'"}), + 'id_document_key': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'id_document_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'intended_status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDIntendedStatus']"}), + 'last_modified_date': ('django.db.models.fields.DateField', [], {}), + 'lc_changes': ('django.db.models.fields.CharField', [], {'max_length': '3', 'null': 'True'}), + 'lc_expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'lc_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'local_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'replaced_by': ('django.db.models.fields.related.ForeignKey', ["orm['idtracker.InternetDraft']"], {'related_name': "'replaces_set'", 'null': 'True', 'db_column': "'replaced_by'", 'blank': 'True'}), + 'review_by_rfc_editor': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'revision': ('django.db.models.fields.CharField', [], {'max_length': '2'}), + 'revision_date': ('django.db.models.fields.DateField', [], {}), + 'rfc_number': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), + 'shepherd': ('django.db.models.fields.related.ForeignKey', ["orm['idtracker.PersonOrOrgInfo']"], {'null': 'True', 'blank': 'True'}), + 'start_date': ('django.db.models.fields.DateField', [], {}), + 'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDStatus']"}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'id_document_name'"}), + 'txt_page_count': ('django.db.models.fields.IntegerField', [], {}), + 'wgreturn_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}) + }, + 'idtracker.personororginfo': { + 'Meta': {'db_table': "'person_or_org_info'"}, + 'address_type': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), + 'created_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}), + 'date_modified': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), + 'first_name_key': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), + 'last_name_key': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), + 'middle_initial': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), + 'middle_initial_key': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), + 'modified_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), + 'name_prefix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), + 'name_suffix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), + 'person_or_org_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'record_type': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}) + }, + 'ietfworkflows.annotationtag': { + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), + 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'annotation_tags'", 'to': "orm['workflows.Workflow']"}) + }, + 'ietfworkflows.annotationtagobjectrelation': { + 'annotation_tag': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.AnnotationTag']"}), + 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'annotation_tags'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'ietfworkflows.objectannotationtaghistoryentry': { + 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), + 'setted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'unsetted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + 'ietfworkflows.objecthistoryentry': { + 'comment': ('django.db.models.fields.TextField', [], {}), + 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), + 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}) + }, + 'ietfworkflows.objectstreamhistoryentry': { + 'from_stream': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), + 'to_stream': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + 'ietfworkflows.objectworkflowhistoryentry': { + 'from_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), + 'to_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'ietfworkflows.statedescription': { + 'definition': ('django.db.models.fields.TextField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'order': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) + }, + 'ietfworkflows.stateobjectrelationmetadata': { + 'estimated_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'from_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'relation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.StateObjectRelation']"}) + }, + 'ietfworkflows.stream': { + 'group_chair_model': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'group_model': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'with_groups': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.WGWorkflow']"}) + }, + 'ietfworkflows.streamedid': { + 'draft': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['idtracker.InternetDraft']", 'unique': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.Stream']", 'null': 'True', 'blank': 'True'}) + }, + 'ietfworkflows.wgworkflow': { + 'selected_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['workflows.State']", 'null': 'True', 'blank': 'True'}), + 'selected_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['ietfworkflows.AnnotationTag']", 'null': 'True', 'blank': 'True'}), + 'workflow_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['workflows.Workflow']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'permissions.permission': { + 'codename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), + 'content_types': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}) + }, + 'workflows.state': { + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'transitions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['workflows.Transition']", 'null': 'True', 'blank': 'True'}), + 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'states'", 'to': "orm['workflows.Workflow']"}) + }, + 'workflows.stateobjectrelation': { + 'Meta': {'unique_together': "(('content_type', 'content_id', 'state'),)"}, + 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'state_object'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) + }, + 'workflows.transition': { + 'condition': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), + 'destination': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'destination_state'", 'null': 'True', 'to': "orm['workflows.State']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), + 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['workflows.Workflow']"}) + }, + 'workflows.workflow': { + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'initial_state': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_state'", 'null': 'True', 'to': "orm['workflows.State']"}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['permissions.Permission']", 'symmetrical': 'False'}) + } + } + + complete_apps = ['ietfworkflows'] diff --git a/ietf/ietfworkflows/migrations/0012_refactor_stream_group_descrition.py b/ietf/ietfworkflows/migrations/0012_refactor_stream_group_descrition.py new file mode 100644 index 000000000..e5a61fcbd --- /dev/null +++ b/ietf/ietfworkflows/migrations/0012_refactor_stream_group_descrition.py @@ -0,0 +1,222 @@ + +from south.db import db +from django.db import models +from ietf.ietfworkflows.models import * + +class Migration: + + def forwards(self, orm): + + # Adding field 'Stream.group_chair_attribute' + db.add_column('ietfworkflows_stream', 'group_chair_attribute', orm['ietfworkflows.stream:group_chair_attribute']) + + # Adding field 'Stream.document_group_attribute' + db.add_column('ietfworkflows_stream', 'document_group_attribute', orm['ietfworkflows.stream:document_group_attribute']) + + # Deleting field 'Stream.group_chair_model' + db.delete_column('ietfworkflows_stream', 'group_chair_model') + + # Deleting field 'Stream.with_groups' + db.delete_column('ietfworkflows_stream', 'with_groups') + + # Deleting field 'Stream.group_model' + db.delete_column('ietfworkflows_stream', 'group_model') + + + + def backwards(self, orm): + + # Deleting field 'Stream.group_chair_attribute' + db.delete_column('ietfworkflows_stream', 'group_chair_attribute') + + # Deleting field 'Stream.document_group_attribute' + db.delete_column('ietfworkflows_stream', 'document_group_attribute') + + # Adding field 'Stream.group_chair_model' + db.add_column('ietfworkflows_stream', 'group_chair_model', orm['ietfworkflows.stream:group_chair_model']) + + # Adding field 'Stream.with_groups' + db.add_column('ietfworkflows_stream', 'with_groups', orm['ietfworkflows.stream:with_groups']) + + # Adding field 'Stream.group_model' + db.add_column('ietfworkflows_stream', 'group_model', orm['ietfworkflows.stream:group_model']) + + + + models = { + 'contenttypes.contenttype': { + 'Meta': {'unique_together': "(('app_label', 'model'),)", 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'idtracker.acronym': { + 'Meta': {'db_table': "'acronym'"}, + 'acronym': ('django.db.models.fields.CharField', [], {'max_length': '12'}), + 'acronym_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name_key': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'idtracker.idintendedstatus': { + 'Meta': {'db_table': "'id_intended_status'"}, + 'intended_status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), + 'intended_status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'idtracker.idstatus': { + 'Meta': {'db_table': "'id_status'"}, + 'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), + 'status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'idtracker.internetdraft': { + 'Meta': {'db_table': "'internet_drafts'"}, + 'abstract': ('django.db.models.fields.TextField', [], {}), + 'b_approve_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'b_discussion_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'b_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'dunn_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True'}), + 'expired_tombstone': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'extension_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'file_type': ('django.db.models.fields.CharField', [], {'max_length': '20'}), + 'filename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Acronym']", 'db_column': "'group_acronym_id'"}), + 'id_document_key': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'id_document_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'intended_status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDIntendedStatus']"}), + 'last_modified_date': ('django.db.models.fields.DateField', [], {}), + 'lc_changes': ('django.db.models.fields.CharField', [], {'max_length': '3', 'null': 'True'}), + 'lc_expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'lc_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'local_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'replaced_by': ('django.db.models.fields.related.ForeignKey', ["orm['idtracker.InternetDraft']"], {'related_name': "'replaces_set'", 'null': 'True', 'db_column': "'replaced_by'", 'blank': 'True'}), + 'review_by_rfc_editor': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'revision': ('django.db.models.fields.CharField', [], {'max_length': '2'}), + 'revision_date': ('django.db.models.fields.DateField', [], {}), + 'rfc_number': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), + 'shepherd': ('django.db.models.fields.related.ForeignKey', ["orm['idtracker.PersonOrOrgInfo']"], {'null': 'True', 'blank': 'True'}), + 'start_date': ('django.db.models.fields.DateField', [], {}), + 'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDStatus']"}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'id_document_name'"}), + 'txt_page_count': ('django.db.models.fields.IntegerField', [], {}), + 'wgreturn_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}) + }, + 'idtracker.personororginfo': { + 'Meta': {'db_table': "'person_or_org_info'"}, + 'address_type': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), + 'created_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}), + 'date_modified': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), + 'first_name_key': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), + 'last_name_key': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), + 'middle_initial': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), + 'middle_initial_key': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), + 'modified_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), + 'name_prefix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), + 'name_suffix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), + 'person_or_org_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'record_type': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}) + }, + 'ietfworkflows.annotationtag': { + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), + 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'annotation_tags'", 'to': "orm['workflows.Workflow']"}) + }, + 'ietfworkflows.annotationtagobjectrelation': { + 'annotation_tag': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.AnnotationTag']"}), + 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'annotation_tags'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'ietfworkflows.objectannotationtaghistoryentry': { + 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), + 'setted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'unsetted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + 'ietfworkflows.objecthistoryentry': { + 'comment': ('django.db.models.fields.TextField', [], {}), + 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), + 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}) + }, + 'ietfworkflows.objectstreamhistoryentry': { + 'from_stream': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), + 'to_stream': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + 'ietfworkflows.objectworkflowhistoryentry': { + 'from_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), + 'to_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'ietfworkflows.statedescription': { + 'definition': ('django.db.models.fields.TextField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'order': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) + }, + 'ietfworkflows.stateobjectrelationmetadata': { + 'estimated_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'from_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'relation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.StateObjectRelation']"}) + }, + 'ietfworkflows.stream': { + 'document_group_attribute': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'group_chair_attribute': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.WGWorkflow']"}) + }, + 'ietfworkflows.streamedid': { + 'draft': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['idtracker.InternetDraft']", 'unique': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.Stream']", 'null': 'True', 'blank': 'True'}) + }, + 'ietfworkflows.wgworkflow': { + 'selected_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['workflows.State']", 'null': 'True', 'blank': 'True'}), + 'selected_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['ietfworkflows.AnnotationTag']", 'null': 'True', 'blank': 'True'}), + 'workflow_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['workflows.Workflow']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'permissions.permission': { + 'codename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), + 'content_types': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}) + }, + 'workflows.state': { + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'transitions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['workflows.Transition']", 'null': 'True', 'blank': 'True'}), + 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'states'", 'to': "orm['workflows.Workflow']"}) + }, + 'workflows.stateobjectrelation': { + 'Meta': {'unique_together': "(('content_type', 'content_id', 'state'),)"}, + 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'state_object'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) + }, + 'workflows.transition': { + 'condition': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), + 'destination': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'destination_state'", 'null': 'True', 'to': "orm['workflows.State']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), + 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['workflows.Workflow']"}) + }, + 'workflows.workflow': { + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'initial_state': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_state'", 'null': 'True', 'to': "orm['workflows.State']"}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['permissions.Permission']", 'symmetrical': 'False'}) + } + } + + complete_apps = ['ietfworkflows'] diff --git a/ietf/ietfworkflows/models.py b/ietf/ietfworkflows/models.py index b73261975..7f86cc938 100644 --- a/ietf/ietfworkflows/models.py +++ b/ietf/ietfworkflows/models.py @@ -139,19 +139,46 @@ class WGWorkflow(Workflow): class Stream(models.Model): name = models.CharField(_(u"Name"), max_length=100) - with_groups = models.BooleanField(_(u'With groups'), default=False) - group_model = models.CharField(_(u'Group model'), max_length=100, blank=True, null=True) - group_chair_model = models.CharField(_(u'Group chair model'), max_length=100, blank=True, null=True) + document_group_attribute = models.CharField(_(u'Document group attribute'), max_length=255, blank=True, null=True) + group_chair_attribute = models.CharField(_(u'Group chair attribute'), max_length=255, blank=True, null=True) workflow = models.ForeignKey(WGWorkflow) def __unicode__(self): return u'%s stream' % self.name + def get_group_for_document(self, document): + if not self.document_group_attribute: + return None + attr = None + obj = document + for attr_name in self.document_group_attribute.split('.'): + attr = getattr(obj, attr_name, None) + if not attr: + return None + if callable(attr): + attr = attr() + obj = attr + return attr + + def get_chairs_for_document(self, document): + group = self.get_group_for_document(document) + if not group or not self.group_chair_attribute: + return [] + attr = None + obj = group + for attr_name in self.group_chair_attribute.split('.'): + attr = getattr(obj, attr_name, None) + if not attr: + return None + if callable(attr): + attr = attr() + obj = attr + return attr + class StreamedID(models.Model): draft = models.OneToOneField(InternetDraft) stream = models.ForeignKey(Stream, blank=True, null=True) - content_type = models.ForeignKey(ContentType, verbose_name=_(u"Content type"), related_name="streamed_id", blank=True, null=True) - content_id = models.PositiveIntegerField(_(u"Content id"), blank=True, null=True) - group = generic.GenericForeignKey(ct_field="content_type", fk_field="content_id") + def get_group(self): + return self.stream.get_group_for_document(self.draft) From 6d68c732a5bb550e65181e8f4ec0d0177f509bb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20A=2E=20S=C3=A1nchez=20L=C3=B3pez?= Date: Tue, 2 Aug 2011 06:41:02 +0000 Subject: [PATCH 04/10] Retrieve group from the existing one in the drafts. See #694 - Legacy-Id: 3274 --- ietf/ietfworkflows/accounts.py | 6 +-- ietf/ietfworkflows/streams.py | 50 +------------------ ietf/ietfworkflows/utils.py | 7 +-- ietf/templates/idrfc/doc_main_id.html | 2 +- ietf/templates/idrfc/doc_tab_document_id.html | 4 +- 5 files changed, 11 insertions(+), 58 deletions(-) diff --git a/ietf/ietfworkflows/accounts.py b/ietf/ietfworkflows/accounts.py index 13f82f713..db7828f64 100644 --- a/ietf/ietfworkflows/accounts.py +++ b/ietf/ietfworkflows/accounts.py @@ -29,10 +29,10 @@ def is_chair_of_draft(user, draft): streamed = get_streamed_draft(draft) if not streamed or not streamed.stream: return False - group = streamed.group - if not group or not hasattr(group, 'chairs'): + chairs = streamed.stream.get_chairs_for_document(draft) + if not chairs: return False - return bool(group.chairs().filter(person=person).count()) + return bool(chairs.filter(person=person).count()) def can_edit_state(user, draft): diff --git a/ietf/ietfworkflows/streams.py b/ietf/ietfworkflows/streams.py index a1ee4ec72..17f43d925 100644 --- a/ietf/ietfworkflows/streams.py +++ b/ietf/ietfworkflows/streams.py @@ -34,60 +34,12 @@ def get_stream_from_id(stream_id): return None -def get_chair_model(stream): - model_str = stream.group_chair_model - if not model_str: - return None - try: - app, model = model_str.split('.', 1) - except ValueError: - return None - chair_model = models.get_model(app, model) - if not chair_model: - return - return chair_model - - -def _get_group_from_acronym(group_model_str, acronym): - try: - app, model = group_model_str.split('.', 1) - except ValueError: - return None - group_model = models.get_model(app, model) - if not group_model: - return - if 'acronym' in group_model._meta.get_all_field_names(): - try: - return group_model._default_manager.get(acronym=acronym) - except group_model.DoesNotExist: - return None - elif 'group_acronym' in group_model._meta.get_all_field_names(): - try: - return group_model._default_manager.get(group_acronym__acronym=acronym) - except group_model.DoesNotExist: - return None - else: - return None - - def _set_stream_automatically(draft, stream): (streamed, created) = StreamedID.objects.get_or_create(draft=draft) if created: streamed.stream = stream streamed.save() - else: - return - if not stream or not stream.with_groups: - return - try: - draft_literal, stream_name, group_name, extra = draft.filename.split('-', 3) - if stream_name.lower() == stream.name.lower(): - group = _get_group_from_acronym(stream.group_model, group_name) - if group: - streamed.group = group - streamed.save() - except ValueError: - return + return def get_stream_from_wrapper(idrfc_wrapper): diff --git a/ietf/ietfworkflows/utils.py b/ietf/ietfworkflows/utils.py index d9f27d39f..ba6979023 100644 --- a/ietf/ietfworkflows/utils.py +++ b/ietf/ietfworkflows/utils.py @@ -87,11 +87,12 @@ def get_workflow_for_draft(draft): if not streamed_draft or not streamed_draft.stream: return None stream = streamed_draft.stream - if stream.with_groups: - if not streamed_draft.group: + if stream.document_group_attribute: + group = streamed_draft.get_group() + if not group: return None else: - workflow = get_workflow_for_wg(streamed_draft.group, streamed_draft.stream.workflow) + workflow = get_workflow_for_wg(group, streamed_draft.stream.workflow) else: workflow = stream.workflow set_workflow_for_object(draft, workflow) diff --git a/ietf/templates/idrfc/doc_main_id.html b/ietf/templates/idrfc/doc_main_id.html index 1d44e26f5..e42801b25 100644 --- a/ietf/templates/idrfc/doc_main_id.html +++ b/ietf/templates/idrfc/doc_main_id.html @@ -47,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. {% with doc.replaces as r %}{% if r %}
Replaces {% filter urlize_ietf_docs %}{{ r|join:", "}}{% endfilter %}{% endif %}{% endwith %} Last updated: {{ doc.publication_date|default:"(data missing)" }} -IETF WG status:{{ stream_info.state.name }} ({{ stream_info.streamed.group }}) +IETF WG status:{{ stream_info.state.name }} ({{ stream_info.streamed.get_group }}) {% if stream_info.tags %}
{% for tag in stream_info.tags %}{{ tag.name }}{% if not forloop.last %}, {% endif %}{% endfor %}{% endif %} Intended RFC status:{% if doc.in_ietf_process %}{{ doc.ietf_process.intended_maturity_level|default:"-" }}{% else %}-{%endif%} diff --git a/ietf/templates/idrfc/doc_tab_document_id.html b/ietf/templates/idrfc/doc_tab_document_id.html index 81c5d67c6..513cff0ff 100644 --- a/ietf/templates/idrfc/doc_tab_document_id.html +++ b/ietf/templates/idrfc/doc_tab_document_id.html @@ -44,11 +44,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. {% with doc.replaces as r %}{% if r %}
Replaces {% filter urlize_ietf_docs %}{{ r|join:", "}}{% endfilter %}{% endif %}{% endwith %} Last updated: {{ doc.publication_date|default:"(data missing)" }} -{% ifequal stream_info.stream.name "IETF" %}IETF WG status:{{ stream_info.state.name }} ({{ stream_info.streamed.group }}) +{% ifequal stream_info.stream.name "IETF" %}IETF WG status:{{ stream_info.state.name }} ({{ stream_info.streamed.get_group }}) {% if stream_info.tags %}
{% for tag in stream_info.tags %}{{ tag.name }}{% if not forloop.last %}, {% endif %}{% endfor %}{% endif %} {% else %} -{% if stream_info.stream %}{{ stream_info.stream.name }} status:{{ stream_info.state.name }} {% if stream_info.streamed.group %}({{ stream_info.streamed.group }}) {% endif %} +{% if stream_info.stream %}{{ stream_info.stream.name }} status:{{ stream_info.state.name }} {% if stream_info.streamed.get_group %}({{ stream_info.streamed.get_group }}) {% endif %} {% if stream_info.tags %}
{% for tag in stream_info.tags %}{{ tag.name }}{% if not forloop.last %}, {% endif %}{% endfor %}{% endif %} {% endif %} {% endifequal %} From 5af808b6ddaf4bb2f3d3ff5356f9773daef6f876 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20A=2E=20S=C3=A1nchez=20L=C3=B3pez?= Date: Tue, 2 Aug 2011 09:38:03 +0000 Subject: [PATCH 05/10] Retrieve IRTF group and chairs (including the IRTF chair). Fixes #694 - Legacy-Id: 3275 --- ietf/ietfworkflows/accounts.py | 7 ++++++- ietf/ietfworkflows/models.py | 25 ++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/ietf/ietfworkflows/accounts.py b/ietf/ietfworkflows/accounts.py index db7828f64..292130ef5 100644 --- a/ietf/ietfworkflows/accounts.py +++ b/ietf/ietfworkflows/accounts.py @@ -1,3 +1,5 @@ +from django.db.models.query import QuerySet + from ietf.ietfworkflows.streams import get_streamed_draft @@ -32,7 +34,10 @@ def is_chair_of_draft(user, draft): chairs = streamed.stream.get_chairs_for_document(draft) if not chairs: return False - return bool(chairs.filter(person=person).count()) + if isinstance(chairs, QuerySet): + return bool(chairs.filter(person=person).count()) + else: + return person in chairs def can_edit_state(user, draft): diff --git a/ietf/ietfworkflows/models.py b/ietf/ietfworkflows/models.py index 7f86cc938..cd8f34f06 100644 --- a/ietf/ietfworkflows/models.py +++ b/ietf/ietfworkflows/models.py @@ -3,7 +3,7 @@ from django.contrib.contenttypes.models import ContentType from django.db import models from django.utils.translation import ugettext_lazy as _ -from ietf.idtracker.models import PersonOrOrgInfo, InternetDraft +from ietf.idtracker.models import PersonOrOrgInfo, InternetDraft, Role, IRTF from workflows.models import Workflow, State, StateObjectRelation from permissions.models import Permission @@ -146,7 +146,27 @@ class Stream(models.Model): def __unicode__(self): return u'%s stream' % self.name + def _irtf_group(self, document): + filename = document.filename.split('-') + if len(filename) > 2 and filename[0] == 'draft' and filename[1] =='irtf': + try: + return IRTF.objects.get(acronym=filename[2]) + except IRTF.DoesNotExist: + return None + return None + + def _irtf_chairs(self, document): + group = self._irtf_group(document) + if not group: + return [] + chairs = [i.person for i in group.chairs()] + chairs.append(Role.objects.get(pk=Role.IRTF_CHAIR).person) + return chairs + def get_group_for_document(self, document): + if hasattr(self, '_%s_group' % self.name.lower()): + return getattr(self, '_%s_group' % self.name.lower())(document) + if not self.document_group_attribute: return None attr = None @@ -161,6 +181,9 @@ class Stream(models.Model): return attr def get_chairs_for_document(self, document): + if hasattr(self, '_%s_chairs' % self.name.lower()): + return getattr(self, '_%s_chairs' % self.name.lower())(document) + group = self.get_group_for_document(document) if not group or not self.group_chair_attribute: return [] From 322caf332cb041edc5b889326c67ddde4fbd8329 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20A=2E=20S=C3=A1nchez=20L=C3=B3pez?= Date: Thu, 11 Aug 2011 12:11:07 +0000 Subject: [PATCH 06/10] Add stream delegate model. See #699 - Legacy-Id: 3299 --- .../migrations/0013_add_stream_delegates.py | 208 ++++++++++++++++++ ietf/ietfworkflows/models.py | 51 ++++- 2 files changed, 256 insertions(+), 3 deletions(-) create mode 100644 ietf/ietfworkflows/migrations/0013_add_stream_delegates.py diff --git a/ietf/ietfworkflows/migrations/0013_add_stream_delegates.py b/ietf/ietfworkflows/migrations/0013_add_stream_delegates.py new file mode 100644 index 000000000..2647539a7 --- /dev/null +++ b/ietf/ietfworkflows/migrations/0013_add_stream_delegates.py @@ -0,0 +1,208 @@ + +from south.db import db +from django.db import models +from ietf.ietfworkflows.models import * + +class Migration: + + def forwards(self, orm): + + # Adding model 'StreamDelegate' + db.create_table('ietfworkflows_streamdelegate', ( + ('id', orm['ietfworkflows.streamdelegate:id']), + ('stream', orm['ietfworkflows.streamdelegate:stream']), + ('person', orm['ietfworkflows.streamdelegate:person']), + )) + db.send_create_signal('ietfworkflows', ['StreamDelegate']) + + + + def backwards(self, orm): + + # Deleting model 'StreamDelegate' + db.delete_table('ietfworkflows_streamdelegate') + + + + models = { + 'contenttypes.contenttype': { + 'Meta': {'unique_together': "(('app_label', 'model'),)", 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'idtracker.acronym': { + 'Meta': {'db_table': "'acronym'"}, + 'acronym': ('django.db.models.fields.CharField', [], {'max_length': '12'}), + 'acronym_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name_key': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'idtracker.idintendedstatus': { + 'Meta': {'db_table': "'id_intended_status'"}, + 'intended_status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), + 'intended_status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'idtracker.idstatus': { + 'Meta': {'db_table': "'id_status'"}, + 'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), + 'status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'idtracker.internetdraft': { + 'Meta': {'db_table': "'internet_drafts'"}, + 'abstract': ('django.db.models.fields.TextField', [], {}), + 'b_approve_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'b_discussion_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'b_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'dunn_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True'}), + 'expired_tombstone': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'extension_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'file_type': ('django.db.models.fields.CharField', [], {'max_length': '20'}), + 'filename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Acronym']", 'db_column': "'group_acronym_id'"}), + 'id_document_key': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'id_document_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'intended_status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDIntendedStatus']"}), + 'last_modified_date': ('django.db.models.fields.DateField', [], {}), + 'lc_changes': ('django.db.models.fields.CharField', [], {'max_length': '3', 'null': 'True'}), + 'lc_expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'lc_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'local_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'replaced_by': ('django.db.models.fields.related.ForeignKey', ["orm['idtracker.InternetDraft']"], {'related_name': "'replaces_set'", 'null': 'True', 'db_column': "'replaced_by'", 'blank': 'True'}), + 'review_by_rfc_editor': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'revision': ('django.db.models.fields.CharField', [], {'max_length': '2'}), + 'revision_date': ('django.db.models.fields.DateField', [], {}), + 'rfc_number': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), + 'shepherd': ('django.db.models.fields.related.ForeignKey', ["orm['idtracker.PersonOrOrgInfo']"], {'null': 'True', 'blank': 'True'}), + 'start_date': ('django.db.models.fields.DateField', [], {}), + 'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDStatus']"}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'id_document_name'"}), + 'txt_page_count': ('django.db.models.fields.IntegerField', [], {}), + 'wgreturn_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}) + }, + 'idtracker.personororginfo': { + 'Meta': {'db_table': "'person_or_org_info'"}, + 'address_type': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), + 'created_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}), + 'date_modified': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), + 'first_name_key': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), + 'last_name_key': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), + 'middle_initial': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), + 'middle_initial_key': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), + 'modified_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), + 'name_prefix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), + 'name_suffix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), + 'person_or_org_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'record_type': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}) + }, + 'ietfworkflows.annotationtag': { + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), + 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'annotation_tags'", 'to': "orm['workflows.Workflow']"}) + }, + 'ietfworkflows.annotationtagobjectrelation': { + 'annotation_tag': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.AnnotationTag']"}), + 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'annotation_tags'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'ietfworkflows.objectannotationtaghistoryentry': { + 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), + 'setted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'unsetted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + 'ietfworkflows.objecthistoryentry': { + 'comment': ('django.db.models.fields.TextField', [], {}), + 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), + 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}) + }, + 'ietfworkflows.objectstreamhistoryentry': { + 'from_stream': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), + 'to_stream': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + 'ietfworkflows.objectworkflowhistoryentry': { + 'from_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), + 'to_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'ietfworkflows.statedescription': { + 'definition': ('django.db.models.fields.TextField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'order': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) + }, + 'ietfworkflows.stateobjectrelationmetadata': { + 'estimated_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'from_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'relation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.StateObjectRelation']"}) + }, + 'ietfworkflows.stream': { + 'document_group_attribute': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'group_chair_attribute': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.WGWorkflow']"}) + }, + 'ietfworkflows.streamdelegate': { + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}), + 'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.Stream']"}) + }, + 'ietfworkflows.streamedid': { + 'draft': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['idtracker.InternetDraft']", 'unique': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.Stream']", 'null': 'True', 'blank': 'True'}) + }, + 'ietfworkflows.wgworkflow': { + 'selected_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['workflows.State']", 'null': 'True', 'blank': 'True'}), + 'selected_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['ietfworkflows.AnnotationTag']", 'null': 'True', 'blank': 'True'}), + 'workflow_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['workflows.Workflow']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'permissions.permission': { + 'codename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), + 'content_types': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}) + }, + 'workflows.state': { + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'transitions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['workflows.Transition']", 'null': 'True', 'blank': 'True'}), + 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'states'", 'to': "orm['workflows.Workflow']"}) + }, + 'workflows.stateobjectrelation': { + 'Meta': {'unique_together': "(('content_type', 'content_id', 'state'),)"}, + 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'state_object'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) + }, + 'workflows.transition': { + 'condition': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), + 'destination': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'destination_state'", 'null': 'True', 'to': "orm['workflows.State']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), + 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['workflows.Workflow']"}) + }, + 'workflows.workflow': { + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'initial_state': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_state'", 'null': 'True', 'to': "orm['workflows.State']"}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['permissions.Permission']", 'symmetrical': 'False'}) + } + } + + complete_apps = ['ietfworkflows'] diff --git a/ietf/ietfworkflows/models.py b/ietf/ietfworkflows/models.py index cd8f34f06..86de40566 100644 --- a/ietf/ietfworkflows/models.py +++ b/ietf/ietfworkflows/models.py @@ -155,7 +155,7 @@ class Stream(models.Model): return None return None - def _irtf_chairs(self, document): + def _irtf_chairs_for_document(self, document): group = self._irtf_group(document) if not group: return [] @@ -163,6 +163,13 @@ class Stream(models.Model): chairs.append(Role.objects.get(pk=Role.IRTF_CHAIR).person) return chairs + + def _ietf_delegates_for_document(self, document): + group = self.get_group_for_document(document) + if not group: + return False + return [i.person for i in group.wgdelegate_set.all()] + def get_group_for_document(self, document): if hasattr(self, '_%s_group' % self.name.lower()): return getattr(self, '_%s_group' % self.name.lower())(document) @@ -181,8 +188,8 @@ class Stream(models.Model): return attr def get_chairs_for_document(self, document): - if hasattr(self, '_%s_chairs' % self.name.lower()): - return getattr(self, '_%s_chairs' % self.name.lower())(document) + if hasattr(self, '_%s_chairs_for_document' % self.name.lower()): + return getattr(self, '_%s_chairs_for_document' % self.name.lower())(document) group = self.get_group_for_document(document) if not group or not self.group_chair_attribute: @@ -198,6 +205,39 @@ class Stream(models.Model): obj = attr return attr + def get_delegates_for_document(self, document): + delegates = [] + if hasattr(self, '_%s_delegates_for_document' % self.name.lower()): + delegates = getattr(self, '_%s_delegates_for_document' % self.name.lower())(document) + delegates += [i.person for i in self.streamdelegate_set.all()] + return delegates + + def get_chairs(self): + chairs = [] + if hasattr(self, '_%s_stream_chairs' % self.name.lower()): + chairs += list(getattr(self, '_%s_stream_chairs' % self.name.lower())(person)) + + role_key = getattr(Role, '%s_CHAIR' % self.name.upper(), None) + if role_key: + try: + chairs.append(Role.objects.get(pk=role_key).person) + except Role.DoesNotExist: + pass + return list(set(chairs)) + + def get_delegates(self): + delegates = [] + if hasattr(self, '_%s_stream_delegates' % self.name.lower()): + delegates += list(getattr(self, '_%s_stream_delegates' % self.name.lower())(person)) + delegates += [i.person for i in StreamDelegate.objects.filter(stream=self)] + return list(set(delegates)) + + def check_chair(self, person): + return person in self.get_chairs() + + def check_delegate(self, person): + return person in self.get_delegates() + class StreamedID(models.Model): draft = models.OneToOneField(InternetDraft) @@ -205,3 +245,8 @@ class StreamedID(models.Model): def get_group(self): return self.stream.get_group_for_document(self.draft) + + +class StreamDelegate(models.Model): + stream = models.ForeignKey(Stream) + person = models.ForeignKey(PersonOrOrgInfo) From b28469f117c90e6b95315d590370c13728f8734f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20A=2E=20S=C3=A1nchez=20L=C3=B3pez?= Date: Thu, 11 Aug 2011 12:18:59 +0000 Subject: [PATCH 07/10] View to design/remove delegates into an stream. Fixes #699 - Legacy-Id: 3300 --- ietf/ietfworkflows/accounts.py | 40 +++++++++++++----- ietf/ietfworkflows/forms.py | 29 ++++++++++++- ietf/ietfworkflows/models.py | 9 ++-- .../templatetags/ietf_streams.py | 35 +++++++++++++++- ietf/ietfworkflows/urls.py | 1 + ietf/ietfworkflows/views.py | 33 ++++++++++++++- ietf/templates/base_leftmenu.html | 9 +++- .../ietfworkflows/stream_delegates.html | 41 +++++++++++++++++++ 8 files changed, 175 insertions(+), 22 deletions(-) create mode 100644 ietf/templates/ietfworkflows/stream_delegates.html diff --git a/ietf/ietfworkflows/accounts.py b/ietf/ietfworkflows/accounts.py index 292130ef5..702de62b6 100644 --- a/ietf/ietfworkflows/accounts.py +++ b/ietf/ietfworkflows/accounts.py @@ -1,5 +1,3 @@ -from django.db.models.query import QuerySet - from ietf.ietfworkflows.streams import get_streamed_draft @@ -24,20 +22,42 @@ def is_wgdelegate(person): return bool(person.wgdelegate_set.all()) -def is_chair_of_draft(user, draft): +def is_delegate_of_stream(user, stream): + if is_secretariat(user): + return True + person = get_person_for_user(user) + return stream.check_delegate(person) + + +def is_chair_of_stream(user, stream): + if is_secretariat(user): + return True + person = get_person_for_user(user) + return stream.check_chair(person) + + +def is_authorized_in_draft_stream(user, draft): + if is_secretariat(user): + return True person = get_person_for_user(user) if not person: return False streamed = get_streamed_draft(draft) if not streamed or not streamed.stream: return False + # Check if the person is chair of the stream + if is_chair_of_stream(user, streamed.stream): + return True + # Check if the person is delegate of the stream + if is_delegate_of_stream(user, streamed.stream): + return True + # Check if the person is chair of the related group chairs = streamed.stream.get_chairs_for_document(draft) - if not chairs: - return False - if isinstance(chairs, QuerySet): - return bool(chairs.filter(person=person).count()) - else: - return person in chairs + if chairs and person in chairs: + return True + # Check if the person is authorized by a delegate system + delegates = streamed.stream.get_delegates_for_document(draft) + return bool(person in delegates) def can_edit_state(user, draft): @@ -50,7 +70,7 @@ def can_edit_state(user, draft): is_wgchair(person) or is_wgdelegate(person)) return (is_secretariat(user) or - is_chair_of_draft(user, draft)) + is_authorized_in_draft_stream(user, draft)) def can_edit_stream(user, draft): diff --git a/ietf/ietfworkflows/forms.py b/ietf/ietfworkflows/forms.py index 379e09343..175585bb0 100644 --- a/ietf/ietfworkflows/forms.py +++ b/ietf/ietfworkflows/forms.py @@ -8,7 +8,7 @@ from workflows.utils import set_workflow_for_object from ietf.idtracker.models import PersonOrOrgInfo, IETFWG from ietf.wgchairs.accounts import get_person_for_user -from ietf.ietfworkflows.models import Stream +from ietf.ietfworkflows.models import Stream, StreamDelegate from ietf.ietfworkflows.utils import (get_workflow_for_draft, get_workflow_for_wg, get_state_for_draft, get_state_by_name, update_state, FOLLOWUP_TAG, @@ -62,7 +62,7 @@ class NoWorkflowStateForm(StreamDraftForm): wgs = set([i.group_acronym for i in self.person.wgchair_set.all()]).union(set([i.wg for i in self.person.wgdelegate_set.all()])) if len(wgs) > 1: self.wgs = list(wgs) - self.wgs.sort(lambda x,y: cmp(x.group_acronym.acronym, y.group_acronym.acronym)) + self.wgs.sort(lambda x, y: cmp(x.group_acronym.acronym, y.group_acronym.acronym)) self.fields['wg'].choices = [(i.pk, '%s - %s' % (i.group_acronym.acronym, i.group_acronym.name)) for i in self.wgs] else: self.onlywg = list(wgs)[0].group_acronym @@ -200,3 +200,28 @@ class DraftStreamForm(StreamDraftForm): comment=comment, person=self.person, to_stream=to_stream) + + +class StreamDelegatesForm(forms.Form): + email = forms.EmailField() + + def __init__(self, *args, **kwargs): + self.stream = kwargs.pop('stream') + super(StreamDelegatesForm, self).__init__(*args, **kwargs) + + def get_person(self, email): + persons = PersonOrOrgInfo.objects.filter(emailaddress__address=email).distinct() + if not persons: + return None + return persons[0] + + def clean_email(self): + email = self.cleaned_data.get('email') + self.person = self.get_person(email) + if not self.person: + raise forms.ValidationError('There is no user with this email in the system') + + def save(self): + StreamDelegate.objects.get_or_create( + person=self.person, + stream=self.stream) diff --git a/ietf/ietfworkflows/models.py b/ietf/ietfworkflows/models.py index 86de40566..74bb3c7d4 100644 --- a/ietf/ietfworkflows/models.py +++ b/ietf/ietfworkflows/models.py @@ -148,7 +148,7 @@ class Stream(models.Model): def _irtf_group(self, document): filename = document.filename.split('-') - if len(filename) > 2 and filename[0] == 'draft' and filename[1] =='irtf': + if len(filename) > 2 and filename[0] == 'draft' and filename[1] == 'irtf': try: return IRTF.objects.get(acronym=filename[2]) except IRTF.DoesNotExist: @@ -163,7 +163,6 @@ class Stream(models.Model): chairs.append(Role.objects.get(pk=Role.IRTF_CHAIR).person) return chairs - def _ietf_delegates_for_document(self, document): group = self.get_group_for_document(document) if not group: @@ -215,8 +214,8 @@ class Stream(models.Model): def get_chairs(self): chairs = [] if hasattr(self, '_%s_stream_chairs' % self.name.lower()): - chairs += list(getattr(self, '_%s_stream_chairs' % self.name.lower())(person)) - + chairs += list(getattr(self, '_%s_stream_chairs' % self.name.lower())()) + role_key = getattr(Role, '%s_CHAIR' % self.name.upper(), None) if role_key: try: @@ -228,7 +227,7 @@ class Stream(models.Model): def get_delegates(self): delegates = [] if hasattr(self, '_%s_stream_delegates' % self.name.lower()): - delegates += list(getattr(self, '_%s_stream_delegates' % self.name.lower())(person)) + delegates += list(getattr(self, '_%s_stream_delegates' % self.name.lower())()) delegates += [i.person for i in StreamDelegate.objects.filter(stream=self)] return list(set(delegates)) diff --git a/ietf/ietfworkflows/templatetags/ietf_streams.py b/ietf/ietfworkflows/templatetags/ietf_streams.py index 7e88cf0f2..a13427031 100644 --- a/ietf/ietfworkflows/templatetags/ietf_streams.py +++ b/ietf/ietfworkflows/templatetags/ietf_streams.py @@ -6,7 +6,9 @@ from ietf.ietfworkflows.utils import (get_workflow_for_draft, from ietf.wgchairs.accounts import (can_manage_shepherd_of_a_document, can_manage_writeup_of_a_document) from ietf.ietfworkflows.streams import get_stream_from_wrapper -from ietf.ietfworkflows.accounts import (can_edit_state, can_edit_stream) +from ietf.ietfworkflows.models import Stream +from ietf.ietfworkflows.accounts import (can_edit_state, can_edit_stream, + is_chair_of_stream) register = template.Library() @@ -14,7 +16,6 @@ register = template.Library() @register.inclusion_tag('ietfworkflows/stream_state.html', takes_context=True) def stream_state(context, doc): - request = context.get('request', None) data = {} stream = get_stream_from_wrapper(doc) data.update({'stream': stream}) @@ -72,3 +73,33 @@ def edit_actions(context, wrapper): 'draft': draft, 'doc': wrapper, } + + +class StreamListNode(template.Node): + + def __init__(self, user, var_name): + self.user = user + self.var_name = var_name + + def render(self, context): + user = self.user.resolve(context) + streams = [] + for i in Stream.objects.all(): + if is_chair_of_stream(user, i): + streams.append(i) + context.update({self.var_name: streams}) + return '' + + +@register.tag +def get_user_managed_streams(parser, token): + firstbits = token.contents.split(None, 2) + if len(firstbits) != 3: + raise template.TemplateSyntaxError("'get_user_managed_streams' tag takes three arguments") + user = parser.compile_filter(firstbits[1]) + lastbits_reversed = firstbits[2][::-1].split(None, 2) + if lastbits_reversed[1][::-1] != 'as': + raise template.TemplateSyntaxError("next-to-last argument to 'get_user_managed_stream' tag must" + " be 'as'") + var_name = lastbits_reversed[0][::-1] + return StreamListNode(user, var_name) diff --git a/ietf/ietfworkflows/urls.py b/ietf/ietfworkflows/urls.py index 4583bff7d..b18805e3e 100644 --- a/ietf/ietfworkflows/urls.py +++ b/ietf/ietfworkflows/urls.py @@ -6,4 +6,5 @@ urlpatterns = patterns('ietf.ietfworkflows.views', url(r'^(?P[^/]+)/history/$', 'stream_history', name='stream_history'), url(r'^(?P[^/]+)/edit/state/$', 'edit_state', name='edit_state'), url(r'^(?P[^/]+)/edit/stream/$', 'edit_stream', name='edit_stream'), + url(r'^delegates/(?P[^/]+)/$', 'stream_delegates', name='stream_delegates'), ) diff --git a/ietf/ietfworkflows/views.py b/ietf/ietfworkflows/views.py index 4b4ee3b92..97fcf5877 100644 --- a/ietf/ietfworkflows/views.py +++ b/ietf/ietfworkflows/views.py @@ -3,16 +3,19 @@ from django.shortcuts import get_object_or_404, render_to_response from django.template import RequestContext from ietf.idtracker.models import InternetDraft +from ietf.ietfworkflows.models import Stream, StreamDelegate from ietf.ietfworkflows.forms import (DraftTagsStateForm, DraftStreamForm, - NoWorkflowStateForm) + NoWorkflowStateForm, + StreamDelegatesForm) from ietf.ietfworkflows.streams import (get_stream_from_draft, get_streamed_draft) from ietf.ietfworkflows.utils import (get_workflow_history_for_draft, get_workflow_for_draft, get_annotation_tags_for_draft, get_state_for_draft) -from ietf.ietfworkflows.accounts import (can_edit_state, can_edit_stream) +from ietf.ietfworkflows.accounts import (can_edit_state, can_edit_stream, + is_chair_of_stream) REDUCED_HISTORY_LEN = 20 @@ -81,8 +84,34 @@ def edit_state(request, name): return HttpResponseForbidden('You have no permission to access this view') return _edit_draft_stream(request, draft, DraftTagsStateForm) + def edit_stream(request, name): draft = get_object_or_404(InternetDraft, filename=name) if not can_edit_stream(request.user, draft): return HttpResponseForbidden('You have no permission to access this view') return _edit_draft_stream(request, draft, DraftStreamForm) + + +def stream_delegates(request, stream_name): + stream = get_object_or_404(Stream, name=stream_name) + if not is_chair_of_stream(request.user, stream): + return HttpResponseForbidden('You have no permission to access this view') + chairs = stream.get_chairs() + form = StreamDelegatesForm(stream=stream) + if request.method == 'POST': + if request.POST.get('delete', False): + pk_list = request.POST.getlist('remove_delegate') + StreamDelegate.objects.filter(stream=stream, person__pk__in=pk_list).delete() + else: + form = StreamDelegatesForm(request.POST, stream=stream) + if form.is_valid(): + form.save() + form = StreamDelegatesForm(stream=stream) + delegates = stream.get_delegates() + return render_to_response('ietfworkflows/stream_delegates.html', + {'stream': stream, + 'chairs': chairs, + 'delegates': delegates, + 'form': form, + }, + context_instance=RequestContext(request)) diff --git a/ietf/templates/base_leftmenu.html b/ietf/templates/base_leftmenu.html index ca7ef7f4e..5a9cb3bba 100644 --- a/ietf/templates/base_leftmenu.html +++ b/ietf/templates/base_leftmenu.html @@ -33,7 +33,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. {% endcomment %} {% load wg_menu %} -{% load ietf_filters %} +{% load ietf_filters ietf_streams %}
    {% if user|in_group:"Area_Director" %}
  • AD Dashboard
  • @@ -47,6 +47,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  • Telechat Dates
  • Working Groups
  • {% endif %} +{% get_user_managed_streams user as stream_list %} +{% if stream_list %} +
  • Streams
  • + {% for stream in stream_list %} + {{ stream.name }} stream + {% endfor %} +{% endif %}
  • Working Groups
  • diff --git a/ietf/templates/ietfworkflows/stream_delegates.html b/ietf/templates/ietfworkflows/stream_delegates.html new file mode 100644 index 000000000..0bf175b94 --- /dev/null +++ b/ietf/templates/ietfworkflows/stream_delegates.html @@ -0,0 +1,41 @@ +{% extends "base.html" %} +{% load ietf_streams ietf_filters %} + +{% block content %} +

    Stream: {{ stream.name }}

    + +{% if chairs %} +

    {{ stream.name }} stream chairs

    + + +{% for chair in chairs %} + +{% endfor %} +
    NameEmail
    {{ chair }}{{ chair.email.0 }} <{{ chair.email.1 }}>
    +{% endif %} + +

    {{ stream.name }} stream delegates

    +
    +{% if delegates %} + + +{% for delegate in delegates %} + +{% endfor %} +
    NameEmail
    {{ delegate }}{{ delegate.email.0 }} <{{ delegate.email.1 }}>
    +

    + +

    +{% else %} +

    +No delegates for {{ stream.name }} stream asigned. +

    +{% endif %} +

    +Enter a valid e-mail address to add a new delegate. +

    +{% if form.errors.email %}{{ form.errors.email }}{% endif %} +{{ form.email }} + +
    +{% endblock %} From 40afa5fb06e50adb403981a0082a1546a71fe0db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20A=2E=20S=C3=A1nchez=20L=C3=B3pez?= Date: Mon, 22 Aug 2011 06:34:55 +0000 Subject: [PATCH 08/10] Remove uneeded states. Fixes #704 - Legacy-Id: 3346 --- .../0014_change_alt_streams_states.py | 234 ++++++++++++++++++ 1 file changed, 234 insertions(+) create mode 100644 ietf/ietfworkflows/migrations/0014_change_alt_streams_states.py diff --git a/ietf/ietfworkflows/migrations/0014_change_alt_streams_states.py b/ietf/ietfworkflows/migrations/0014_change_alt_streams_states.py new file mode 100644 index 000000000..a6ef0232e --- /dev/null +++ b/ietf/ietfworkflows/migrations/0014_change_alt_streams_states.py @@ -0,0 +1,234 @@ + +from south.db import db +from django.db import models +from ietf.ietfworkflows.models import * + +class Migration: + + no_dry_run = True + + def forwards(self, orm): + # Remove all 'Published RFC' status + for state in orm['workflows.state'].objects.filter(name='Published RFC'): + state.delete() + + + def backwards(self, orm): + "Write your backwards migration here" + + + models = { + 'contenttypes.contenttype': { + 'Meta': {'unique_together': "(('app_label', 'model'),)", 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'idtracker.acronym': { + 'Meta': {'db_table': "'acronym'"}, + 'acronym': ('django.db.models.fields.CharField', [], {'max_length': '12'}), + 'acronym_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name_key': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'idtracker.idintendedstatus': { + 'Meta': {'db_table': "'id_intended_status'"}, + 'intended_status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), + 'intended_status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'idtracker.idstatus': { + 'Meta': {'db_table': "'id_status'"}, + 'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"}), + 'status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'idtracker.internetdraft': { + 'Meta': {'db_table': "'internet_drafts'"}, + 'abstract': ('django.db.models.fields.TextField', [], {}), + 'b_approve_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'b_discussion_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'b_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'dunn_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True'}), + 'expired_tombstone': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'extension_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'file_type': ('django.db.models.fields.CharField', [], {'max_length': '20'}), + 'filename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Acronym']", 'db_column': "'group_acronym_id'"}), + 'id_document_key': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'id_document_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'intended_status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDIntendedStatus']"}), + 'last_modified_date': ('django.db.models.fields.DateField', [], {}), + 'lc_changes': ('django.db.models.fields.CharField', [], {'max_length': '3', 'null': 'True'}), + 'lc_expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'lc_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'local_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'replaced_by': ('django.db.models.fields.related.ForeignKey', ["orm['idtracker.InternetDraft']"], {'related_name': "'replaces_set'", 'null': 'True', 'db_column': "'replaced_by'", 'blank': 'True'}), + 'review_by_rfc_editor': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'revision': ('django.db.models.fields.CharField', [], {'max_length': '2'}), + 'revision_date': ('django.db.models.fields.DateField', [], {}), + 'rfc_number': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), + 'shepherd': ('django.db.models.fields.related.ForeignKey', ["orm['idtracker.PersonOrOrgInfo']"], {'null': 'True', 'blank': 'True'}), + 'start_date': ('django.db.models.fields.DateField', [], {}), + 'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDStatus']"}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'id_document_name'"}), + 'txt_page_count': ('django.db.models.fields.IntegerField', [], {}), + 'wgreturn_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}) + }, + 'idtracker.personororginfo': { + 'Meta': {'db_table': "'person_or_org_info'"}, + 'address_type': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), + 'created_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}), + 'date_modified': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), + 'first_name_key': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), + 'last_name_key': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), + 'middle_initial': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), + 'middle_initial_key': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), + 'modified_by': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}), + 'name_prefix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), + 'name_suffix': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), + 'person_or_org_tag': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'record_type': ('django.db.models.fields.CharField', [], {'max_length': '8', 'null': 'True', 'blank': 'True'}) + }, + 'ietfworkflows.annotationtag': { + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), + 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'annotation_tags'", 'to': "orm['workflows.Workflow']"}) + }, + 'ietfworkflows.annotationtagobjectrelation': { + 'annotation_tag': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.AnnotationTag']"}), + 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'annotation_tags'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'ietfworkflows.objectannotationtaghistoryentry': { + 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), + 'setted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'unsetted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + 'ietfworkflows.objecthistoryentry': { + 'comment': ('django.db.models.fields.TextField', [], {}), + 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), + 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}) + }, + 'ietfworkflows.objectstreamhistoryentry': { + 'from_stream': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), + 'to_stream': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + 'ietfworkflows.objectworkflowhistoryentry': { + 'from_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'objecthistoryentry_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ietfworkflows.ObjectHistoryEntry']", 'unique': 'True', 'primary_key': 'True'}), + 'to_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'ietfworkflows.statedescription': { + 'definition': ('django.db.models.fields.TextField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'order': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) + }, + 'ietfworkflows.stateobjectrelationmetadata': { + 'estimated_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'from_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'relation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.StateObjectRelation']"}) + }, + 'ietfworkflows.stream': { + 'document_group_attribute': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'group_chair_attribute': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.WGWorkflow']"}) + }, + 'ietfworkflows.streamdelegate': { + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}), + 'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.Stream']"}) + }, + 'ietfworkflows.streamedid': { + 'draft': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['idtracker.InternetDraft']", 'unique': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ietfworkflows.Stream']", 'null': 'True', 'blank': 'True'}) + }, + 'ietfworkflows.wgworkflow': { + 'selected_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['workflows.State']", 'null': 'True', 'blank': 'True'}), + 'selected_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['ietfworkflows.AnnotationTag']", 'null': 'True', 'blank': 'True'}), + 'workflow_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['workflows.Workflow']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'permissions.permission': { + 'codename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), + 'content_types': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}) + }, + 'permissions.role': { + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}) + }, + 'workflows.state': { + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'transitions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['workflows.Transition']", 'null': 'True', 'blank': 'True'}), + 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'states'", 'to': "orm['workflows.Workflow']"}) + }, + 'workflows.stateinheritanceblock': { + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']"}), + 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) + }, + 'workflows.stateobjectrelation': { + 'Meta': {'unique_together': "(('content_type', 'content_id', 'state'),)"}, + 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'state_object'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) + }, + 'workflows.statepermissionrelation': { + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']"}), + 'role': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Role']"}), + 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}) + }, + 'workflows.transition': { + 'condition': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), + 'destination': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'destination_state'", 'null': 'True', 'to': "orm['workflows.State']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']", 'null': 'True', 'blank': 'True'}), + 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['workflows.Workflow']"}) + }, + 'workflows.workflow': { + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'initial_state': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_state'", 'null': 'True', 'to': "orm['workflows.State']"}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['permissions.Permission']", 'symmetrical': 'False'}) + }, + 'workflows.workflowmodelrelation': { + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']", 'unique': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'wmrs'", 'to': "orm['workflows.Workflow']"}) + }, + 'workflows.workflowobjectrelation': { + 'Meta': {'unique_together': "(('content_type', 'content_id'),)"}, + 'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_object'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'wors'", 'to': "orm['workflows.Workflow']"}) + }, + 'workflows.workflowpermissionrelation': { + 'Meta': {'unique_together': "(('workflow', 'permission'),)"}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'permission': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'permissions'", 'to': "orm['permissions.Permission']"}), + 'workflow': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.Workflow']"}) + } + } + + complete_apps = ['ietfworkflows', 'workflows'] From 6485555bf1b3ca92d23c83b928632ff3c7c46e5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20A=2E=20S=C3=A1nchez=20L=C3=B3pez?= Date: Thu, 22 Sep 2011 10:01:19 +0000 Subject: [PATCH 09/10] Update the subject and body of the IESG email. Fixes #709 - Legacy-Id: 3437 --- ietf/templates/idrfc/approval_mail_rfc_editor.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ietf/templates/idrfc/approval_mail_rfc_editor.txt b/ietf/templates/idrfc/approval_mail_rfc_editor.txt index fd10f8f48..543f458dd 100644 --- a/ietf/templates/idrfc/approval_mail_rfc_editor.txt +++ b/ietf/templates/idrfc/approval_mail_rfc_editor.txt @@ -1,8 +1,10 @@ {% autoescape off %}From: The IESG To: RFC Editor Cc: The IESG , , -Subject: Re: {{ status }} to be: {{ doc.file_tag }} -{% filter wordwrap:73 %}{% if disapproved %} +Subject: Results of IETF-conflict review for {{ doc.file_tag }} +{% filter wordwrap:73 %} +The IESG has completed a review of consistent with RFC5742. This review is applied to all non-IETF streams. +{% if disapproved %} The IESG recommends that '{{ doc.title }}' {{ doc.file_tag|safe }} NOT be published as {{ full_status }}. {% else %} The IESG has no problem with the publication of '{{ doc.title }}' {{ doc.file_tag|safe }} as {{ full_status }}. From cfe6afce9403288d3bae4d4497a9f3c8a85d96eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20A=2E=20S=C3=A1nchez=20L=C3=B3pez?= Date: Wed, 19 Oct 2011 09:22:56 +0000 Subject: [PATCH 10/10] Check for an ISE Role. Fix #711 - Legacy-Id: 3448 --- ietf/ietfworkflows/models.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ietf/ietfworkflows/models.py b/ietf/ietfworkflows/models.py index 74bb3c7d4..f5c9d7b40 100644 --- a/ietf/ietfworkflows/models.py +++ b/ietf/ietfworkflows/models.py @@ -211,6 +211,14 @@ class Stream(models.Model): delegates += [i.person for i in self.streamdelegate_set.all()] return delegates + def _ise_stream_chairs(self): + chairs = [] + try: + chairs.append(Role.objects.get(role_name='ISE').person) + except Role.DoesNotExist: + pass + return chairs + def get_chairs(self): chairs = [] if hasattr(self, '_%s_stream_chairs' % self.name.lower()):