Merged in branch branch/yaco/wgchairs from esanchez@yaco.es. This provides the WG Chair Tracker functionality.
- Legacy-Id: 3120
This commit is contained in:
commit
a142e89a87
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -15,3 +15,6 @@
|
|||
.*.swp
|
||||
.DS_store
|
||||
# Simulated Subversion default ignores end here
|
||||
/.project
|
||||
/.pydevproject
|
||||
/.settings
|
||||
|
|
2
ietf/.gitignore
vendored
2
ietf/.gitignore
vendored
|
@ -1 +1,3 @@
|
|||
/*.pyc
|
||||
/settings_local.py
|
||||
/ietfdb.sql.gz
|
||||
|
|
|
@ -49,6 +49,7 @@ from ietf.idtracker.templatetags.ietf_filters import format_textarea, fill
|
|||
from ietf.idrfc import markup_txt
|
||||
from ietf.idrfc.models import RfcIndex, DraftVersions
|
||||
from ietf.idrfc.idrfc_wrapper import BallotWrapper, IdWrapper, RfcWrapper
|
||||
from ietf.ietfworkflows.utils import get_full_info_for_draft
|
||||
|
||||
def document_debug(request, name):
|
||||
r = re.compile("^rfc([1-9][0-9]*)$")
|
||||
|
@ -123,25 +124,6 @@ def document_main(request, name, tab):
|
|||
doc = IdWrapper(id)
|
||||
|
||||
info = {}
|
||||
stream_id = doc.stream_id()
|
||||
if stream_id == 2:
|
||||
stream = " (IAB document)"
|
||||
elif stream_id == 3:
|
||||
stream = " (IRTF document)"
|
||||
elif stream_id == 4:
|
||||
stream = " (Independent submission via RFC Editor)"
|
||||
elif doc.group_acronym():
|
||||
stream = " ("+doc.group_acronym().upper()+" WG document)"
|
||||
else:
|
||||
stream = " (Individual document)"
|
||||
|
||||
if id.status.status == "Active":
|
||||
info['is_active_draft'] = True
|
||||
info['type'] = "Active Internet-Draft"+stream
|
||||
else:
|
||||
info['is_active_draft'] = False
|
||||
info['type'] = "Old Internet-Draft"+stream
|
||||
|
||||
info['has_pdf'] = (".pdf" in doc.file_types())
|
||||
info['is_rfc'] = False
|
||||
|
||||
|
@ -159,6 +141,7 @@ def document_main(request, name, tab):
|
|||
{'content1':content1, 'content2':content2,
|
||||
'doc':doc, 'info':info, 'tab':tab,
|
||||
'include_text':include_text(request),
|
||||
'stream_info': get_full_info_for_draft(id),
|
||||
'versions':versions, 'history':history},
|
||||
context_instance=RequestContext(request));
|
||||
|
||||
|
|
|
@ -380,5 +380,3 @@ def add_comment(request, name):
|
|||
dict(doc=doc,
|
||||
form=form),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
||||
|
|
437
ietf/idtracker/migrations/0002_shepherd.py
Normal file
437
ietf/idtracker/migrations/0002_shepherd.py
Normal file
|
@ -0,0 +1,437 @@
|
|||
|
||||
from south.db import db
|
||||
from django.db import models
|
||||
from ietf.idtracker.models import *
|
||||
|
||||
class Migration:
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Adding field 'InternetDraft.shepherd'
|
||||
db.add_column('internet_drafts', 'shepherd', orm['idtracker.internetdraft:shepherd'])
|
||||
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Deleting field 'InternetDraft.shepherd'
|
||||
db.delete_column('internet_drafts', 'shepherd_id')
|
||||
|
||||
|
||||
|
||||
models = {
|
||||
'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.area': {
|
||||
'Meta': {'db_table': "'areas'"},
|
||||
'area_acronym': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['idtracker.Acronym']", 'unique': 'True', 'primary_key': 'True'}),
|
||||
'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'concluded_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'extra_email_addresses': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'last_modified_date': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'blank': 'True'}),
|
||||
'start_date': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.AreaStatus']"})
|
||||
},
|
||||
'idtracker.areadirector': {
|
||||
'Meta': {'db_table': "'area_directors'"},
|
||||
'area': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Area']", 'null': 'True', 'db_column': "'area_acronym_id'"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"})
|
||||
},
|
||||
'idtracker.areagroup': {
|
||||
'Meta': {'db_table': "'area_group'"},
|
||||
'area': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'areagroup'", 'db_column': "'area_acronym_id'", 'to': "orm['idtracker.Area']"}),
|
||||
'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IETFWG']", 'unique': 'True', 'db_column': "'group_acronym_id'"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||
},
|
||||
'idtracker.areastatus': {
|
||||
'Meta': {'db_table': "'area_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.areawgurl': {
|
||||
'Meta': {'db_table': "'wg_www_pages'"},
|
||||
'description': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True', 'db_column': "'area_ID'"}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_column': "'area_Name'"}),
|
||||
'url': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
'idtracker.ballotinfo': {
|
||||
'Meta': {'db_table': "'ballot_info'"},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
|
||||
'an_sent': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
|
||||
'an_sent_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ansent'", 'null': 'True', 'db_column': "'an_sent_by'", 'to': "orm['idtracker.IESGLogin']"}),
|
||||
'an_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'approval_text': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'ballot': ('django.db.models.fields.AutoField', [], {'primary_key': 'True', 'db_column': "'ballot_id'"}),
|
||||
'ballot_issued': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'ballot_writeup': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'defer': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
|
||||
'defer_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'deferred'", 'null': 'True', 'db_column': "'defer_by'", 'to': "orm['idtracker.IESGLogin']"}),
|
||||
'defer_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'last_call_text': ('django.db.models.fields.TextField', [], {'blank': 'True'})
|
||||
},
|
||||
'idtracker.chairshistory': {
|
||||
'Meta': {'db_table': "'chairs_history'"},
|
||||
'chair_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Role']"}),
|
||||
'end_year': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}),
|
||||
'present_chair': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
|
||||
'start_year': ('django.db.models.fields.IntegerField', [], {})
|
||||
},
|
||||
'idtracker.documentcomment': {
|
||||
'Meta': {'db_table': "'document_comments'"},
|
||||
'ballot': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
|
||||
'comment_text': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'created_by': ('BrokenForeignKey', ["orm['idtracker.IESGLogin']"], {'null': 'True', 'db_column': "'created_by'", 'null_values': '(0,999)'}),
|
||||
'date': ('django.db.models.fields.DateField', [], {'default': 'datetime.date.today', 'db_column': "'comment_date'"}),
|
||||
'document': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDInternal']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'origin_state': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments_coming_from_state'", 'null': 'True', 'db_column': "'origin_state'", 'to': "orm['idtracker.IDState']"}),
|
||||
'public_flag': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
|
||||
'result_state': ('BrokenForeignKey', ["orm['idtracker.IDState']"], {'related_name': '"comments_leading_to_state"', 'null': 'True', 'db_column': "'result_state'", 'null_values': '(0,99)'}),
|
||||
'rfc_flag': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'time': ('django.db.models.fields.CharField', [], {'default': "'05:10:39'", 'max_length': '20', 'db_column': "'comment_time'"}),
|
||||
'version': ('django.db.models.fields.CharField', [], {'max_length': '3', 'blank': 'True'})
|
||||
},
|
||||
'idtracker.emailaddress': {
|
||||
'Meta': {'db_table': "'email_addresses'"},
|
||||
'address': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'email_address'"}),
|
||||
'comment': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_column': "'email_comment'", 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person_or_org': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}),
|
||||
'priority': ('django.db.models.fields.IntegerField', [], {'db_column': "'email_priority'"}),
|
||||
'type': ('django.db.models.fields.CharField', [], {'max_length': '4', 'db_column': "'email_type'"})
|
||||
},
|
||||
'idtracker.goalmilestone': {
|
||||
'Meta': {'db_table': "'goals_milestones'"},
|
||||
'description': ('django.db.models.fields.TextField', [], {}),
|
||||
'done': ('django.db.models.fields.CharField', [], {'max_length': '4', 'blank': 'True'}),
|
||||
'done_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'expected_due_date': ('django.db.models.fields.DateField', [], {}),
|
||||
'gm_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'group_acronym': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IETFWG']"}),
|
||||
'last_modified_date': ('django.db.models.fields.DateField', [], {})
|
||||
},
|
||||
'idtracker.idauthor': {
|
||||
'Meta': {'db_table': "'id_authors'"},
|
||||
'author_order': ('django.db.models.fields.IntegerField', [], {}),
|
||||
'document': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'authors'", 'db_column': "'id_document_tag'", 'to': "orm['idtracker.InternetDraft']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"})
|
||||
},
|
||||
'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.idinternal': {
|
||||
'Meta': {'db_table': "'id_internal'"},
|
||||
'agenda': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'approved_in_minute': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'area_acronym': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Area']"}),
|
||||
'assigned_to': ('django.db.models.fields.CharField', [], {'max_length': '25', 'blank': 'True'}),
|
||||
'ballot': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'drafts'", 'db_column': "'ballot_id'", 'to': "orm['idtracker.BallotInfo']"}),
|
||||
'cur_state': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'docs'", 'db_column': "'cur_state'", 'to': "orm['idtracker.IDState']"}),
|
||||
'cur_sub_state': ('BrokenForeignKey', ["orm['idtracker.IDSubState']"], {'related_name': "'docs'", 'null': 'True', 'null_values': '(0,-1)', 'blank': 'True'}),
|
||||
'dnp': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'dnp_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'draft': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.InternetDraft']", 'unique': 'True', 'primary_key': 'True', 'db_column': "'id_document_tag'"}),
|
||||
'email_display': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
|
||||
'event_date': ('django.db.models.fields.DateField', [], {'null': 'True'}),
|
||||
'group_flag': ('django.db.models.fields.IntegerField', [], {'default': '0', 'blank': 'True'}),
|
||||
'job_owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'documents'", 'db_column': "'job_owner'", 'to': "orm['idtracker.IESGLogin']"}),
|
||||
'mark_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'marked'", 'db_column': "'mark_by'", 'to': "orm['idtracker.IESGLogin']"}),
|
||||
'noproblem': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'note': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'prev_state': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'docs_prev'", 'db_column': "'prev_state'", 'to': "orm['idtracker.IDState']"}),
|
||||
'prev_sub_state': ('BrokenForeignKey', ["orm['idtracker.IDSubState']"], {'related_name': "'docs_prev'", 'null': 'True', 'null_values': '(0,-1)', 'blank': 'True'}),
|
||||
'primary_flag': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'resurrect_requested_by': ('BrokenForeignKey', ["orm['idtracker.IESGLogin']"], {'related_name': "'docsresurrected'", 'null': 'True', 'db_column': "'resurrect_requested_by'", 'blank': 'True'}),
|
||||
'returning_item': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'rfc_flag': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
|
||||
'state_change_notice_to': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||
'status_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'telechat_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'token_email': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||
'token_name': ('django.db.models.fields.CharField', [], {'max_length': '25', 'blank': 'True'}),
|
||||
'via_rfc_editor': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
'idtracker.idnextstate': {
|
||||
'Meta': {'db_table': "'ref_next_states_new'"},
|
||||
'condition': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||
'cur_state': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'nextstate'", 'to': "orm['idtracker.IDState']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'next_state': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'prevstate'", 'to': "orm['idtracker.IDState']"})
|
||||
},
|
||||
'idtracker.idstate': {
|
||||
'Meta': {'db_table': "'ref_doc_states_new'"},
|
||||
'description': ('django.db.models.fields.TextField', [], {'db_column': "'document_desc'", 'blank': 'True'}),
|
||||
'document_state_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'equiv_group_flag': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'state': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_column': "'document_state_val'"})
|
||||
},
|
||||
'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.idsubstate': {
|
||||
'Meta': {'db_table': "'sub_state'"},
|
||||
'description': ('django.db.models.fields.TextField', [], {'db_column': "'sub_state_desc'", 'blank': 'True'}),
|
||||
'sub_state': ('django.db.models.fields.CharField', [], {'max_length': '55', 'db_column': "'sub_state_val'"}),
|
||||
'sub_state_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||
},
|
||||
'idtracker.iesgcomment': {
|
||||
'Meta': {'unique_together': "(('ballot', 'ad'),)", 'db_table': "'ballots_comment'"},
|
||||
'active': ('django.db.models.fields.IntegerField', [], {}),
|
||||
'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IESGLogin']"}),
|
||||
'ballot': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments'", 'to': "orm['idtracker.BallotInfo']"}),
|
||||
'date': ('django.db.models.fields.DateField', [], {'db_column': "'comment_date'"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'revision': ('django.db.models.fields.CharField', [], {'max_length': '2'}),
|
||||
'text': ('django.db.models.fields.TextField', [], {'db_column': "'comment_text'", 'blank': 'True'})
|
||||
},
|
||||
'idtracker.iesgdiscuss': {
|
||||
'Meta': {'unique_together': "(('ballot', 'ad'),)", 'db_table': "'ballots_discuss'"},
|
||||
'active': ('django.db.models.fields.IntegerField', [], {}),
|
||||
'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IESGLogin']"}),
|
||||
'ballot': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'discusses'", 'to': "orm['idtracker.BallotInfo']"}),
|
||||
'date': ('django.db.models.fields.DateField', [], {'db_column': "'discuss_date'"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'revision': ('django.db.models.fields.CharField', [], {'max_length': '2'}),
|
||||
'text': ('django.db.models.fields.TextField', [], {'db_column': "'discuss_text'", 'blank': 'True'})
|
||||
},
|
||||
'idtracker.iesglogin': {
|
||||
'Meta': {'db_table': "'iesg_login'"},
|
||||
'default_search': ('django.db.models.fields.NullBooleanField', [], {'null': 'True'}),
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '25', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '25', 'blank': 'True'}),
|
||||
'login_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||
'password': ('django.db.models.fields.CharField', [], {'max_length': '25'}),
|
||||
'person': ('BrokenForeignKey', ["orm['idtracker.PersonOrOrgInfo']"], {'unique': 'True', 'null': 'True', 'db_column': "'person_or_org_tag'", 'null_values': '(0,888888)'}),
|
||||
'pgp_id': ('django.db.models.fields.CharField', [], {'max_length': '20', 'null': 'True', 'blank': 'True'}),
|
||||
'user_level': ('django.db.models.fields.IntegerField', [], {})
|
||||
},
|
||||
'idtracker.ietfwg': {
|
||||
'Meta': {'db_table': "'groups_ietf'"},
|
||||
'area_director': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.AreaDirector']", 'null': 'True'}),
|
||||
'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'concluded_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'dormant_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'email_address': ('django.db.models.fields.CharField', [], {'max_length': '60', 'blank': 'True'}),
|
||||
'email_archive': ('django.db.models.fields.CharField', [], {'max_length': '95', 'blank': 'True'}),
|
||||
'email_keyword': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
|
||||
'email_subscribe': ('django.db.models.fields.CharField', [], {'max_length': '120', 'blank': 'True'}),
|
||||
'group_acronym': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['idtracker.Acronym']", 'unique': 'True', 'primary_key': 'True'}),
|
||||
'group_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.WGType']"}),
|
||||
'last_modified_date': ('django.db.models.fields.DateField', [], {}),
|
||||
'meeting_scheduled': ('django.db.models.fields.CharField', [], {'max_length': '3', 'blank': 'True'}),
|
||||
'meeting_scheduled_old': ('django.db.models.fields.CharField', [], {'max_length': '3', 'blank': 'True'}),
|
||||
'proposed_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.WGStatus']"})
|
||||
},
|
||||
'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': ('BrokenForeignKey', ["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', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}),
|
||||
'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.irtf': {
|
||||
'Meta': {'db_table': "'irtf'"},
|
||||
'acronym': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'irtf_acronym'", 'blank': 'True'}),
|
||||
'charter_text': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'irtf_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'meeting_scheduled': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'irtf_name'", 'blank': 'True'})
|
||||
},
|
||||
'idtracker.irtfchair': {
|
||||
'Meta': {'db_table': "'irtf_chairs'"},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'irtf': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IRTF']"}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"})
|
||||
},
|
||||
'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'})
|
||||
},
|
||||
'idtracker.phonenumber': {
|
||||
'Meta': {'db_table': "'phone_numbers'"},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person_or_org': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}),
|
||||
'phone_comment': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||
'phone_number': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||
'phone_priority': ('django.db.models.fields.IntegerField', [], {}),
|
||||
'phone_type': ('django.db.models.fields.CharField', [], {'max_length': '3'})
|
||||
},
|
||||
'idtracker.position': {
|
||||
'Meta': {'unique_together': "(('ballot', 'ad'),)", 'db_table': "'ballots'"},
|
||||
'abstain': ('django.db.models.fields.IntegerField', [], {}),
|
||||
'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IESGLogin']"}),
|
||||
'approve': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'ballot': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'positions'", 'to': "orm['idtracker.BallotInfo']"}),
|
||||
'discuss': ('django.db.models.fields.IntegerField', [], {}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'noobj': ('django.db.models.fields.IntegerField', [], {'db_column': "'no_col'"}),
|
||||
'recuse': ('django.db.models.fields.IntegerField', [], {}),
|
||||
'yes': ('django.db.models.fields.IntegerField', [], {'db_column': "'yes_col'"})
|
||||
},
|
||||
'idtracker.postaladdress': {
|
||||
'Meta': {'db_table': "'postal_addresses'"},
|
||||
'address_priority': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
|
||||
'address_type': ('django.db.models.fields.CharField', [], {'max_length': '4'}),
|
||||
'aff_company_key': ('django.db.models.fields.CharField', [], {'max_length': '70', 'blank': 'True'}),
|
||||
'affiliated_company': ('django.db.models.fields.CharField', [], {'max_length': '70', 'blank': 'True'}),
|
||||
'city': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}),
|
||||
'country': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}),
|
||||
'department': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'mail_stop': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}),
|
||||
'person_or_org': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}),
|
||||
'person_title': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
|
||||
'postal_code': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}),
|
||||
'staddr1': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
|
||||
'staddr2': ('django.db.models.fields.CharField', [], {'max_length': '40', 'blank': 'True'}),
|
||||
'state_or_prov': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'})
|
||||
},
|
||||
'idtracker.rfc': {
|
||||
'Meta': {'db_table': "'rfcs'"},
|
||||
'area_acronym': ('django.db.models.fields.CharField', [], {'max_length': '8', 'blank': 'True'}),
|
||||
'b_approve_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', [], {'blank': 'True'}),
|
||||
'draft_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'fyi_number': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}),
|
||||
'group_acronym': ('django.db.models.fields.CharField', [], {'max_length': '8', 'blank': 'True'}),
|
||||
'historic_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'intended_status': ('django.db.models.fields.related.ForeignKey', [], {'default': '5', 'to': "orm['idtracker.RfcIntendedStatus']", 'db_column': "'intended_status_id'"}),
|
||||
'last_modified_date': ('django.db.models.fields.DateField', [], {}),
|
||||
'lc_expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'lc_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'online_version': ('django.db.models.fields.CharField', [], {'default': "'YES'", 'max_length': '3'}),
|
||||
'proposed_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'rfc_name_key': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
|
||||
'rfc_number': ('django.db.models.fields.IntegerField', [], {'primary_key': 'True'}),
|
||||
'rfc_published_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'standard_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.RfcStatus']", 'db_column': "'status_id'"}),
|
||||
'std_number': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'db_column': "'rfc_name'"}),
|
||||
'txt_page_count': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
'idtracker.rfcauthor': {
|
||||
'Meta': {'db_table': "'rfc_authors'"},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}),
|
||||
'rfc': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'authors'", 'db_column': "'rfc_number'", 'to': "orm['idtracker.Rfc']"})
|
||||
},
|
||||
'idtracker.rfcintendedstatus': {
|
||||
'Meta': {'db_table': "'rfc_intend_status'"},
|
||||
'intended_status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"})
|
||||
},
|
||||
'idtracker.rfcobsolete': {
|
||||
'Meta': {'db_table': "'rfcs_obsolete'"},
|
||||
'action': ('django.db.models.fields.CharField', [], {'max_length': '20'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'rfc': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'updates_or_obsoletes'", 'db_column': "'rfc_number'", 'to': "orm['idtracker.Rfc']"}),
|
||||
'rfc_acted_on': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'updated_or_obsoleted_by'", 'db_column': "'rfc_acted_on'", 'to': "orm['idtracker.Rfc']"})
|
||||
},
|
||||
'idtracker.rfcstatus': {
|
||||
'Meta': {'db_table': "'rfc_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.role': {
|
||||
'Meta': {'db_table': "'chairs'"},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}),
|
||||
'role_name': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'chair_name'"})
|
||||
},
|
||||
'idtracker.wgchair': {
|
||||
'Meta': {'db_table': "'g_chairs'"},
|
||||
'group_acronym': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IETFWG']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"})
|
||||
},
|
||||
'idtracker.wgeditor': {
|
||||
'Meta': {'db_table': "'g_editors'"},
|
||||
'group_acronym': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IETFWG']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'unique': 'True', 'db_column': "'person_or_org_tag'"})
|
||||
},
|
||||
'idtracker.wgsecretary': {
|
||||
'Meta': {'db_table': "'g_secretaries'"},
|
||||
'group_acronym': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IETFWG']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"})
|
||||
},
|
||||
'idtracker.wgstatus': {
|
||||
'Meta': {'db_table': "'g_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.wgtechadvisor': {
|
||||
'Meta': {'db_table': "'g_tech_advisors'"},
|
||||
'group_acronym': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IETFWG']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"})
|
||||
},
|
||||
'idtracker.wgtype': {
|
||||
'Meta': {'db_table': "'g_type'"},
|
||||
'group_type_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'type': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'group_type'"})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['idtracker']
|
|
@ -0,0 +1,439 @@
|
|||
|
||||
from south.db import db
|
||||
from django.db import models
|
||||
from ietf.idtracker.models import *
|
||||
|
||||
class Migration:
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Changing field 'InternetDraft.shepherd'
|
||||
# (to signature: django.db.models.fields.related.ForeignKey(to=orm['idtracker.PersonOrOrgInfo'], null=True, blank=True))
|
||||
db.alter_column('internet_drafts', 'shepherd_id', orm['idtracker.internetdraft:shepherd'])
|
||||
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Changing field 'InternetDraft.shepherd'
|
||||
# (to signature: django.db.models.fields.related.ForeignKey(to=orm['idtracker.PersonOrOrgInfo']))
|
||||
db.alter_column('internet_drafts', 'shepherd_id', orm['idtracker.internetdraft:shepherd'])
|
||||
|
||||
|
||||
|
||||
models = {
|
||||
'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.area': {
|
||||
'Meta': {'db_table': "'areas'"},
|
||||
'area_acronym': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['idtracker.Acronym']", 'unique': 'True', 'primary_key': 'True'}),
|
||||
'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'concluded_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'extra_email_addresses': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'last_modified_date': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'blank': 'True'}),
|
||||
'start_date': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.AreaStatus']"})
|
||||
},
|
||||
'idtracker.areadirector': {
|
||||
'Meta': {'db_table': "'area_directors'"},
|
||||
'area': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Area']", 'null': 'True', 'db_column': "'area_acronym_id'"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"})
|
||||
},
|
||||
'idtracker.areagroup': {
|
||||
'Meta': {'db_table': "'area_group'"},
|
||||
'area': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'areagroup'", 'db_column': "'area_acronym_id'", 'to': "orm['idtracker.Area']"}),
|
||||
'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IETFWG']", 'unique': 'True', 'db_column': "'group_acronym_id'"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||
},
|
||||
'idtracker.areastatus': {
|
||||
'Meta': {'db_table': "'area_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.areawgurl': {
|
||||
'Meta': {'db_table': "'wg_www_pages'"},
|
||||
'description': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True', 'db_column': "'area_ID'"}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_column': "'area_Name'"}),
|
||||
'url': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
'idtracker.ballotinfo': {
|
||||
'Meta': {'db_table': "'ballot_info'"},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
|
||||
'an_sent': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
|
||||
'an_sent_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ansent'", 'null': 'True', 'db_column': "'an_sent_by'", 'to': "orm['idtracker.IESGLogin']"}),
|
||||
'an_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'approval_text': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'ballot': ('django.db.models.fields.AutoField', [], {'primary_key': 'True', 'db_column': "'ballot_id'"}),
|
||||
'ballot_issued': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'ballot_writeup': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'defer': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
|
||||
'defer_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'deferred'", 'null': 'True', 'db_column': "'defer_by'", 'to': "orm['idtracker.IESGLogin']"}),
|
||||
'defer_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'last_call_text': ('django.db.models.fields.TextField', [], {'blank': 'True'})
|
||||
},
|
||||
'idtracker.chairshistory': {
|
||||
'Meta': {'db_table': "'chairs_history'"},
|
||||
'chair_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Role']"}),
|
||||
'end_year': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}),
|
||||
'present_chair': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
|
||||
'start_year': ('django.db.models.fields.IntegerField', [], {})
|
||||
},
|
||||
'idtracker.documentcomment': {
|
||||
'Meta': {'db_table': "'document_comments'"},
|
||||
'ballot': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
|
||||
'comment_text': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'created_by': ('BrokenForeignKey', ["orm['idtracker.IESGLogin']"], {'null': 'True', 'db_column': "'created_by'", 'null_values': '(0,999)'}),
|
||||
'date': ('django.db.models.fields.DateField', [], {'default': 'datetime.date.today', 'db_column': "'comment_date'"}),
|
||||
'document': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IDInternal']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'origin_state': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments_coming_from_state'", 'null': 'True', 'db_column': "'origin_state'", 'to': "orm['idtracker.IDState']"}),
|
||||
'public_flag': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
|
||||
'result_state': ('BrokenForeignKey', ["orm['idtracker.IDState']"], {'related_name': '"comments_leading_to_state"', 'null': 'True', 'db_column': "'result_state'", 'null_values': '(0,99)'}),
|
||||
'rfc_flag': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'time': ('django.db.models.fields.CharField', [], {'default': "'08:36:20'", 'max_length': '20', 'db_column': "'comment_time'"}),
|
||||
'version': ('django.db.models.fields.CharField', [], {'max_length': '3', 'blank': 'True'})
|
||||
},
|
||||
'idtracker.emailaddress': {
|
||||
'Meta': {'db_table': "'email_addresses'"},
|
||||
'address': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'email_address'"}),
|
||||
'comment': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_column': "'email_comment'", 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person_or_org': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}),
|
||||
'priority': ('django.db.models.fields.IntegerField', [], {'db_column': "'email_priority'"}),
|
||||
'type': ('django.db.models.fields.CharField', [], {'max_length': '4', 'db_column': "'email_type'"})
|
||||
},
|
||||
'idtracker.goalmilestone': {
|
||||
'Meta': {'db_table': "'goals_milestones'"},
|
||||
'description': ('django.db.models.fields.TextField', [], {}),
|
||||
'done': ('django.db.models.fields.CharField', [], {'max_length': '4', 'blank': 'True'}),
|
||||
'done_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'expected_due_date': ('django.db.models.fields.DateField', [], {}),
|
||||
'gm_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'group_acronym': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IETFWG']"}),
|
||||
'last_modified_date': ('django.db.models.fields.DateField', [], {})
|
||||
},
|
||||
'idtracker.idauthor': {
|
||||
'Meta': {'db_table': "'id_authors'"},
|
||||
'author_order': ('django.db.models.fields.IntegerField', [], {}),
|
||||
'document': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'authors'", 'db_column': "'id_document_tag'", 'to': "orm['idtracker.InternetDraft']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"})
|
||||
},
|
||||
'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.idinternal': {
|
||||
'Meta': {'db_table': "'id_internal'"},
|
||||
'agenda': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'approved_in_minute': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'area_acronym': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Area']"}),
|
||||
'assigned_to': ('django.db.models.fields.CharField', [], {'max_length': '25', 'blank': 'True'}),
|
||||
'ballot': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'drafts'", 'db_column': "'ballot_id'", 'to': "orm['idtracker.BallotInfo']"}),
|
||||
'cur_state': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'docs'", 'db_column': "'cur_state'", 'to': "orm['idtracker.IDState']"}),
|
||||
'cur_sub_state': ('BrokenForeignKey', ["orm['idtracker.IDSubState']"], {'related_name': "'docs'", 'null': 'True', 'null_values': '(0,-1)', 'blank': 'True'}),
|
||||
'dnp': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'dnp_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'draft': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.InternetDraft']", 'unique': 'True', 'primary_key': 'True', 'db_column': "'id_document_tag'"}),
|
||||
'email_display': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
|
||||
'event_date': ('django.db.models.fields.DateField', [], {'null': 'True'}),
|
||||
'group_flag': ('django.db.models.fields.IntegerField', [], {'default': '0', 'blank': 'True'}),
|
||||
'job_owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'documents'", 'db_column': "'job_owner'", 'to': "orm['idtracker.IESGLogin']"}),
|
||||
'mark_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'marked'", 'db_column': "'mark_by'", 'to': "orm['idtracker.IESGLogin']"}),
|
||||
'noproblem': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'note': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'prev_state': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'docs_prev'", 'db_column': "'prev_state'", 'to': "orm['idtracker.IDState']"}),
|
||||
'prev_sub_state': ('BrokenForeignKey', ["orm['idtracker.IDSubState']"], {'related_name': "'docs_prev'", 'null': 'True', 'null_values': '(0,-1)', 'blank': 'True'}),
|
||||
'primary_flag': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'resurrect_requested_by': ('BrokenForeignKey', ["orm['idtracker.IESGLogin']"], {'related_name': "'docsresurrected'", 'null': 'True', 'db_column': "'resurrect_requested_by'", 'blank': 'True'}),
|
||||
'returning_item': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'rfc_flag': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
|
||||
'state_change_notice_to': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||
'status_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'telechat_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'token_email': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||
'token_name': ('django.db.models.fields.CharField', [], {'max_length': '25', 'blank': 'True'}),
|
||||
'via_rfc_editor': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
'idtracker.idnextstate': {
|
||||
'Meta': {'db_table': "'ref_next_states_new'"},
|
||||
'condition': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||
'cur_state': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'nextstate'", 'to': "orm['idtracker.IDState']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'next_state': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'prevstate'", 'to': "orm['idtracker.IDState']"})
|
||||
},
|
||||
'idtracker.idstate': {
|
||||
'Meta': {'db_table': "'ref_doc_states_new'"},
|
||||
'description': ('django.db.models.fields.TextField', [], {'db_column': "'document_desc'", 'blank': 'True'}),
|
||||
'document_state_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'equiv_group_flag': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'state': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_column': "'document_state_val'"})
|
||||
},
|
||||
'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.idsubstate': {
|
||||
'Meta': {'db_table': "'sub_state'"},
|
||||
'description': ('django.db.models.fields.TextField', [], {'db_column': "'sub_state_desc'", 'blank': 'True'}),
|
||||
'sub_state': ('django.db.models.fields.CharField', [], {'max_length': '55', 'db_column': "'sub_state_val'"}),
|
||||
'sub_state_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||
},
|
||||
'idtracker.iesgcomment': {
|
||||
'Meta': {'unique_together': "(('ballot', 'ad'),)", 'db_table': "'ballots_comment'"},
|
||||
'active': ('django.db.models.fields.IntegerField', [], {}),
|
||||
'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IESGLogin']"}),
|
||||
'ballot': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments'", 'to': "orm['idtracker.BallotInfo']"}),
|
||||
'date': ('django.db.models.fields.DateField', [], {'db_column': "'comment_date'"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'revision': ('django.db.models.fields.CharField', [], {'max_length': '2'}),
|
||||
'text': ('django.db.models.fields.TextField', [], {'db_column': "'comment_text'", 'blank': 'True'})
|
||||
},
|
||||
'idtracker.iesgdiscuss': {
|
||||
'Meta': {'unique_together': "(('ballot', 'ad'),)", 'db_table': "'ballots_discuss'"},
|
||||
'active': ('django.db.models.fields.IntegerField', [], {}),
|
||||
'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IESGLogin']"}),
|
||||
'ballot': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'discusses'", 'to': "orm['idtracker.BallotInfo']"}),
|
||||
'date': ('django.db.models.fields.DateField', [], {'db_column': "'discuss_date'"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'revision': ('django.db.models.fields.CharField', [], {'max_length': '2'}),
|
||||
'text': ('django.db.models.fields.TextField', [], {'db_column': "'discuss_text'", 'blank': 'True'})
|
||||
},
|
||||
'idtracker.iesglogin': {
|
||||
'Meta': {'db_table': "'iesg_login'"},
|
||||
'default_search': ('django.db.models.fields.NullBooleanField', [], {'null': 'True'}),
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '25', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '25', 'blank': 'True'}),
|
||||
'login_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||
'password': ('django.db.models.fields.CharField', [], {'max_length': '25'}),
|
||||
'person': ('BrokenForeignKey', ["orm['idtracker.PersonOrOrgInfo']"], {'unique': 'True', 'null': 'True', 'db_column': "'person_or_org_tag'", 'null_values': '(0,888888)'}),
|
||||
'pgp_id': ('django.db.models.fields.CharField', [], {'max_length': '20', 'null': 'True', 'blank': 'True'}),
|
||||
'user_level': ('django.db.models.fields.IntegerField', [], {})
|
||||
},
|
||||
'idtracker.ietfwg': {
|
||||
'Meta': {'db_table': "'groups_ietf'"},
|
||||
'area_director': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.AreaDirector']", 'null': 'True'}),
|
||||
'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'concluded_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'dormant_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'email_address': ('django.db.models.fields.CharField', [], {'max_length': '60', 'blank': 'True'}),
|
||||
'email_archive': ('django.db.models.fields.CharField', [], {'max_length': '95', 'blank': 'True'}),
|
||||
'email_keyword': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
|
||||
'email_subscribe': ('django.db.models.fields.CharField', [], {'max_length': '120', 'blank': 'True'}),
|
||||
'group_acronym': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['idtracker.Acronym']", 'unique': 'True', 'primary_key': 'True'}),
|
||||
'group_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.WGType']"}),
|
||||
'last_modified_date': ('django.db.models.fields.DateField', [], {}),
|
||||
'meeting_scheduled': ('django.db.models.fields.CharField', [], {'max_length': '3', 'blank': 'True'}),
|
||||
'meeting_scheduled_old': ('django.db.models.fields.CharField', [], {'max_length': '3', 'blank': 'True'}),
|
||||
'proposed_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.WGStatus']"})
|
||||
},
|
||||
'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': ('BrokenForeignKey', ["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', [], {'to': "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.irtf': {
|
||||
'Meta': {'db_table': "'irtf'"},
|
||||
'acronym': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'irtf_acronym'", 'blank': 'True'}),
|
||||
'charter_text': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'irtf_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'meeting_scheduled': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_column': "'irtf_name'", 'blank': 'True'})
|
||||
},
|
||||
'idtracker.irtfchair': {
|
||||
'Meta': {'db_table': "'irtf_chairs'"},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'irtf': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IRTF']"}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"})
|
||||
},
|
||||
'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'})
|
||||
},
|
||||
'idtracker.phonenumber': {
|
||||
'Meta': {'db_table': "'phone_numbers'"},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person_or_org': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}),
|
||||
'phone_comment': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||
'phone_number': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||
'phone_priority': ('django.db.models.fields.IntegerField', [], {}),
|
||||
'phone_type': ('django.db.models.fields.CharField', [], {'max_length': '3'})
|
||||
},
|
||||
'idtracker.position': {
|
||||
'Meta': {'unique_together': "(('ballot', 'ad'),)", 'db_table': "'ballots'"},
|
||||
'abstain': ('django.db.models.fields.IntegerField', [], {}),
|
||||
'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IESGLogin']"}),
|
||||
'approve': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'ballot': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'positions'", 'to': "orm['idtracker.BallotInfo']"}),
|
||||
'discuss': ('django.db.models.fields.IntegerField', [], {}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'noobj': ('django.db.models.fields.IntegerField', [], {'db_column': "'no_col'"}),
|
||||
'recuse': ('django.db.models.fields.IntegerField', [], {}),
|
||||
'yes': ('django.db.models.fields.IntegerField', [], {'db_column': "'yes_col'"})
|
||||
},
|
||||
'idtracker.postaladdress': {
|
||||
'Meta': {'db_table': "'postal_addresses'"},
|
||||
'address_priority': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
|
||||
'address_type': ('django.db.models.fields.CharField', [], {'max_length': '4'}),
|
||||
'aff_company_key': ('django.db.models.fields.CharField', [], {'max_length': '70', 'blank': 'True'}),
|
||||
'affiliated_company': ('django.db.models.fields.CharField', [], {'max_length': '70', 'blank': 'True'}),
|
||||
'city': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}),
|
||||
'country': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}),
|
||||
'department': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'mail_stop': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}),
|
||||
'person_or_org': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}),
|
||||
'person_title': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
|
||||
'postal_code': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}),
|
||||
'staddr1': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
|
||||
'staddr2': ('django.db.models.fields.CharField', [], {'max_length': '40', 'blank': 'True'}),
|
||||
'state_or_prov': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'})
|
||||
},
|
||||
'idtracker.rfc': {
|
||||
'Meta': {'db_table': "'rfcs'"},
|
||||
'area_acronym': ('django.db.models.fields.CharField', [], {'max_length': '8', 'blank': 'True'}),
|
||||
'b_approve_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', [], {'blank': 'True'}),
|
||||
'draft_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'fyi_number': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}),
|
||||
'group_acronym': ('django.db.models.fields.CharField', [], {'max_length': '8', 'blank': 'True'}),
|
||||
'historic_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'intended_status': ('django.db.models.fields.related.ForeignKey', [], {'default': '5', 'to': "orm['idtracker.RfcIntendedStatus']", 'db_column': "'intended_status_id'"}),
|
||||
'last_modified_date': ('django.db.models.fields.DateField', [], {}),
|
||||
'lc_expiration_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'lc_sent_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'online_version': ('django.db.models.fields.CharField', [], {'default': "'YES'", 'max_length': '3'}),
|
||||
'proposed_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'rfc_name_key': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
|
||||
'rfc_number': ('django.db.models.fields.IntegerField', [], {'primary_key': 'True'}),
|
||||
'rfc_published_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'standard_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.RfcStatus']", 'db_column': "'status_id'"}),
|
||||
'std_number': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'db_column': "'rfc_name'"}),
|
||||
'txt_page_count': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
'idtracker.rfcauthor': {
|
||||
'Meta': {'db_table': "'rfc_authors'"},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}),
|
||||
'rfc': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'authors'", 'db_column': "'rfc_number'", 'to': "orm['idtracker.Rfc']"})
|
||||
},
|
||||
'idtracker.rfcintendedstatus': {
|
||||
'Meta': {'db_table': "'rfc_intend_status'"},
|
||||
'intended_status_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'status': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'status_value'"})
|
||||
},
|
||||
'idtracker.rfcobsolete': {
|
||||
'Meta': {'db_table': "'rfcs_obsolete'"},
|
||||
'action': ('django.db.models.fields.CharField', [], {'max_length': '20'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'rfc': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'updates_or_obsoletes'", 'db_column': "'rfc_number'", 'to': "orm['idtracker.Rfc']"}),
|
||||
'rfc_acted_on': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'updated_or_obsoleted_by'", 'db_column': "'rfc_acted_on'", 'to': "orm['idtracker.Rfc']"})
|
||||
},
|
||||
'idtracker.rfcstatus': {
|
||||
'Meta': {'db_table': "'rfc_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.role': {
|
||||
'Meta': {'db_table': "'chairs'"},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"}),
|
||||
'role_name': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'chair_name'"})
|
||||
},
|
||||
'idtracker.wgchair': {
|
||||
'Meta': {'db_table': "'g_chairs'"},
|
||||
'group_acronym': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IETFWG']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"})
|
||||
},
|
||||
'idtracker.wgeditor': {
|
||||
'Meta': {'db_table': "'g_editors'"},
|
||||
'group_acronym': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IETFWG']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'unique': 'True', 'db_column': "'person_or_org_tag'"})
|
||||
},
|
||||
'idtracker.wgsecretary': {
|
||||
'Meta': {'db_table': "'g_secretaries'"},
|
||||
'group_acronym': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IETFWG']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"})
|
||||
},
|
||||
'idtracker.wgstatus': {
|
||||
'Meta': {'db_table': "'g_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.wgtechadvisor': {
|
||||
'Meta': {'db_table': "'g_tech_advisors'"},
|
||||
'group_acronym': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IETFWG']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"})
|
||||
},
|
||||
'idtracker.wgtype': {
|
||||
'Meta': {'db_table': "'g_type'"},
|
||||
'group_type_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'type': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'group_type'"})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['idtracker']
|
0
ietf/idtracker/migrations/__init__.py
Normal file
0
ietf/idtracker/migrations/__init__.py
Normal file
|
@ -171,6 +171,7 @@ class InternetDraft(models.Model):
|
|||
review_by_rfc_editor = models.BooleanField()
|
||||
expired_tombstone = models.BooleanField()
|
||||
idinternal = FKAsOneToOne('idinternal', reverse=True, query=models.Q(rfc_flag = 0))
|
||||
shepherd = models.ForeignKey('PersonOrOrgInfo', null=True, blank=True)
|
||||
def __str__(self):
|
||||
return self.filename
|
||||
def save(self, *args, **kwargs):
|
||||
|
@ -270,7 +271,7 @@ class PersonOrOrgInfo(models.Model):
|
|||
return u"(Person #%s)" % self.person_or_org_tag
|
||||
return u"%s %s" % ( self.first_name or u"<nofirst>", self.last_name or u"<nolast>")
|
||||
def email(self, priority=1, type=None):
|
||||
name = str(self)
|
||||
name = str(self)
|
||||
email = ''
|
||||
types = type and [ type ] or [ "INET", "Prim", None ]
|
||||
for type in types:
|
||||
|
@ -1073,6 +1074,8 @@ class IRTF(models.Model):
|
|||
meeting_scheduled = models.BooleanField(blank=True)
|
||||
def __str__(self):
|
||||
return self.acronym
|
||||
def chairs(self): # return a set of IRTFChair objects for this work group
|
||||
return IRTFChair.objects.filter(irtf=self)
|
||||
class Meta:
|
||||
db_table = 'irtf'
|
||||
verbose_name="IRTF Research Group"
|
||||
|
|
0
ietf/ietfworkflows/__init__.py
Normal file
0
ietf/ietfworkflows/__init__.py
Normal file
52
ietf/ietfworkflows/accounts.py
Normal file
52
ietf/ietfworkflows/accounts.py
Normal file
|
@ -0,0 +1,52 @@
|
|||
from ietf.ietfworkflows.streams import get_streamed_draft
|
||||
|
||||
|
||||
def get_person_for_user(user):
|
||||
try:
|
||||
return user.get_profile().person()
|
||||
except:
|
||||
return None
|
||||
|
||||
|
||||
def is_secretariat(user):
|
||||
if not user or not user.is_authenticated():
|
||||
return False
|
||||
return bool(user.groups.filter(name='Secretariat'))
|
||||
|
||||
|
||||
def is_wgchair(person):
|
||||
return bool(person.wgchair_set.all())
|
||||
|
||||
|
||||
def is_wgdelegate(person):
|
||||
return bool(person.wgdelegate_set.all())
|
||||
|
||||
|
||||
def is_chair_of_draft(user, draft):
|
||||
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
|
||||
group = streamed.group
|
||||
if not group or not hasattr(group, 'chairs'):
|
||||
return False
|
||||
return bool(group.chairs().filter(person=person).count())
|
||||
|
||||
|
||||
def can_edit_state(user, draft):
|
||||
streamed = get_streamed_draft(draft)
|
||||
if not streamed or not streamed.stream:
|
||||
person = get_person_for_user(user)
|
||||
if not person:
|
||||
return False
|
||||
return (is_secretariat(user) or
|
||||
is_wgchair(person) or
|
||||
is_wgdelegate(person))
|
||||
return (is_secretariat(user) or
|
||||
is_chair_of_draft(user, draft))
|
||||
|
||||
|
||||
def can_edit_stream(user, draft):
|
||||
return is_secretariat(user)
|
17
ietf/ietfworkflows/admin.py
Normal file
17
ietf/ietfworkflows/admin.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
from django.contrib import admin
|
||||
|
||||
from ietf.ietfworkflows.models import (AnnotationTag, WGWorkflow,
|
||||
Stream)
|
||||
from workflows.admin import StateInline
|
||||
|
||||
|
||||
class AnnotationTagInline(admin.TabularInline):
|
||||
model = AnnotationTag
|
||||
|
||||
|
||||
class IETFWorkflowAdmin(admin.ModelAdmin):
|
||||
inlines = [StateInline, AnnotationTagInline]
|
||||
|
||||
|
||||
admin.site.register(WGWorkflow, IETFWorkflowAdmin)
|
||||
admin.site.register(Stream, admin.ModelAdmin)
|
13
ietf/ietfworkflows/constants.py
Normal file
13
ietf/ietfworkflows/constants.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
# Required states
|
||||
CALL_FOR_ADOPTION = 'Call For Adoption By WG Issued'
|
||||
WG_DOCUMENT = 'WG Document'
|
||||
SUBMITTED_TO_IESG = 'Submitted to IESG for Publication'
|
||||
|
||||
REQUIRED_STATES = (
|
||||
CALL_FOR_ADOPTION,
|
||||
WG_DOCUMENT,
|
||||
SUBMITTED_TO_IESG,
|
||||
)
|
||||
|
||||
# IETF Stream
|
||||
IETF_STREAM = 'IETF'
|
705
ietf/ietfworkflows/fixtures/initial_data.xml
Normal file
705
ietf/ietfworkflows/fixtures/initial_data.xml
Normal file
|
@ -0,0 +1,705 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<django-objects version="1.0">
|
||||
<object pk="1" model="workflows.workflow">
|
||||
<field type="CharField" name="name">Default WG Workflow</field>
|
||||
<field to="workflows.state" name="initial_state" rel="ManyToOneRel">11</field>
|
||||
</object>
|
||||
<object pk="2" model="workflows.workflow">
|
||||
<field type="CharField" name="name">IAB Workflow</field>
|
||||
<field to="workflows.state" name="initial_state" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="3" model="workflows.workflow">
|
||||
<field type="CharField" name="name">IRTF Workflow</field>
|
||||
<field to="workflows.state" name="initial_state" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="4" model="workflows.workflow">
|
||||
<field type="CharField" name="name">ISE Workflow</field>
|
||||
<field to="workflows.state" name="initial_state" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="32" model="workflows.state">
|
||||
<field type="CharField" name="name">Active IAB Document</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">2</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="42" model="workflows.state">
|
||||
<field type="CharField" name="name">Active RG Document</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">3</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="12" model="workflows.state">
|
||||
<field type="CharField" name="name">Adopted by a WG</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"><object pk="12"></object></field>
|
||||
</object>
|
||||
<object pk="13" model="workflows.state">
|
||||
<field type="CharField" name="name">Adopted for WG Info Only</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="36" model="workflows.state">
|
||||
<field type="CharField" name="name">Approved by IAB, To Be Sent to RFC Editor</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">2</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="47" model="workflows.state">
|
||||
<field type="CharField" name="name">Awaiting IRSG Reviews</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">3</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="11" model="workflows.state">
|
||||
<field type="CharField" name="name">Call For Adoption By WG Issued</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"><object pk="10"></object><object pk="11"></object></field>
|
||||
</object>
|
||||
<object pk="31" model="workflows.state">
|
||||
<field type="CharField" name="name">Candidate IAB Document</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">2</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="41" model="workflows.state">
|
||||
<field type="CharField" name="name">Candidate RG Document</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">3</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="35" model="workflows.state">
|
||||
<field type="CharField" name="name">Community Review</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">2</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="40" model="workflows.state">
|
||||
<field type="CharField" name="name">Dead IAB Document</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">2</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="53" model="workflows.state">
|
||||
<field type="CharField" name="name">Dead IRTF Document</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">3</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="16" model="workflows.state">
|
||||
<field type="CharField" name="name">Dead WG Document</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"><object pk="12"></object></field>
|
||||
</object>
|
||||
<object pk="51" model="workflows.state">
|
||||
<field type="CharField" name="name">Document on Hold Based On IESG Request</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">3</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="62" model="workflows.state">
|
||||
<field type="CharField" name="name">Document on Hold Based On IESG Request</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">4</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="55" model="workflows.state">
|
||||
<field type="CharField" name="name">Finding Reviewers</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">4</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="34" model="workflows.state">
|
||||
<field type="CharField" name="name">IAB Review</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">2</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="49" model="workflows.state">
|
||||
<field type="CharField" name="name">In IESG Review</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">3</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="58" model="workflows.state">
|
||||
<field type="CharField" name="name">In IESG Review</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">4</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="48" model="workflows.state">
|
||||
<field type="CharField" name="name">In IRSG Poll</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">3</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="56" model="workflows.state">
|
||||
<field type="CharField" name="name">In ISE Review</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">4</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="44" model="workflows.state">
|
||||
<field type="CharField" name="name">In RG Last Call</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">3</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="17" model="workflows.state">
|
||||
<field type="CharField" name="name">In WG Last Call</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"><object pk="12"></object><object pk="17"></object><object pk="18"></object></field>
|
||||
</object>
|
||||
<object pk="61" model="workflows.state">
|
||||
<field type="CharField" name="name">No Longer In Independent Submission Stream</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">4</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="33" model="workflows.state">
|
||||
<field type="CharField" name="name">Parked IAB Document</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">2</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="43" model="workflows.state">
|
||||
<field type="CharField" name="name">Parked RG Document</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">3</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="15" model="workflows.state">
|
||||
<field type="CharField" name="name">Parked WG Document</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"><object pk="12"></object></field>
|
||||
</object>
|
||||
<object pk="52" model="workflows.state">
|
||||
<field type="CharField" name="name">Published RFC</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">3</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="60" model="workflows.state">
|
||||
<field type="CharField" name="name">Published RFC</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">4</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="39" model="workflows.state">
|
||||
<field type="CharField" name="name">Published RFC</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">2</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="57" model="workflows.state">
|
||||
<field type="CharField" name="name">Response to Review Needed</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">4</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="37" model="workflows.state">
|
||||
<field type="CharField" name="name">Sent to a Different Organization for Publication</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">2</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="38" model="workflows.state">
|
||||
<field type="CharField" name="name">Sent to the RFC Editor</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">2</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="59" model="workflows.state">
|
||||
<field type="CharField" name="name">Sent to the RFC Editor</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">4</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="50" model="workflows.state">
|
||||
<field type="CharField" name="name">Sent to the RFC Editor</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">3</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="54" model="workflows.state">
|
||||
<field type="CharField" name="name">Submission Received</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">4</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="20" model="workflows.state">
|
||||
<field type="CharField" name="name">Submitted to IESG for Publication</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"><object pk="12"></object></field>
|
||||
</object>
|
||||
<object pk="45" model="workflows.state">
|
||||
<field type="CharField" name="name">Waiting for Document Shepherd</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">3</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="46" model="workflows.state">
|
||||
<field type="CharField" name="name">Waiting for IRTF Chair</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">3</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="18" model="workflows.state">
|
||||
<field type="CharField" name="name">Waiting for WG Chair Go-Ahead</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"><object pk="16"></object><object pk="17"></object></field>
|
||||
</object>
|
||||
<object pk="19" model="workflows.state">
|
||||
<field type="CharField" name="name">WG Consensus: Waiting for Write-Up</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"><object pk="15"></object></field>
|
||||
</object>
|
||||
<object pk="14" model="workflows.state">
|
||||
<field type="CharField" name="name">WG Document</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
<field to="workflows.transition" name="transitions" rel="ManyToManyRel"><object pk="13"></object><object pk="14"></object><object pk="16"></object><object pk="17"></object></field>
|
||||
</object>
|
||||
<object pk="18" model="workflows.transition">
|
||||
<field type="CharField" name="name">Wait for go-ahead</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
<field to="workflows.state" name="destination" rel="ManyToOneRel">18</field>
|
||||
<field type="CharField" name="condition"></field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="17" model="workflows.transition">
|
||||
<field type="CharField" name="name">Reach consensus</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
<field to="workflows.state" name="destination" rel="ManyToOneRel">19</field>
|
||||
<field type="CharField" name="condition"></field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="10" model="workflows.transition">
|
||||
<field type="CharField" name="name">Adopt</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
<field to="workflows.state" name="destination" rel="ManyToOneRel">12</field>
|
||||
<field type="CharField" name="condition"></field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="11" model="workflows.transition">
|
||||
<field type="CharField" name="name">Adopt for WG info only</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
<field to="workflows.state" name="destination" rel="ManyToOneRel">13</field>
|
||||
<field type="CharField" name="condition"></field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="12" model="workflows.transition">
|
||||
<field type="CharField" name="name">Develop</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
<field to="workflows.state" name="destination" rel="ManyToOneRel">14</field>
|
||||
<field type="CharField" name="condition"></field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="13" model="workflows.transition">
|
||||
<field type="CharField" name="name">Park</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
<field to="workflows.state" name="destination" rel="ManyToOneRel">15</field>
|
||||
<field type="CharField" name="condition"></field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="14" model="workflows.transition">
|
||||
<field type="CharField" name="name">Die</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
<field to="workflows.state" name="destination" rel="ManyToOneRel">16</field>
|
||||
<field type="CharField" name="condition"></field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="15" model="workflows.transition">
|
||||
<field type="CharField" name="name">Submit to IESG</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
<field to="workflows.state" name="destination" rel="ManyToOneRel">20</field>
|
||||
<field type="CharField" name="condition"></field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="16" model="workflows.transition">
|
||||
<field type="CharField" name="name">Raise last call</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
<field to="workflows.state" name="destination" rel="ManyToOneRel">17</field>
|
||||
<field type="CharField" name="condition"></field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="31" model="ietfworkflows.annotationtag">
|
||||
<field type="CharField" name="name">Revised I-D Needed</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">3</field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="29" model="ietfworkflows.annotationtag">
|
||||
<field type="CharField" name="name">Shepherd Needed</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">3</field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="30" model="ietfworkflows.annotationtag">
|
||||
<field type="CharField" name="name">Waiting for Dependency on Other Document</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">3</field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="26" model="ietfworkflows.annotationtag">
|
||||
<field type="CharField" name="name">Revised I-D Needed</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">2</field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="27" model="ietfworkflows.annotationtag">
|
||||
<field type="CharField" name="name">Document Shepherd Followup</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">2</field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="28" model="ietfworkflows.annotationtag">
|
||||
<field type="CharField" name="name">Editor Needed</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">3</field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="25" model="ietfworkflows.annotationtag">
|
||||
<field type="CharField" name="name">Awaiting Reviews</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">2</field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="24" model="ietfworkflows.annotationtag">
|
||||
<field type="CharField" name="name">Waiting for Partner Feedback</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">2</field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="11" model="ietfworkflows.annotationtag">
|
||||
<field type="CharField" name="name">Other - see Comment Log</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="23" model="ietfworkflows.annotationtag">
|
||||
<field type="CharField" name="name">Editor Needed</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">2</field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="10" model="ietfworkflows.annotationtag">
|
||||
<field type="CharField" name="name">Doc Shepherd Follow-Up Underway</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="9" model="ietfworkflows.annotationtag">
|
||||
<field type="CharField" name="name">Revised I-D Needed - Issue raised by IESG</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="1" model="ietfworkflows.annotationtag">
|
||||
<field type="CharField" name="name">Awaiting Expert Review/Resolution of Issues Raised</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="2" model="ietfworkflows.annotationtag">
|
||||
<field type="CharField" name="name">Awaiting External Review/Resolution of Issues Raised</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="3" model="ietfworkflows.annotationtag">
|
||||
<field type="CharField" name="name">Awaiting Merge with Other Document</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="4" model="ietfworkflows.annotationtag">
|
||||
<field type="CharField" name="name">Author or Editor Needed</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="5" model="ietfworkflows.annotationtag">
|
||||
<field type="CharField" name="name">Waiting for Referenced Document</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="8" model="ietfworkflows.annotationtag">
|
||||
<field type="CharField" name="name">Revised I-D Needed - Issue raised by AD</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="7" model="ietfworkflows.annotationtag">
|
||||
<field type="CharField" name="name">Revised I-D Needed - Issue raised by WGLC</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="6" model="ietfworkflows.annotationtag">
|
||||
<field type="CharField" name="name">Waiting for Referencing Document</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="32" model="ietfworkflows.annotationtag">
|
||||
<field type="CharField" name="name">IESG Review Completed</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">3</field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="33" model="ietfworkflows.annotationtag">
|
||||
<field type="CharField" name="name">Waiting for Dependency on Other Document</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">4</field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="34" model="ietfworkflows.annotationtag">
|
||||
<field type="CharField" name="name">Awaiting Reviews</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">4</field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="35" model="ietfworkflows.annotationtag">
|
||||
<field type="CharField" name="name">Revised I-D Needed</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">4</field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="36" model="ietfworkflows.annotationtag">
|
||||
<field type="CharField" name="name">IESG Review Completed</field>
|
||||
<field to="workflows.workflow" name="workflow" rel="ManyToOneRel">4</field>
|
||||
<field to="permissions.permission" name="permission" rel="ManyToOneRel"><None></None></field>
|
||||
</object>
|
||||
<object pk="1" model="ietfworkflows.wgworkflow">
|
||||
<field to="workflows.state" name="selected_states" rel="ManyToManyRel"></field>
|
||||
<field to="ietfworkflows.annotationtag" name="selected_tags" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="2" model="ietfworkflows.wgworkflow">
|
||||
<field to="workflows.state" name="selected_states" rel="ManyToManyRel"></field>
|
||||
<field to="ietfworkflows.annotationtag" name="selected_tags" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="3" model="ietfworkflows.wgworkflow">
|
||||
<field to="workflows.state" name="selected_states" rel="ManyToManyRel"></field>
|
||||
<field to="ietfworkflows.annotationtag" name="selected_tags" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="4" model="ietfworkflows.wgworkflow">
|
||||
<field to="workflows.state" name="selected_states" rel="ManyToManyRel"></field>
|
||||
<field to="ietfworkflows.annotationtag" name="selected_tags" rel="ManyToManyRel"></field>
|
||||
</object>
|
||||
<object pk="1" model="ietfworkflows.stream">
|
||||
<field type="CharField" name="name">IETF</field>
|
||||
<field type="BooleanField" name="with_groups">True</field>
|
||||
<field type="CharField" name="group_model">idtracker.IETFWG</field>
|
||||
<field type="CharField" name="group_chair_model">idtracker.WGChair</field>
|
||||
<field to="ietfworkflows.wgworkflow" name="workflow" rel="ManyToOneRel">1</field>
|
||||
</object>
|
||||
<object pk="2" model="ietfworkflows.stream">
|
||||
<field type="CharField" name="name">IAB</field>
|
||||
<field type="BooleanField" name="with_groups">False</field>
|
||||
<field type="CharField" name="group_model"></field>
|
||||
<field type="CharField" name="group_chair_model"></field>
|
||||
<field to="ietfworkflows.wgworkflow" name="workflow" rel="ManyToOneRel">2</field>
|
||||
</object>
|
||||
<object pk="3" model="ietfworkflows.stream">
|
||||
<field type="CharField" name="name">IRTF</field>
|
||||
<field type="BooleanField" name="with_groups">True</field>
|
||||
<field type="CharField" name="group_model">idtracker.IRTF</field>
|
||||
<field type="CharField" name="group_chair_model">idtracker.IRTFChair</field>
|
||||
<field to="ietfworkflows.wgworkflow" name="workflow" rel="ManyToOneRel">3</field>
|
||||
</object>
|
||||
<object pk="4" model="ietfworkflows.stream">
|
||||
<field type="CharField" name="name">ISE</field>
|
||||
<field type="BooleanField" name="with_groups">False</field>
|
||||
<field type="CharField" name="group_model"></field>
|
||||
<field type="CharField" name="group_chair_model"></field>
|
||||
<field to="ietfworkflows.wgworkflow" name="workflow" rel="ManyToOneRel">4</field>
|
||||
</object>
|
||||
<object pk="1" model="ietfworkflows.statedescription">
|
||||
<field to="workflows.state" name="state" rel="ManyToOneRel">11</field>
|
||||
<field type="TextField" name="definition"><a href="http://tools.ietf.org/html/rfc6174#section-4.2.1" target="_blank">4.2.1. Call for Adoption by WG Issued</a>
|
||||
|
||||
|
||||
The "Call for Adoption by WG Issued" state should be used to indicate
|
||||
when an I-D is being considered for adoption by an IETF WG. An I-D
|
||||
that is in this state is actively being considered for adoption and
|
||||
has not yet achieved consensus, preference, or selection in the WG.
|
||||
|
||||
This state may be used to describe an I-D that someone has asked a WG
|
||||
to consider for adoption, if the WG Chair has agreed with the
|
||||
request. This state may also be used to identify an I-D that a WG
|
||||
Chair asked an author to write specifically for consideration as a
|
||||
candidate WG item [WGDTSPEC], and/or an I-D that is listed as a
|
||||
'candidate draft' in the WG's charter.
|
||||
|
||||
Under normal conditions, it should not be possible for an I-D to be
|
||||
in the "Call for Adoption by WG Issued" state in more than one
|
||||
working group at the same time. This said, it is not uncommon for
|
||||
authors to "shop" their I-Ds to more than one WG at a time, with the
|
||||
hope of getting their documents adopted somewhere.
|
||||
|
||||
After this state is implemented in the Datatracker, an I-D that is in
|
||||
the "Call for Adoption by WG Issued" state will not be able to be
|
||||
"shopped" to any other WG without the consent of the WG Chairs and
|
||||
the responsible ADs impacted by the shopping.
|
||||
|
||||
Note that Figure 1 includes an arc leading from this state to outside
|
||||
of the WG state machine. This illustrates that some I-Ds that are
|
||||
considered do not get adopted as WG drafts. An I-D that is not
|
||||
adopted as a WG draft will transition out of the WG state machine and
|
||||
revert back to having no stream-specific state; however, the status
|
||||
change history log of the I-D will record that the I-D was previously
|
||||
in the "Call for Adoption by WG Issued" state.
|
||||
</field>
|
||||
<field type="PositiveIntegerField" name="order">1</field>
|
||||
</object>
|
||||
<object pk="2" model="ietfworkflows.statedescription">
|
||||
<field to="workflows.state" name="state" rel="ManyToOneRel">12</field>
|
||||
<field type="TextField" name="definition"><a href="http://tools.ietf.org/html/rfc6174#section-4.2.2" target="_blank">4.2.2. Adopted by a WG</a>
|
||||
|
||||
|
||||
The "Adopted by a WG" state describes an individual submission I-D
|
||||
that an IETF WG has agreed to adopt as one of its WG drafts.
|
||||
|
||||
WG Chairs who use this state will be able to clearly indicate when
|
||||
their WGs adopt individual submission I-Ds. This will facilitate the
|
||||
Datatracker's ability to correctly capture "Replaces" information for
|
||||
WG drafts and correct "Replaced by" information for individual
|
||||
submission I-Ds that have been replaced by WG drafts.
|
||||
|
||||
This state is needed because the Datatracker uses the filename of an
|
||||
I-D as a key to search its database for status information about the
|
||||
I-D, and because the filename of a WG I-D is supposed to be different
|
||||
from the filename of an individual submission I-D.
|
||||
The filename of an individual submission I-D will typically be
|
||||
formatted as 'draft-author-wgname-topic-nn'.
|
||||
|
||||
The filename of a WG document is supposed to be formatted as 'draft-
|
||||
ietf-wgname-topic-nn'.
|
||||
|
||||
An individual I-D that is adopted by a WG may take weeks or months to
|
||||
be resubmitted by the author as a new (version-00) WG draft. If the
|
||||
"Adopted by a WG" state is not used, the Datatracker has no way to
|
||||
determine that an I-D has been adopted until a new version of the I-D
|
||||
is submitted to the WG by the author and until the I-D is approved
|
||||
for posting by a WG Chair.
|
||||
</field>
|
||||
<field type="PositiveIntegerField" name="order">2</field>
|
||||
</object>
|
||||
<object pk="3" model="ietfworkflows.statedescription">
|
||||
<field to="workflows.state" name="state" rel="ManyToOneRel">13</field>
|
||||
<field type="TextField" name="definition"><a href="http://tools.ietf.org/html/rfc6174#section-4.2.3" target="_blank">4.2.3. Adopted for WG Info Only</a>
|
||||
|
||||
|
||||
The "Adopted for WG Info Only" state describes a document that
|
||||
contains useful information for the WG that adopted it, but the
|
||||
document is not intended to be published as an RFC. The WG will not
|
||||
actively develop the contents of the I-D or progress it for
|
||||
publication as an RFC. The only purpose of the I-D is to provide
|
||||
information for internal use by the WG.
|
||||
</field>
|
||||
<field type="PositiveIntegerField" name="order">3</field>
|
||||
</object>
|
||||
<object pk="4" model="ietfworkflows.statedescription">
|
||||
<field to="workflows.state" name="state" rel="ManyToOneRel">14</field>
|
||||
<field type="TextField" name="definition"><a href="http://tools.ietf.org/html/rfc6174#section-4.2.4" target="_blank">4.2.4. WG Document</a>
|
||||
|
||||
|
||||
The "WG Document" state describes an I-D that has been adopted by an
|
||||
IETF WG and is being actively developed.
|
||||
|
||||
A WG Chair may transition an I-D into the "WG Document" state at any
|
||||
time as long as the I-D is not being considered or developed in any
|
||||
other WG.
|
||||
|
||||
Alternatively, WG Chairs may rely upon new functionality to be added
|
||||
to the Datatracker to automatically move version-00 drafts into the
|
||||
"WG Document" state as described in Section 4.1.
|
||||
|
||||
Under normal conditions, it should not be possible for an I-D to be
|
||||
in the "WG Document" state in more than one WG at a time. This said,
|
||||
I-Ds may be transferred from one WG to another with the consent of
|
||||
the WG Chairs and the responsible ADs.
|
||||
|
||||
</field>
|
||||
<field type="PositiveIntegerField" name="order">4</field>
|
||||
</object>
|
||||
<object pk="5" model="ietfworkflows.statedescription">
|
||||
<field to="workflows.state" name="state" rel="ManyToOneRel">15</field>
|
||||
<field type="TextField" name="definition"><a href="http://tools.ietf.org/html/rfc6174#section-4.2.5" target="_blank">4.2.5. Parked WG Document</a>
|
||||
|
||||
|
||||
A "Parked WG Document" is an I-D that has lost its author or editor,
|
||||
is waiting for another document to be written or for a review to be
|
||||
completed, or cannot be progressed by the working group for some
|
||||
other reason.
|
||||
|
||||
Some of the annotation tags described in Section 4.3 may be used in
|
||||
conjunction with this state to indicate why an I-D has been parked,
|
||||
and/or what may need to happen for the I-D to be un-parked.
|
||||
|
||||
Parking a WG draft will not prevent it from expiring; however, this
|
||||
state can be used to indicate why the I-D has stopped progressing in
|
||||
the WG.
|
||||
|
||||
A "Parked WG Document" that is not expired may be transferred from
|
||||
one WG to another with the consent of the WG Chairs and the
|
||||
responsible ADs.
|
||||
|
||||
</field>
|
||||
<field type="PositiveIntegerField" name="order">5</field>
|
||||
</object>
|
||||
<object pk="6" model="ietfworkflows.statedescription">
|
||||
<field to="workflows.state" name="state" rel="ManyToOneRel">16</field>
|
||||
<field type="TextField" name="definition"><a href="http://tools.ietf.org/html/rfc6174#section-4.2.6" target="_blank">4.2.6. Dead WG Document</a>
|
||||
|
||||
|
||||
A "Dead WG Document" is an I-D that has been abandoned. Note that
|
||||
'Dead' is not always a final state for a WG I-D. If consensus is
|
||||
subsequently achieved, a "Dead WG Document" may be resurrected. A
|
||||
"Dead WG Document" that is not resurrected will eventually expire.
|
||||
|
||||
Note that an I-D that is declared to be "Dead" in one WG and that is
|
||||
not expired may be transferred to a non-dead state in another WG with
|
||||
the consent of the WG Chairs and the responsible ADs.
|
||||
|
||||
</field>
|
||||
<field type="PositiveIntegerField" name="order">6</field>
|
||||
</object>
|
||||
<object pk="7" model="ietfworkflows.statedescription">
|
||||
<field to="workflows.state" name="state" rel="ManyToOneRel">17</field>
|
||||
<field type="TextField" name="definition"><a href="http://tools.ietf.org/html/rfc6174#section-4.2.7" target="_blank">4.2.7. In WG Last Call</a>
|
||||
|
||||
|
||||
A document "In WG Last Call" is an I-D for which a WG Last Call
|
||||
(WGLC) has been issued and is in progress.
|
||||
|
||||
Note that conducting a WGLC is an optional part of the IETF WG
|
||||
process, per Section 7.4 of RFC 2418 [RFC2418].
|
||||
|
||||
If a WG Chair decides to conduct a WGLC on an I-D, the "In WG Last
|
||||
Call" state can be used to track the progress of the WGLC. The Chair
|
||||
may configure the Datatracker to send a WGLC message to one or more
|
||||
mailing lists when the Chair moves the I-D into this state. The WG
|
||||
Chair may also be able to select a different set of mailing lists for
|
||||
a different document undergoing a WGLC; some documents may deserve
|
||||
coordination with other WGs.
|
||||
|
||||
A WG I-D in this state should remain "In WG Last Call" until the WG
|
||||
Chair moves it to another state. The WG Chair may configure the
|
||||
Datatracker to send an e-mail after a specified period of time to
|
||||
remind or 'nudge' the Chair to conclude the WGLC and to determine the
|
||||
next state for the document.
|
||||
|
||||
It is possible for one WGLC to lead into another WGLC for the same
|
||||
document. For example, an I-D that completed a WGLC as an
|
||||
"Informational" document may need another WGLC if a decision is taken
|
||||
to convert the I-D into a Standards Track document.
|
||||
|
||||
</field>
|
||||
<field type="PositiveIntegerField" name="order">7</field>
|
||||
</object>
|
||||
<object pk="8" model="ietfworkflows.statedescription">
|
||||
<field to="workflows.state" name="state" rel="ManyToOneRel">18</field>
|
||||
<field type="TextField" name="definition"><a href="http://tools.ietf.org/html/rfc6174#section-4.2.8" target="_blank">4.2.8. Waiting for WG Chair Go-Ahead</a>
|
||||
|
||||
|
||||
A WG Chair may wish to place an I-D that receives a lot of comments
|
||||
during a WGLC into the "Waiting for WG Chair Go-Ahead" state. This
|
||||
state describes an I-D that has undergone a WGLC; however, the Chair
|
||||
is not yet ready to call consensus on the document.
|
||||
|
||||
If comments from the WGLC need to be responded to, or a revision to
|
||||
the I-D is needed, the Chair may place an I-D into this state until
|
||||
all of the WGLC comments are adequately addressed and the (possibly
|
||||
revised) document is in the I-D repository.
|
||||
|
||||
</field>
|
||||
<field type="PositiveIntegerField" name="order">8</field>
|
||||
</object>
|
||||
<object pk="9" model="ietfworkflows.statedescription">
|
||||
<field to="workflows.state" name="state" rel="ManyToOneRel">19</field>
|
||||
<field type="TextField" name="definition"><a href="http://tools.ietf.org/html/rfc6174#section-4.2.9" target="_blank">4.2.9. WG Consensus: Waiting for Writeup</a>
|
||||
|
||||
|
||||
A document in the "WG Consensus: Waiting for Writeup" state has
|
||||
essentially completed its development within the working group, and
|
||||
is nearly ready to be sent to the IESG for publication. The last
|
||||
thing to be done is the preparation of a protocol writeup by a
|
||||
Document Shepherd. The IESG requires that a document shepherd
|
||||
writeup be completed before publication of the I-D is requested. The
|
||||
IETF document shepherding process and the role of a WG Document
|
||||
Shepherd is described in RFC 4858 [RFC4858]
|
||||
|
||||
A WG Chair may call consensus on an I-D without a formal WGLC and
|
||||
transition an I-D that was in the "WG Document" state directly into
|
||||
this state.
|
||||
|
||||
The name of this state includes the words "Waiting for Writeup"
|
||||
because a good document shepherd writeup takes time to prepare.
|
||||
|
||||
</field>
|
||||
<field type="PositiveIntegerField" name="order">9</field>
|
||||
</object>
|
||||
<object pk="10" model="ietfworkflows.statedescription">
|
||||
<field to="workflows.state" name="state" rel="ManyToOneRel">20</field>
|
||||
<field type="TextField" name="definition"><a href="http://tools.ietf.org/html/rfc6174#section-4.2.10" target="_blank">4.2.10. Submitted to IESG for Publication</a>
|
||||
|
||||
|
||||
This state describes a WG document that has been submitted to the
|
||||
IESG for publication and that has not been sent back to the working
|
||||
group for revision.
|
||||
|
||||
An I-D in this state may be under review by the IESG, it may have
|
||||
been approved and be in the RFC Editor's queue, or it may have been
|
||||
published as an RFC. Other possibilities exist too. The document
|
||||
may be "Dead" (in the IESG state machine) or in a "Do Not Publish"
|
||||
state.
|
||||
|
||||
</field>
|
||||
<field type="PositiveIntegerField" name="order">10</field>
|
||||
</object>
|
||||
</django-objects>
|
202
ietf/ietfworkflows/forms.py
Normal file
202
ietf/ietfworkflows/forms.py
Normal file
|
@ -0,0 +1,202 @@
|
|||
import datetime
|
||||
|
||||
|
||||
from django import forms
|
||||
from django.template.loader import render_to_string
|
||||
from workflows.models import State
|
||||
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.utils import (get_workflow_for_draft, get_workflow_for_wg,
|
||||
get_state_for_draft, get_state_by_name,
|
||||
update_state, FOLLOWUP_TAG,
|
||||
get_annotation_tags_for_draft,
|
||||
update_tags, update_stream)
|
||||
from ietf.ietfworkflows.accounts import is_secretariat
|
||||
from ietf.ietfworkflows.streams import (get_stream_from_draft, get_streamed_draft,
|
||||
get_stream_by_name, set_stream_for_draft)
|
||||
from ietf.ietfworkflows.constants import CALL_FOR_ADOPTION, IETF_STREAM
|
||||
|
||||
|
||||
class StreamDraftForm(forms.Form):
|
||||
|
||||
can_cancel = False
|
||||
template = None
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.draft = kwargs.pop('draft', None)
|
||||
self.user = kwargs.pop('user', None)
|
||||
self.person = get_person_for_user(self.user)
|
||||
self.workflow = get_workflow_for_draft(self.draft)
|
||||
self.message = {}
|
||||
super(StreamDraftForm, self).__init__(*args, **kwargs)
|
||||
|
||||
def get_message(self):
|
||||
return self.message
|
||||
|
||||
def set_message(self, msg_type, msg_value):
|
||||
self.message = {'type': msg_type,
|
||||
'value': msg_value,
|
||||
}
|
||||
|
||||
def __unicode__(self):
|
||||
return render_to_string(self.template, {'form': self})
|
||||
|
||||
|
||||
class NoWorkflowStateForm(StreamDraftForm):
|
||||
comment = forms.CharField(widget=forms.Textarea)
|
||||
weeks = forms.IntegerField(required=False)
|
||||
wg = forms.ChoiceField(required=False)
|
||||
|
||||
template = 'ietfworkflows/noworkflow_state_form.html'
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(NoWorkflowStateForm, self).__init__(*args, **kwargs)
|
||||
self.wgs = None
|
||||
self.onlywg = None
|
||||
if is_secretariat(self.user):
|
||||
wgs = IETFWG.objects.all()
|
||||
else:
|
||||
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.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
|
||||
|
||||
def save(self):
|
||||
comment = self.cleaned_data.get('comment')
|
||||
weeks = self.cleaned_data.get('weeks')
|
||||
if self.onlywg:
|
||||
wg = self.onlywg
|
||||
else:
|
||||
wg = IETFWG.objects.get(pk=self.cleaned_data.get('wg'))
|
||||
estimated_date = None
|
||||
if weeks:
|
||||
now = datetime.date.today()
|
||||
estimated_date = now + datetime.timedelta(weeks=weeks)
|
||||
workflow = get_workflow_for_wg(wg)
|
||||
set_workflow_for_object(self.draft, workflow)
|
||||
stream = get_stream_by_name(IETF_STREAM)
|
||||
streamed = get_streamed_draft(self.draft)
|
||||
if not streamed:
|
||||
set_stream_for_draft(self.draft, stream)
|
||||
streamed = get_streamed_draft(self.draft)
|
||||
streamed.stream = stream
|
||||
streamed.group = wg
|
||||
streamed.save()
|
||||
update_state(obj=self.draft,
|
||||
comment=comment,
|
||||
person=self.person,
|
||||
to_state=get_state_by_name(CALL_FOR_ADOPTION),
|
||||
estimated_date=estimated_date)
|
||||
|
||||
|
||||
class DraftTagsStateForm(StreamDraftForm):
|
||||
|
||||
comment = forms.CharField(widget=forms.Textarea)
|
||||
new_state = forms.ChoiceField()
|
||||
weeks = forms.IntegerField(required=False)
|
||||
tags = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple, required=False)
|
||||
|
||||
template = 'ietfworkflows/state_form.html'
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(DraftTagsStateForm, self).__init__(*args, **kwargs)
|
||||
self.state = get_state_for_draft(self.draft)
|
||||
self.fields['new_state'].choices = self.get_states()
|
||||
if self.is_bound:
|
||||
for key, value in self.data.items():
|
||||
if key.startswith('transition_'):
|
||||
new_state = self.get_new_state(key)
|
||||
if new_state:
|
||||
self.data = self.data.copy()
|
||||
self.data.update({'new_state': new_state.id})
|
||||
self.available_tags = self.workflow.get_tags()
|
||||
self.tags = [i.annotation_tag for i in get_annotation_tags_for_draft(self.draft)]
|
||||
self.fields['tags'].choices = [(i.pk, i.name) for i in self.available_tags]
|
||||
self.fields['tags'].initial = [i.pk for i in self.tags]
|
||||
|
||||
def get_new_state(self, key):
|
||||
transition_id = key.replace('transition_', '')
|
||||
transition = self.get_transitions().filter(id=transition_id)
|
||||
if transition:
|
||||
return transition[0].destination
|
||||
return None
|
||||
|
||||
def get_transitions(self):
|
||||
return self.state.transitions.filter(workflow=self.workflow)
|
||||
|
||||
def get_states(self):
|
||||
return [(i.pk, i.name) for i in self.workflow.get_states()]
|
||||
|
||||
def save_tags(self):
|
||||
comment = self.cleaned_data.get('comment')
|
||||
new_tags = self.cleaned_data.get('tags')
|
||||
|
||||
set_tags = [tag for tag in self.available_tags if str(tag.pk) in new_tags and tag not in self.tags]
|
||||
reset_tags = [tag for tag in self.available_tags if str(tag.pk) not in new_tags and tag in self.tags]
|
||||
followup = bool([tag for tag in set_tags if tag.name == FOLLOWUP_TAG])
|
||||
extra_notify = []
|
||||
if followup:
|
||||
try:
|
||||
shepherd = self.draft.shepherd
|
||||
if shepherd:
|
||||
extra_notify = ['%s <%s>' % shepherd.email()]
|
||||
except PersonOrOrgInfo.DoesNotExist:
|
||||
pass
|
||||
if not set_tags and not reset_tags:
|
||||
return
|
||||
update_tags(self.draft,
|
||||
comment=comment,
|
||||
person=self.person,
|
||||
set_tags=set_tags,
|
||||
reset_tags=reset_tags,
|
||||
extra_notify=extra_notify)
|
||||
|
||||
def save_state(self):
|
||||
comment = self.cleaned_data.get('comment')
|
||||
state = State.objects.get(pk=self.cleaned_data.get('new_state'))
|
||||
weeks = self.cleaned_data.get('weeks')
|
||||
estimated_date = None
|
||||
if weeks:
|
||||
now = datetime.date.today()
|
||||
estimated_date = now + datetime.timedelta(weeks=weeks)
|
||||
update_state(obj=self.draft,
|
||||
comment=comment,
|
||||
person=self.person,
|
||||
to_state=state,
|
||||
estimated_date=estimated_date)
|
||||
|
||||
def save(self):
|
||||
self.save_tags()
|
||||
if 'only_tags' in self.data.keys():
|
||||
return
|
||||
self.save_state()
|
||||
|
||||
|
||||
class DraftStreamForm(StreamDraftForm):
|
||||
|
||||
comment = forms.CharField(widget=forms.Textarea)
|
||||
stream = forms.ModelChoiceField(Stream.objects.all())
|
||||
|
||||
template = 'ietfworkflows/stream_form.html'
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(DraftStreamForm, self).__init__(*args, **kwargs)
|
||||
self.stream = get_stream_from_draft(self.draft)
|
||||
self.tags = [i.annotation_tag for i in get_annotation_tags_for_draft(self.draft)]
|
||||
if self.stream:
|
||||
self.fields['stream'].initial = self.stream.pk
|
||||
|
||||
def save(self):
|
||||
comment = self.cleaned_data.get('comment')
|
||||
to_stream = self.cleaned_data.get('stream')
|
||||
|
||||
update_stream(self.draft,
|
||||
comment=comment,
|
||||
person=self.person,
|
||||
to_stream=to_stream)
|
148
ietf/ietfworkflows/migrations/0001_initial.py
Normal file
148
ietf/ietfworkflows/migrations/0001_initial.py
Normal file
|
@ -0,0 +1,148 @@
|
|||
|
||||
from south.db import db
|
||||
from django.db import models
|
||||
from ietf.ietfworkflows.models import *
|
||||
|
||||
class Migration:
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Adding model 'WGWorkflow'
|
||||
db.create_table('ietfworkflows_wgworkflow', (
|
||||
('workflow_ptr', orm['ietfworkflows.WGWorkflow:workflow_ptr']),
|
||||
))
|
||||
db.send_create_signal('ietfworkflows', ['WGWorkflow'])
|
||||
|
||||
# Adding model 'ObjectWorkflowHistoryEntry'
|
||||
db.create_table('ietfworkflows_objectworkflowhistoryentry', (
|
||||
('id', orm['ietfworkflows.ObjectWorkflowHistoryEntry:id']),
|
||||
('content_type', orm['ietfworkflows.ObjectWorkflowHistoryEntry:content_type']),
|
||||
('content_id', orm['ietfworkflows.ObjectWorkflowHistoryEntry:content_id']),
|
||||
('from_state', orm['ietfworkflows.ObjectWorkflowHistoryEntry:from_state']),
|
||||
('to_state', orm['ietfworkflows.ObjectWorkflowHistoryEntry:to_state']),
|
||||
('transition_date', orm['ietfworkflows.ObjectWorkflowHistoryEntry:transition_date']),
|
||||
('comment', orm['ietfworkflows.ObjectWorkflowHistoryEntry:comment']),
|
||||
))
|
||||
db.send_create_signal('ietfworkflows', ['ObjectWorkflowHistoryEntry'])
|
||||
|
||||
# Adding model 'ObjectAnnotationTagHistoryEntry'
|
||||
db.create_table('ietfworkflows_objectannotationtaghistoryentry', (
|
||||
('id', orm['ietfworkflows.ObjectAnnotationTagHistoryEntry:id']),
|
||||
('content_type', orm['ietfworkflows.ObjectAnnotationTagHistoryEntry:content_type']),
|
||||
('content_id', orm['ietfworkflows.ObjectAnnotationTagHistoryEntry:content_id']),
|
||||
('setted', orm['ietfworkflows.ObjectAnnotationTagHistoryEntry:setted']),
|
||||
('unsetted', orm['ietfworkflows.ObjectAnnotationTagHistoryEntry:unsetted']),
|
||||
('change_date', orm['ietfworkflows.ObjectAnnotationTagHistoryEntry:change_date']),
|
||||
('comment', orm['ietfworkflows.ObjectAnnotationTagHistoryEntry:comment']),
|
||||
))
|
||||
db.send_create_signal('ietfworkflows', ['ObjectAnnotationTagHistoryEntry'])
|
||||
|
||||
# Adding model 'AnnotationTag'
|
||||
db.create_table('ietfworkflows_annotationtag', (
|
||||
('id', orm['ietfworkflows.AnnotationTag:id']),
|
||||
('name', orm['ietfworkflows.AnnotationTag:name']),
|
||||
('workflow', orm['ietfworkflows.AnnotationTag:workflow']),
|
||||
('permission', orm['ietfworkflows.AnnotationTag:permission']),
|
||||
))
|
||||
db.send_create_signal('ietfworkflows', ['AnnotationTag'])
|
||||
|
||||
# Adding model 'AnnotationTagObjectRelation'
|
||||
db.create_table('ietfworkflows_annotationtagobjectrelation', (
|
||||
('id', orm['ietfworkflows.AnnotationTagObjectRelation:id']),
|
||||
('content_type', orm['ietfworkflows.AnnotationTagObjectRelation:content_type']),
|
||||
('content_id', orm['ietfworkflows.AnnotationTagObjectRelation:content_id']),
|
||||
('annotation_tag', orm['ietfworkflows.AnnotationTagObjectRelation:annotation_tag']),
|
||||
))
|
||||
db.send_create_signal('ietfworkflows', ['AnnotationTagObjectRelation'])
|
||||
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Deleting model 'WGWorkflow'
|
||||
db.delete_table('ietfworkflows_wgworkflow')
|
||||
|
||||
# Deleting model 'ObjectWorkflowHistoryEntry'
|
||||
db.delete_table('ietfworkflows_objectworkflowhistoryentry')
|
||||
|
||||
# Deleting model 'ObjectAnnotationTagHistoryEntry'
|
||||
db.delete_table('ietfworkflows_objectannotationtaghistoryentry')
|
||||
|
||||
# Deleting model 'AnnotationTag'
|
||||
db.delete_table('ietfworkflows_annotationtag')
|
||||
|
||||
# Deleting model 'AnnotationTagObjectRelation'
|
||||
db.delete_table('ietfworkflows_annotationtagobjectrelation')
|
||||
|
||||
|
||||
|
||||
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'})
|
||||
},
|
||||
'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': {
|
||||
'change_date': ('django.db.models.fields.DateTimeField', [], {}),
|
||||
'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': "'annotation_tags_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'setted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'unsetted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
'ietfworkflows.objectworkflowhistoryentry': {
|
||||
'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']"}),
|
||||
'from_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'to_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'transition_date': ('django.db.models.fields.DateTimeField', [], {})
|
||||
},
|
||||
'ietfworkflows.wgworkflow': {
|
||||
'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.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']
|
|
@ -0,0 +1,107 @@
|
|||
|
||||
from south.db import db
|
||||
from django.db import models
|
||||
from ietf.ietfworkflows.models import *
|
||||
|
||||
class Migration:
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Adding ManyToManyField 'WGWorkflow.selected_tags'
|
||||
db.create_table('ietfworkflows_wgworkflow_selected_tags', (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('wgworkflow', models.ForeignKey(orm.WGWorkflow, null=False)),
|
||||
('annotationtag', models.ForeignKey(orm.AnnotationTag, null=False))
|
||||
))
|
||||
|
||||
# Adding ManyToManyField 'WGWorkflow.selected_states'
|
||||
db.create_table('ietfworkflows_wgworkflow_selected_states', (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('wgworkflow', models.ForeignKey(orm.WGWorkflow, null=False)),
|
||||
('state', models.ForeignKey(orm['workflows.State'], null=False))
|
||||
))
|
||||
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Dropping ManyToManyField 'WGWorkflow.selected_tags'
|
||||
db.delete_table('ietfworkflows_wgworkflow_selected_tags')
|
||||
|
||||
# Dropping ManyToManyField 'WGWorkflow.selected_states'
|
||||
db.delete_table('ietfworkflows_wgworkflow_selected_states')
|
||||
|
||||
|
||||
|
||||
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'})
|
||||
},
|
||||
'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': {
|
||||
'change_date': ('django.db.models.fields.DateTimeField', [], {}),
|
||||
'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': "'annotation_tags_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'setted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'unsetted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
'ietfworkflows.objectworkflowhistoryentry': {
|
||||
'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']"}),
|
||||
'from_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'to_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'transition_date': ('django.db.models.fields.DateTimeField', [], {})
|
||||
},
|
||||
'ietfworkflows.wgworkflow': {
|
||||
'selected_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['workflows.State']"}),
|
||||
'selected_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['ietfworkflows.AnnotationTag']"}),
|
||||
'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.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']
|
119
ietf/ietfworkflows/migrations/0003_add_person_to_history.py
Normal file
119
ietf/ietfworkflows/migrations/0003_add_person_to_history.py
Normal file
|
@ -0,0 +1,119 @@
|
|||
|
||||
from south.db import db
|
||||
from django.db import models
|
||||
from ietf.ietfworkflows.models import *
|
||||
|
||||
class Migration:
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Adding field 'ObjectWorkflowHistoryEntry.person'
|
||||
db.add_column('ietfworkflows_objectworkflowhistoryentry', 'person', orm['ietfworkflows.objectworkflowhistoryentry:person'])
|
||||
|
||||
# Adding field 'ObjectAnnotationTagHistoryEntry.person'
|
||||
db.add_column('ietfworkflows_objectannotationtaghistoryentry', 'person', orm['ietfworkflows.objectannotationtaghistoryentry:person'])
|
||||
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Deleting field 'ObjectWorkflowHistoryEntry.person'
|
||||
db.delete_column('ietfworkflows_objectworkflowhistoryentry', 'person_id')
|
||||
|
||||
# Deleting field 'ObjectAnnotationTagHistoryEntry.person'
|
||||
db.delete_column('ietfworkflows_objectannotationtaghistoryentry', 'person_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.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': {
|
||||
'change_date': ('django.db.models.fields.DateTimeField', [], {}),
|
||||
'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': "'annotation_tags_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}),
|
||||
'setted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'unsetted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
'ietfworkflows.objectworkflowhistoryentry': {
|
||||
'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']"}),
|
||||
'from_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}),
|
||||
'to_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'transition_date': ('django.db.models.fields.DateTimeField', [], {})
|
||||
},
|
||||
'ietfworkflows.wgworkflow': {
|
||||
'selected_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['workflows.State']", 'symmetrical': 'False'}),
|
||||
'selected_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['ietfworkflows.AnnotationTag']", 'symmetrical': 'False'}),
|
||||
'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', [], {'symmetrical': 'False', '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', [], {'symmetrical': 'False', 'to': "orm['workflows.Transition']", 'null': 'True', 'blank': 'True'}),
|
||||
'workflow': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'states'", 'to': "orm['workflows.Workflow']"})
|
||||
},
|
||||
'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']
|
132
ietf/ietfworkflows/migrations/0004_add_object_state_dates.py
Normal file
132
ietf/ietfworkflows/migrations/0004_add_object_state_dates.py
Normal file
|
@ -0,0 +1,132 @@
|
|||
|
||||
from south.db import db
|
||||
from django.db import models
|
||||
from ietf.ietfworkflows.models import *
|
||||
|
||||
class Migration:
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Adding model 'StateObjectRelationMetadata'
|
||||
db.create_table('ietfworkflows_stateobjectrelationmetadata', (
|
||||
('id', orm['ietfworkflows.stateobjectrelationmetadata:id']),
|
||||
('relation', orm['ietfworkflows.stateobjectrelationmetadata:relation']),
|
||||
('from_date', orm['ietfworkflows.stateobjectrelationmetadata:from_date']),
|
||||
('estimated_date', orm['ietfworkflows.stateobjectrelationmetadata:estimated_date']),
|
||||
))
|
||||
db.send_create_signal('ietfworkflows', ['StateObjectRelationMetadata'])
|
||||
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Deleting model 'StateObjectRelationMetadata'
|
||||
db.delete_table('ietfworkflows_stateobjectrelationmetadata')
|
||||
|
||||
|
||||
|
||||
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.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': {
|
||||
'change_date': ('django.db.models.fields.DateTimeField', [], {}),
|
||||
'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': "'annotation_tags_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}),
|
||||
'setted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'unsetted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
'ietfworkflows.objectworkflowhistoryentry': {
|
||||
'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']"}),
|
||||
'from_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}),
|
||||
'to_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'transition_date': ('django.db.models.fields.DateTimeField', [], {})
|
||||
},
|
||||
'ietfworkflows.stateobjectrelationmetadata': {
|
||||
'estimated_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'from_date': ('django.db.models.fields.DateTimeField', [], {}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'relation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.StateObjectRelation']"})
|
||||
},
|
||||
'ietfworkflows.wgworkflow': {
|
||||
'selected_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['workflows.State']", 'symmetrical': 'False'}),
|
||||
'selected_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['ietfworkflows.AnnotationTag']", 'symmetrical': 'False'}),
|
||||
'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', [], {'symmetrical': 'False', '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', [], {'symmetrical': 'False', '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']
|
209
ietf/ietfworkflows/migrations/0005_add_streams.py
Normal file
209
ietf/ietfworkflows/migrations/0005_add_streams.py
Normal file
|
@ -0,0 +1,209 @@
|
|||
|
||||
from south.db import db
|
||||
from django.db import models
|
||||
from ietf.ietfworkflows.models import *
|
||||
|
||||
class Migration:
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Adding model 'StreamedID'
|
||||
db.create_table('ietfworkflows_streamedid', (
|
||||
('id', orm['ietfworkflows.streamedid:id']),
|
||||
('draft', orm['ietfworkflows.streamedid:draft']),
|
||||
('stream', orm['ietfworkflows.streamedid:stream']),
|
||||
))
|
||||
db.send_create_signal('ietfworkflows', ['StreamedID'])
|
||||
|
||||
# Adding model 'Stream'
|
||||
db.create_table('ietfworkflows_stream', (
|
||||
('id', orm['ietfworkflows.stream:id']),
|
||||
('name', orm['ietfworkflows.stream:name']),
|
||||
('with_groups', orm['ietfworkflows.stream:with_groups']),
|
||||
('group_model', orm['ietfworkflows.stream:group_model']),
|
||||
('group_chair_model', orm['ietfworkflows.stream:group_chair_model']),
|
||||
('workflow', orm['ietfworkflows.stream:workflow']),
|
||||
))
|
||||
db.send_create_signal('ietfworkflows', ['Stream'])
|
||||
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Deleting model 'StreamedID'
|
||||
db.delete_table('ietfworkflows_streamedid')
|
||||
|
||||
# Deleting model 'Stream'
|
||||
db.delete_table('ietfworkflows_stream')
|
||||
|
||||
|
||||
|
||||
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', [], {'to': "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': {
|
||||
'change_date': ('django.db.models.fields.DateTimeField', [], {}),
|
||||
'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': "'annotation_tags_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}),
|
||||
'setted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'unsetted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
'ietfworkflows.objectworkflowhistoryentry': {
|
||||
'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']"}),
|
||||
'from_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}),
|
||||
'to_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'transition_date': ('django.db.models.fields.DateTimeField', [], {})
|
||||
},
|
||||
'ietfworkflows.stateobjectrelationmetadata': {
|
||||
'estimated_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'from_date': ('django.db.models.fields.DateTimeField', [], {}),
|
||||
'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']"})
|
||||
},
|
||||
'ietfworkflows.wgworkflow': {
|
||||
'selected_states': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['workflows.State']", 'null': 'True', 'blank': 'True'}),
|
||||
'selected_tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', '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', [], {'symmetrical': 'False', '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', [], {'symmetrical': 'False', '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']
|
198
ietf/ietfworkflows/migrations/0006_add_group_to_streamed_id.py
Normal file
198
ietf/ietfworkflows/migrations/0006_add_group_to_streamed_id.py
Normal file
|
@ -0,0 +1,198 @@
|
|||
|
||||
from south.db import db
|
||||
from django.db import models
|
||||
from ietf.ietfworkflows.models import *
|
||||
|
||||
class Migration:
|
||||
|
||||
def forwards(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'])
|
||||
|
||||
|
||||
|
||||
def backwards(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')
|
||||
|
||||
|
||||
|
||||
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', [], {'to': "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': {
|
||||
'change_date': ('django.db.models.fields.DateTimeField', [], {}),
|
||||
'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': "'annotation_tags_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}),
|
||||
'setted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'unsetted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
'ietfworkflows.objectworkflowhistoryentry': {
|
||||
'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']"}),
|
||||
'from_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}),
|
||||
'to_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'transition_date': ('django.db.models.fields.DateTimeField', [], {})
|
||||
},
|
||||
'ietfworkflows.stateobjectrelationmetadata': {
|
||||
'estimated_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'from_date': ('django.db.models.fields.DateTimeField', [], {}),
|
||||
'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': {
|
||||
'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'streamed_id'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}),
|
||||
'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']"})
|
||||
},
|
||||
'ietfworkflows.wgworkflow': {
|
||||
'selected_states': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['workflows.State']", 'null': 'True', 'blank': 'True'}),
|
||||
'selected_tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', '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', [], {'symmetrical': 'False', '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', [], {'symmetrical': 'False', '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']
|
194
ietf/ietfworkflows/migrations/0007_do_stream_optional.py
Normal file
194
ietf/ietfworkflows/migrations/0007_do_stream_optional.py
Normal file
|
@ -0,0 +1,194 @@
|
|||
|
||||
from south.db import db
|
||||
from django.db import models
|
||||
from ietf.ietfworkflows.models import *
|
||||
|
||||
class Migration:
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Changing field 'StreamedID.stream'
|
||||
# (to signature: django.db.models.fields.related.ForeignKey(to=orm['ietfworkflows.Stream'], null=True, blank=True))
|
||||
db.alter_column('ietfworkflows_streamedid', 'stream_id', orm['ietfworkflows.streamedid:stream'])
|
||||
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Changing field 'StreamedID.stream'
|
||||
# (to signature: django.db.models.fields.related.ForeignKey(to=orm['ietfworkflows.Stream']))
|
||||
db.alter_column('ietfworkflows_streamedid', 'stream_id', orm['ietfworkflows.streamedid:stream'])
|
||||
|
||||
|
||||
|
||||
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', [], {'to': "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': {
|
||||
'change_date': ('django.db.models.fields.DateTimeField', [], {}),
|
||||
'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': "'annotation_tags_history'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}),
|
||||
'setted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'unsetted': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
'ietfworkflows.objectworkflowhistoryentry': {
|
||||
'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']"}),
|
||||
'from_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}),
|
||||
'to_state': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'transition_date': ('django.db.models.fields.DateTimeField', [], {})
|
||||
},
|
||||
'ietfworkflows.stateobjectrelationmetadata': {
|
||||
'estimated_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'from_date': ('django.db.models.fields.DateTimeField', [], {}),
|
||||
'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': {
|
||||
'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'streamed_id'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}),
|
||||
'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', [], {'symmetrical': 'False', 'to': "orm['workflows.State']", 'null': 'True', 'blank': 'True'}),
|
||||
'selected_tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', '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', [], {'symmetrical': 'False', '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', [], {'symmetrical': 'False', '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']
|
267
ietf/ietfworkflows/migrations/0008_refactor_history_entries.py
Normal file
267
ietf/ietfworkflows/migrations/0008_refactor_history_entries.py
Normal file
|
@ -0,0 +1,267 @@
|
|||
|
||||
from south.db import db
|
||||
from django.db import models
|
||||
from ietf.ietfworkflows.models import *
|
||||
|
||||
class Migration:
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Deleting model 'objectworkflowhistoryentry'
|
||||
db.delete_table('ietfworkflows_objectworkflowhistoryentry')
|
||||
|
||||
# Deleting model 'objectannotationtaghistoryentry'
|
||||
db.delete_table('ietfworkflows_objectannotationtaghistoryentry')
|
||||
|
||||
# Adding model 'ObjectAnnotationTagHistoryEntry'
|
||||
db.create_table('ietfworkflows_objectannotationtaghistoryentry', (
|
||||
('objecthistoryentry_ptr', orm['ietfworkflows.objectannotationtaghistoryentry:objecthistoryentry_ptr']),
|
||||
('setted', orm['ietfworkflows.objectannotationtaghistoryentry:setted']),
|
||||
('unsetted', orm['ietfworkflows.objectannotationtaghistoryentry:unsetted']),
|
||||
))
|
||||
db.send_create_signal('ietfworkflows', ['ObjectAnnotationTagHistoryEntry'])
|
||||
|
||||
# Adding model 'ObjectHistoryEntry'
|
||||
db.create_table('ietfworkflows_objecthistoryentry', (
|
||||
('id', orm['ietfworkflows.objecthistoryentry:id']),
|
||||
('content_type', orm['ietfworkflows.objecthistoryentry:content_type']),
|
||||
('content_id', orm['ietfworkflows.objecthistoryentry:content_id']),
|
||||
('date', orm['ietfworkflows.objecthistoryentry:date']),
|
||||
('comment', orm['ietfworkflows.objecthistoryentry:comment']),
|
||||
('person', orm['ietfworkflows.objecthistoryentry:person']),
|
||||
))
|
||||
db.send_create_signal('ietfworkflows', ['ObjectHistoryEntry'])
|
||||
|
||||
# Adding model 'ObjectStreamHistoryEntry'
|
||||
db.create_table('ietfworkflows_objectstreamhistoryentry', (
|
||||
('objecthistoryentry_ptr', orm['ietfworkflows.objectstreamhistoryentry:objecthistoryentry_ptr']),
|
||||
('from_stream', orm['ietfworkflows.objectstreamhistoryentry:from_stream']),
|
||||
('to_stream', orm['ietfworkflows.objectstreamhistoryentry:to_stream']),
|
||||
))
|
||||
db.send_create_signal('ietfworkflows', ['ObjectStreamHistoryEntry'])
|
||||
|
||||
# Adding model 'ObjectWorkflowHistoryEntry'
|
||||
db.create_table('ietfworkflows_objectworkflowhistoryentry', (
|
||||
('objecthistoryentry_ptr', orm['ietfworkflows.objectworkflowhistoryentry:objecthistoryentry_ptr']),
|
||||
('from_state', orm['ietfworkflows.objectworkflowhistoryentry:from_state']),
|
||||
('to_state', orm['ietfworkflows.objectworkflowhistoryentry:to_state']),
|
||||
))
|
||||
db.send_create_signal('ietfworkflows', ['ObjectWorkflowHistoryEntry'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Deleting model 'ObjectAnnotationTagHistoryEntry'
|
||||
db.delete_table('ietfworkflows_objectannotationtaghistoryentry')
|
||||
|
||||
# Deleting model 'ObjectHistoryEntry'
|
||||
db.delete_table('ietfworkflows_objecthistoryentry')
|
||||
|
||||
# Deleting model 'ObjectStreamHistoryEntry'
|
||||
db.delete_table('ietfworkflows_objectstreamhistoryentry')
|
||||
|
||||
# Deleting model 'ObjectWorkflowHistoryEntry'
|
||||
db.delete_table('ietfworkflows_objectworkflowhistoryentry')
|
||||
|
||||
# Adding model 'objectworkflowhistoryentry'
|
||||
db.create_table('ietfworkflows_objectworkflowhistoryentry', (
|
||||
('comment', orm['ietfworkflows.objectworkflowhistoryentry:comment']),
|
||||
('from_state', orm['ietfworkflows.objectworkflowhistoryentry:from_state']),
|
||||
('to_state', orm['ietfworkflows.objectworkflowhistoryentry:to_state']),
|
||||
('content_type', orm['ietfworkflows.objectworkflowhistoryentry:content_type']),
|
||||
('person', orm['ietfworkflows.objectworkflowhistoryentry:person']),
|
||||
('content_id', orm['ietfworkflows.objectworkflowhistoryentry:content_id']),
|
||||
('id', orm['ietfworkflows.objectworkflowhistoryentry:id']),
|
||||
('transition_date', orm['ietfworkflows.objectworkflowhistoryentry:transition_date']),
|
||||
))
|
||||
db.send_create_signal('ietfworkflows', ['objectworkflowhistoryentry'])
|
||||
|
||||
# Adding model 'objectannotationtaghistoryentry'
|
||||
db.create_table('ietfworkflows_objectannotationtaghistoryentry', (
|
||||
('comment', orm['ietfworkflows.objectworkflowhistoryentry:comment']),
|
||||
('person', orm['ietfworkflows.objectworkflowhistoryentry:person']),
|
||||
('unsetted', orm['ietfworkflows.objectworkflowhistoryentry:unsetted']),
|
||||
('content_type', orm['ietfworkflows.objectworkflowhistoryentry:content_type']),
|
||||
('change_date', orm['ietfworkflows.objectworkflowhistoryentry:change_date']),
|
||||
('setted', orm['ietfworkflows.objectworkflowhistoryentry:setted']),
|
||||
('content_id', orm['ietfworkflows.objectworkflowhistoryentry:content_id']),
|
||||
('id', orm['ietfworkflows.objectworkflowhistoryentry:id']),
|
||||
))
|
||||
db.send_create_signal('ietfworkflows', ['objectannotationtaghistoryentry'])
|
||||
|
||||
|
||||
|
||||
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', [], {'to': "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.stateobjectrelationmetadata': {
|
||||
'estimated_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'from_date': ('django.db.models.fields.DateTimeField', [], {}),
|
||||
'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': {
|
||||
'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'streamed_id'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}),
|
||||
'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', [], {'symmetrical': 'False', 'to': "orm['workflows.State']", 'null': 'True', 'blank': 'True'}),
|
||||
'selected_tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', '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', [], {'symmetrical': 'False', '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', [], {'symmetrical': 'False', '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']
|
197
ietf/ietfworkflows/migrations/0009_allow_null_in_from_date.py
Normal file
197
ietf/ietfworkflows/migrations/0009_allow_null_in_from_date.py
Normal file
|
@ -0,0 +1,197 @@
|
|||
|
||||
from south.db import db
|
||||
from django.db import models
|
||||
from ietf.ietfworkflows.models import *
|
||||
|
||||
class Migration:
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Changing field 'StateObjectRelationMetadata.from_date'
|
||||
# (to signature: django.db.models.fields.DateTimeField(null=True, blank=True))
|
||||
db.alter_column('ietfworkflows_stateobjectrelationmetadata', 'from_date', orm['ietfworkflows.stateobjectrelationmetadata:from_date'])
|
||||
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Changing field 'StateObjectRelationMetadata.from_date'
|
||||
# (to signature: django.db.models.fields.DateTimeField())
|
||||
db.alter_column('ietfworkflows_stateobjectrelationmetadata', 'from_date', orm['ietfworkflows.stateobjectrelationmetadata:from_date'])
|
||||
|
||||
|
||||
|
||||
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', [], {'to': "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.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': {
|
||||
'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'streamed_id'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}),
|
||||
'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', [], {'symmetrical': 'False', 'to': "orm['workflows.State']", 'null': 'True', 'blank': 'True'}),
|
||||
'selected_tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', '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', [], {'symmetrical': 'False', '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', [], {'symmetrical': 'False', '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']
|
207
ietf/ietfworkflows/migrations/0010_add_state_definitions.py
Normal file
207
ietf/ietfworkflows/migrations/0010_add_state_definitions.py
Normal file
|
@ -0,0 +1,207 @@
|
|||
|
||||
from south.db import db
|
||||
from django.db import models
|
||||
from ietf.ietfworkflows.models import *
|
||||
|
||||
class Migration:
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Adding model 'StateDescription'
|
||||
db.create_table('ietfworkflows_statedescription', (
|
||||
('id', orm['ietfworkflows.statedescription:id']),
|
||||
('state', orm['ietfworkflows.statedescription:state']),
|
||||
('definition', orm['ietfworkflows.statedescription:definition']),
|
||||
('order', orm['ietfworkflows.statedescription:order']),
|
||||
))
|
||||
db.send_create_signal('ietfworkflows', ['StateDescription'])
|
||||
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Deleting model 'StateDescription'
|
||||
db.delete_table('ietfworkflows_statedescription')
|
||||
|
||||
|
||||
|
||||
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', [], {'to': "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': {
|
||||
'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'streamed_id'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}),
|
||||
'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']
|
0
ietf/ietfworkflows/migrations/__init__.py
Normal file
0
ietf/ietfworkflows/migrations/__init__.py
Normal file
157
ietf/ietfworkflows/models.py
Normal file
157
ietf/ietfworkflows/models.py
Normal file
|
@ -0,0 +1,157 @@
|
|||
from django.contrib.contenttypes import generic
|
||||
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 workflows.models import Workflow, State, StateObjectRelation
|
||||
from permissions.models import Permission
|
||||
|
||||
|
||||
class ObjectHistoryEntry(models.Model):
|
||||
content_type = models.ForeignKey(ContentType, verbose_name=_(u"Content type"), related_name="workflow_history", blank=True, null=True)
|
||||
content_id = models.PositiveIntegerField(_(u"Content id"), blank=True, null=True)
|
||||
content = generic.GenericForeignKey(ct_field="content_type", fk_field="content_id")
|
||||
|
||||
date = models.DateTimeField(_('Date'), auto_now_add=True)
|
||||
comment = models.TextField(_('Comment'))
|
||||
person = models.ForeignKey(PersonOrOrgInfo)
|
||||
|
||||
class Meta:
|
||||
ordering = ('-date', )
|
||||
|
||||
def get_real_instance(self):
|
||||
if hasattr(self, '_real_instance'):
|
||||
return self._real_instance
|
||||
for i in ('objectworkflowhistoryentry', 'objectannotationtaghistoryentry', 'objectstreamhistoryentry'):
|
||||
try:
|
||||
real_instance = getattr(self, i, None)
|
||||
if real_instance:
|
||||
self._real_instance = real_instance
|
||||
return real_instance
|
||||
except models.ObjectDoesNotExist:
|
||||
continue
|
||||
self._real_instance = self
|
||||
return self
|
||||
|
||||
|
||||
class ObjectWorkflowHistoryEntry(ObjectHistoryEntry):
|
||||
from_state = models.CharField(_('From state'), max_length=100)
|
||||
to_state = models.CharField(_('To state'), max_length=100)
|
||||
|
||||
def describe_change(self):
|
||||
html = '<p class="describe_state_change">'
|
||||
html += 'Changed state <i>%s</i> to <b>%s</b>' % (self.from_state, self.to_state)
|
||||
html += '</p>'
|
||||
return html
|
||||
|
||||
|
||||
class ObjectAnnotationTagHistoryEntry(ObjectHistoryEntry):
|
||||
setted = models.TextField(_('Setted tags'), blank=True, null=True)
|
||||
unsetted = models.TextField(_('Unsetted tags'), blank=True, null=True)
|
||||
|
||||
def describe_change(self):
|
||||
html = ''
|
||||
if self.setted:
|
||||
html += '<p class="describe_tags_set">'
|
||||
html += 'Annotation tags set: '
|
||||
html += self.setted
|
||||
html += '</p>'
|
||||
if self.unsetted:
|
||||
html += '<p class="describe_tags_reset">'
|
||||
html += 'Annotation tags reset: '
|
||||
html += self.unsetted
|
||||
html += '</p>'
|
||||
return html
|
||||
|
||||
|
||||
class ObjectStreamHistoryEntry(ObjectHistoryEntry):
|
||||
from_stream = models.TextField(_('From stream'), blank=True, null=True)
|
||||
to_stream = models.TextField(_('To stream'), blank=True, null=True)
|
||||
|
||||
def describe_change(self):
|
||||
html = '<p class="describe_stream_change">'
|
||||
html += 'Changed doc from stream <i>%s</i> to <b>%s</b>' % (self.from_stream, self.to_stream)
|
||||
html += '</p>'
|
||||
return html
|
||||
|
||||
|
||||
class StateDescription(models.Model):
|
||||
state = models.ForeignKey(State)
|
||||
definition = models.TextField()
|
||||
order = models.PositiveIntegerField()
|
||||
|
||||
class Meta:
|
||||
ordering = ('order', )
|
||||
|
||||
def __unicode__(self):
|
||||
return unicode(self.state)
|
||||
|
||||
|
||||
class AnnotationTag(models.Model):
|
||||
name = models.CharField(_(u"Name"), max_length=100)
|
||||
workflow = models.ForeignKey(Workflow, verbose_name=_(u"Workflow"), related_name="annotation_tags")
|
||||
permission = models.ForeignKey(Permission, verbose_name=_(u"Permission"), blank=True, null=True)
|
||||
|
||||
class Meta:
|
||||
ordering = ('name', )
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class AnnotationTagObjectRelation(models.Model):
|
||||
content_type = models.ForeignKey(ContentType, verbose_name=_(u"Content type"), related_name="annotation_tags", blank=True, null=True)
|
||||
content_id = models.PositiveIntegerField(_(u"Content id"), blank=True, null=True)
|
||||
content = generic.GenericForeignKey(ct_field="content_type", fk_field="content_id")
|
||||
|
||||
annotation_tag = models.ForeignKey(AnnotationTag, verbose_name=_(u"Annotation tag"))
|
||||
|
||||
|
||||
class StateObjectRelationMetadata(models.Model):
|
||||
relation = models.ForeignKey(StateObjectRelation)
|
||||
from_date = models.DateTimeField(_('Initial date'), blank=True, null=True)
|
||||
estimated_date = models.DateTimeField(_('Estimated date'), blank=True, null=True)
|
||||
|
||||
|
||||
class WGWorkflow(Workflow):
|
||||
selected_states = models.ManyToManyField(State, blank=True, null=True)
|
||||
selected_tags = models.ManyToManyField(AnnotationTag, blank=True, null=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = 'IETF Workflow'
|
||||
verbose_name_plural = 'IETF Workflows'
|
||||
|
||||
def get_tags(self):
|
||||
tags = self.annotation_tags.all()
|
||||
if tags.count():
|
||||
return tags
|
||||
else:
|
||||
return self.selected_tags.all()
|
||||
|
||||
def get_states(self):
|
||||
states = self.states.all()
|
||||
if states.count():
|
||||
return states
|
||||
else:
|
||||
return self.selected_states.all()
|
||||
|
||||
|
||||
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)
|
||||
workflow = models.ForeignKey(WGWorkflow)
|
||||
|
||||
def __unicode__(self):
|
||||
return u'%s stream' % self.name
|
||||
|
||||
|
||||
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")
|
114
ietf/ietfworkflows/streams.py
Normal file
114
ietf/ietfworkflows/streams.py
Normal file
|
@ -0,0 +1,114 @@
|
|||
from django.db import models
|
||||
|
||||
from ietf.idrfc.idrfc_wrapper import IdRfcWrapper, IdWrapper
|
||||
from ietf.ietfworkflows.models import StreamedID, Stream
|
||||
|
||||
|
||||
def get_streamed_draft(draft):
|
||||
if not draft:
|
||||
return None
|
||||
try:
|
||||
return draft.streamedid
|
||||
except StreamedID.DoesNotExist:
|
||||
return None
|
||||
|
||||
|
||||
def get_stream_from_draft(draft):
|
||||
streamedid = get_streamed_draft(draft)
|
||||
if streamedid:
|
||||
return streamedid.stream
|
||||
return False
|
||||
|
||||
|
||||
def get_stream_by_name(stream_name):
|
||||
try:
|
||||
return Stream.objects.get(name=stream_name)
|
||||
except Stream.DoesNotExist:
|
||||
return None
|
||||
|
||||
|
||||
def get_stream_from_id(stream_id):
|
||||
try:
|
||||
return Stream.objects.get(id=stream_id)
|
||||
except Stream.DoesNotExist:
|
||||
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 = StreamedID.objects.create(stream=stream, draft=draft)
|
||||
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
|
||||
|
||||
|
||||
def get_stream_from_wrapper(idrfc_wrapper):
|
||||
idwrapper = None
|
||||
if isinstance(idrfc_wrapper, IdRfcWrapper):
|
||||
idwrapper = idrfc_wrapper.id
|
||||
elif isinstance(idrfc_wrapper, IdWrapper):
|
||||
idwrapper = idrfc_wrapper
|
||||
if not idwrapper:
|
||||
return None
|
||||
draft = idwrapper._draft
|
||||
stream = get_stream_from_draft(draft)
|
||||
if stream == False:
|
||||
stream_id = idwrapper.stream_id()
|
||||
stream = get_stream_from_id(stream_id)
|
||||
_set_stream_automatically(draft, stream)
|
||||
return stream
|
||||
else:
|
||||
return stream
|
||||
return None
|
||||
|
||||
|
||||
def set_stream_for_draft(draft, stream):
|
||||
(streamed, created) = StreamedID.objects.get_or_create(draft=draft)
|
||||
if streamed.stream != stream:
|
||||
streamed.stream = stream
|
||||
streamed.group = None
|
||||
streamed.save()
|
||||
return streamed.stream
|
0
ietf/ietfworkflows/templatetags/__init__.py
Normal file
0
ietf/ietfworkflows/templatetags/__init__.py
Normal file
74
ietf/ietfworkflows/templatetags/ietf_streams.py
Normal file
74
ietf/ietfworkflows/templatetags/ietf_streams.py
Normal file
|
@ -0,0 +1,74 @@
|
|||
from django import template
|
||||
|
||||
from ietf.idrfc.idrfc_wrapper import IdRfcWrapper, IdWrapper
|
||||
from ietf.ietfworkflows.utils import (get_workflow_for_draft,
|
||||
get_state_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)
|
||||
|
||||
|
||||
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})
|
||||
if not stream:
|
||||
return data
|
||||
|
||||
idwrapper = None
|
||||
if isinstance(doc, IdRfcWrapper):
|
||||
idwrapper = doc.id
|
||||
elif isinstance(doc, IdWrapper):
|
||||
idwrapper = doc
|
||||
if not idwrapper:
|
||||
return data
|
||||
|
||||
draft = getattr(idwrapper, '_draft', None)
|
||||
if not draft:
|
||||
return data
|
||||
|
||||
workflow = get_workflow_for_draft(draft)
|
||||
state = get_state_for_draft(draft)
|
||||
|
||||
data.update({'workflow': workflow,
|
||||
'draft': draft,
|
||||
'state': state})
|
||||
|
||||
return data
|
||||
|
||||
|
||||
@register.inclusion_tag('ietfworkflows/workflow_history_entry.html', takes_context=True)
|
||||
def workflow_history_entry(context, entry):
|
||||
real_entry = entry.get_real_instance()
|
||||
return {'entry': real_entry,
|
||||
'entry_class': real_entry.__class__.__name__.lower()}
|
||||
|
||||
|
||||
@register.inclusion_tag('ietfworkflows/edit_actions.html', takes_context=True)
|
||||
def edit_actions(context, wrapper):
|
||||
request = context.get('request', None)
|
||||
user = request and request.user
|
||||
if not user:
|
||||
return {}
|
||||
idwrapper = None
|
||||
if isinstance(wrapper, IdRfcWrapper):
|
||||
idwrapper = wrapper.id
|
||||
elif isinstance(wrapper, IdWrapper):
|
||||
idwrapper = wrapper
|
||||
if not idwrapper:
|
||||
return None
|
||||
draft = idwrapper._draft
|
||||
return {
|
||||
'can_edit_state': can_edit_state(user, draft),
|
||||
'can_edit_stream': can_edit_stream(user, draft),
|
||||
'can_writeup': can_manage_writeup_of_a_document(user, draft),
|
||||
'can_shepherd': can_manage_shepherd_of_a_document(user, draft),
|
||||
'draft': draft,
|
||||
'doc': wrapper,
|
||||
}
|
9
ietf/ietfworkflows/urls.py
Normal file
9
ietf/ietfworkflows/urls.py
Normal file
|
@ -0,0 +1,9 @@
|
|||
# Copyright The IETF Trust 2008, All Rights Reserved
|
||||
|
||||
from django.conf.urls.defaults import patterns, url
|
||||
|
||||
urlpatterns = patterns('ietf.ietfworkflows.views',
|
||||
url(r'^(?P<name>[^/]+)/history/$', 'stream_history', name='stream_history'),
|
||||
url(r'^(?P<name>[^/]+)/edit/state/$', 'edit_state', name='edit_state'),
|
||||
url(r'^(?P<name>[^/]+)/edit/stream/$', 'edit_stream', name='edit_stream'),
|
||||
)
|
294
ietf/ietfworkflows/utils.py
Normal file
294
ietf/ietfworkflows/utils.py
Normal file
|
@ -0,0 +1,294 @@
|
|||
import copy
|
||||
import datetime
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.mail import EmailMessage
|
||||
from django.template.loader import render_to_string
|
||||
|
||||
from workflows.models import State, StateObjectRelation
|
||||
from workflows.utils import (get_workflow_for_object, set_workflow_for_object,
|
||||
get_state, set_state)
|
||||
|
||||
from ietf.ietfworkflows.streams import (get_streamed_draft, get_stream_from_draft,
|
||||
set_stream_for_draft)
|
||||
from ietf.ietfworkflows.models import (WGWorkflow, AnnotationTagObjectRelation,
|
||||
AnnotationTag, ObjectAnnotationTagHistoryEntry,
|
||||
ObjectHistoryEntry, StateObjectRelationMetadata,
|
||||
ObjectWorkflowHistoryEntry, ObjectStreamHistoryEntry)
|
||||
|
||||
|
||||
WAITING_WRITEUP = 'WG Consensus: Waiting for Write-Up'
|
||||
FOLLOWUP_TAG = 'Doc Shepherd Follow-up Underway'
|
||||
|
||||
|
||||
def get_default_workflow_for_wg():
|
||||
try:
|
||||
workflow = WGWorkflow.objects.get(name='Default WG Workflow')
|
||||
return workflow
|
||||
except WGWorkflow.DoesNotExist:
|
||||
return None
|
||||
|
||||
|
||||
def clone_transition(transition):
|
||||
new = copy.copy(transition)
|
||||
new.pk = None
|
||||
new.save()
|
||||
|
||||
# Reference original initial states
|
||||
for state in transition.states.all():
|
||||
new.states.add(state)
|
||||
return new
|
||||
|
||||
|
||||
def clone_workflow(workflow, name):
|
||||
new = WGWorkflow.objects.create(name=name, initial_state=workflow.initial_state)
|
||||
|
||||
# Reference default states
|
||||
for state in workflow.states.all():
|
||||
new.selected_states.add(state)
|
||||
|
||||
# Reference default annotation tags
|
||||
for tag in workflow.annotation_tags.all():
|
||||
new.selected_tags.add(tag)
|
||||
|
||||
# Reference cloned transitions
|
||||
for transition in workflow.transitions.all():
|
||||
new.transitions.add(clone_transition(transition))
|
||||
return new
|
||||
|
||||
|
||||
def get_workflow_for_wg(wg, default=None):
|
||||
workflow = get_workflow_for_object(wg)
|
||||
try:
|
||||
workflow = workflow and workflow.wgworkflow
|
||||
except WGWorkflow.DoesNotExist:
|
||||
workflow = None
|
||||
if not workflow:
|
||||
if default:
|
||||
workflow = default
|
||||
else:
|
||||
workflow = get_default_workflow_for_wg()
|
||||
if not workflow:
|
||||
return None
|
||||
workflow = clone_workflow(workflow, name='%s workflow' % wg)
|
||||
set_workflow_for_object(wg, workflow)
|
||||
return workflow
|
||||
|
||||
|
||||
def get_workflow_for_draft(draft):
|
||||
workflow = get_workflow_for_object(draft)
|
||||
try:
|
||||
workflow = workflow and workflow.wgworkflow
|
||||
except WGWorkflow.DoesNotExist:
|
||||
workflow = None
|
||||
if not workflow:
|
||||
streamed_draft = get_streamed_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:
|
||||
return None
|
||||
else:
|
||||
workflow = get_workflow_for_wg(streamed_draft.group, streamed_draft.stream.workflow)
|
||||
else:
|
||||
workflow = stream.workflow
|
||||
set_workflow_for_object(draft, workflow)
|
||||
return workflow
|
||||
|
||||
|
||||
def get_workflow_history_for_draft(draft, entry_type=None):
|
||||
ctype = ContentType.objects.get_for_model(draft)
|
||||
filter_param = {'content_type': ctype,
|
||||
'content_id': draft.pk}
|
||||
if entry_type:
|
||||
filter_param.update({'%s__isnull' % entry_type: False})
|
||||
history = ObjectHistoryEntry.objects.filter(**filter_param).\
|
||||
select_related('objectworkflowhistoryentry', 'objectannotationtaghistoryentry',
|
||||
'objectstreamhistoryentry')
|
||||
return history
|
||||
|
||||
|
||||
def get_annotation_tags_for_draft(draft):
|
||||
ctype = ContentType.objects.get_for_model(draft)
|
||||
tags = AnnotationTagObjectRelation.objects.filter(content_type=ctype, content_id=draft.pk)
|
||||
return tags
|
||||
|
||||
|
||||
def get_state_for_draft(draft):
|
||||
return get_state(draft)
|
||||
|
||||
|
||||
def get_state_by_name(state_name):
|
||||
try:
|
||||
return State.objects.get(name=state_name)
|
||||
except State.DoesNotExist:
|
||||
return None
|
||||
|
||||
|
||||
def get_annotation_tag_by_name(tag_name):
|
||||
try:
|
||||
return AnnotationTag.objects.get(name=tag_name)
|
||||
except AnnotationTag.DoesNotExist:
|
||||
return None
|
||||
|
||||
|
||||
def set_tag(obj, tag):
|
||||
ctype = ContentType.objects.get_for_model(obj)
|
||||
(relation, created) = AnnotationTagObjectRelation.objects.get_or_create(
|
||||
content_type=ctype,
|
||||
content_id=obj.pk,
|
||||
annotation_tag=tag)
|
||||
return relation
|
||||
|
||||
|
||||
def set_tag_by_name(obj, tag_name):
|
||||
try:
|
||||
tag = AnnotationTag.objects.get(name=tag_name)
|
||||
return set_tag(obj, tag)
|
||||
except AnnotationTag.DoesNotExist:
|
||||
return None
|
||||
|
||||
|
||||
def reset_tag(obj, tag):
|
||||
ctype = ContentType.objects.get_for_model(obj)
|
||||
try:
|
||||
tag_relation = AnnotationTagObjectRelation.objects.get(
|
||||
content_type=ctype,
|
||||
content_id=obj.pk,
|
||||
annotation_tag=tag)
|
||||
tag_relation.delete()
|
||||
return True
|
||||
except AnnotationTagObjectRelation.DoesNotExist:
|
||||
return False
|
||||
|
||||
|
||||
def reset_tag_by_name(obj, tag_name):
|
||||
try:
|
||||
tag = AnnotationTag.objects.get(name=tag_name)
|
||||
return reset_tag(obj, tag)
|
||||
except AnnotationTag.DoesNotExist:
|
||||
return False
|
||||
|
||||
|
||||
def set_state_for_draft(draft, state, estimated_date=None):
|
||||
workflow = get_workflow_for_draft(draft)
|
||||
if state in workflow.get_states():
|
||||
set_state(draft, state)
|
||||
relation = StateObjectRelation.objects.get(
|
||||
content_type=ContentType.objects.get_for_model(draft),
|
||||
content_id=draft.pk)
|
||||
metadata = StateObjectRelationMetadata.objects.get_or_create(relation=relation)[0]
|
||||
metadata.from_date = datetime.date.today()
|
||||
metadata.to_date = estimated_date
|
||||
metadata.save()
|
||||
return state
|
||||
return False
|
||||
|
||||
|
||||
def notify_entry(entry, template, extra_notify=[]):
|
||||
doc = entry.content
|
||||
wg = doc.group.ietfwg
|
||||
mail_list = set(['%s <%s>' % i.person.email() for i in wg.wgchair_set.all() if i.person.email()])
|
||||
mail_list = mail_list.union(['%s <%s>' % i.person.email() for i in wg.wgdelegate_set.all() if i.person.email()])
|
||||
mail_list = mail_list.union(['%s <%s>' % i.person.email() for i in doc.authors.all() if i.person.email()])
|
||||
mail_list = mail_list.union(extra_notify)
|
||||
mail_list = list(mail_list)
|
||||
|
||||
subject = 'Annotation tags have changed for draft %s' % doc
|
||||
body = render_to_string(template, {'doc': doc,
|
||||
'entry': entry,
|
||||
})
|
||||
mail = EmailMessage(subject=subject,
|
||||
body=body,
|
||||
to=mail_list,
|
||||
from_email=settings.DEFAULT_FROM_EMAIL)
|
||||
# Only send emails if we are not debug mode
|
||||
if not settings.DEBUG:
|
||||
mail.send()
|
||||
return mail
|
||||
|
||||
|
||||
def notify_tag_entry(entry, extra_notify=[]):
|
||||
return notify_entry(entry, 'ietfworkflows/annotation_tags_updated_mail.txt', extra_notify)
|
||||
|
||||
|
||||
def notify_state_entry(entry, extra_notify=[]):
|
||||
return notify_entry(entry, 'ietfworkflows/state_updated_mail.txt', extra_notify)
|
||||
|
||||
|
||||
def notify_stream_entry(entry, extra_notify=[]):
|
||||
return notify_entry(entry, 'ietfworkflows/stream_updated_mail.txt', extra_notify)
|
||||
|
||||
|
||||
def update_tags(obj, comment, person, set_tags=[], reset_tags=[], extra_notify=[]):
|
||||
ctype = ContentType.objects.get_for_model(obj)
|
||||
setted = []
|
||||
resetted = []
|
||||
for tag in set_tags:
|
||||
if isinstance(tag, basestring):
|
||||
if set_tag_by_name(obj, tag):
|
||||
setted.append(tag)
|
||||
else:
|
||||
if set_tag(obj, tag):
|
||||
setted.append(tag.name)
|
||||
for tag in reset_tags:
|
||||
if isinstance(tag, basestring):
|
||||
if reset_tag_by_name(obj, tag):
|
||||
resetted.append(tag)
|
||||
else:
|
||||
if reset_tag(obj, tag):
|
||||
resetted.append(tag.name)
|
||||
entry = ObjectAnnotationTagHistoryEntry.objects.create(
|
||||
content_type=ctype,
|
||||
content_id=obj.pk,
|
||||
setted=','.join(setted),
|
||||
unsetted=','.join(resetted),
|
||||
date=datetime.datetime.now(),
|
||||
comment=comment,
|
||||
person=person)
|
||||
notify_tag_entry(entry, extra_notify)
|
||||
|
||||
|
||||
def update_state(obj, comment, person, to_state, estimated_date=None, extra_notify=[]):
|
||||
ctype = ContentType.objects.get_for_model(obj)
|
||||
from_state = get_state_for_draft(obj)
|
||||
to_state = set_state_for_draft(obj, to_state, estimated_date)
|
||||
if not to_state:
|
||||
return False
|
||||
entry = ObjectWorkflowHistoryEntry.objects.create(
|
||||
content_type=ctype,
|
||||
content_id=obj.pk,
|
||||
from_state=from_state and from_state.name or '',
|
||||
to_state=to_state and to_state.name or '',
|
||||
date=datetime.datetime.now(),
|
||||
comment=comment,
|
||||
person=person)
|
||||
notify_state_entry(entry, extra_notify)
|
||||
|
||||
|
||||
def update_stream(obj, comment, person, to_stream, extra_notify=[]):
|
||||
ctype = ContentType.objects.get_for_model(obj)
|
||||
from_stream = get_stream_from_draft(obj)
|
||||
to_stream = set_stream_for_draft(obj, to_stream)
|
||||
entry = ObjectStreamHistoryEntry.objects.create(
|
||||
content_type=ctype,
|
||||
content_id=obj.pk,
|
||||
from_stream=from_stream and from_stream.name or '',
|
||||
to_stream=to_stream and to_stream.name or '',
|
||||
date=datetime.datetime.now(),
|
||||
comment=comment,
|
||||
person=person)
|
||||
notify_stream_entry(entry, extra_notify)
|
||||
|
||||
|
||||
def get_full_info_for_draft(draft):
|
||||
return dict(
|
||||
streamed=get_streamed_draft(draft),
|
||||
stream=get_stream_from_draft(draft),
|
||||
workflow=get_workflow_for_draft(draft),
|
||||
tags=[i.annotation_tag for i in get_annotation_tags_for_draft(draft)],
|
||||
state=get_state_for_draft(draft),
|
||||
shepherd=draft.shepherd,
|
||||
)
|
88
ietf/ietfworkflows/views.py
Normal file
88
ietf/ietfworkflows/views.py
Normal file
|
@ -0,0 +1,88 @@
|
|||
from django.http import HttpResponseRedirect, HttpResponseForbidden
|
||||
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.forms import (DraftTagsStateForm,
|
||||
DraftStreamForm,
|
||||
NoWorkflowStateForm)
|
||||
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)
|
||||
|
||||
|
||||
REDUCED_HISTORY_LEN = 20
|
||||
|
||||
|
||||
def stream_history(request, name):
|
||||
draft = get_object_or_404(InternetDraft, filename=name)
|
||||
streamed = get_streamed_draft(draft)
|
||||
stream = get_stream_from_draft(draft)
|
||||
workflow = get_workflow_for_draft(draft)
|
||||
tags = []
|
||||
if workflow:
|
||||
tags_setted = [i.annotation_tag.pk for i in get_annotation_tags_for_draft(draft)]
|
||||
for tag in workflow.get_tags():
|
||||
tag.setted = tag.pk in tags_setted
|
||||
tags.append(tag)
|
||||
state = get_state_for_draft(draft)
|
||||
history = get_workflow_history_for_draft(draft)
|
||||
show_more = False
|
||||
if history.count > REDUCED_HISTORY_LEN:
|
||||
show_more = True
|
||||
return render_to_response('ietfworkflows/stream_history.html',
|
||||
{'stream': stream,
|
||||
'streamed': streamed,
|
||||
'draft': draft,
|
||||
'tags': tags,
|
||||
'state': state,
|
||||
'workflow': workflow,
|
||||
'show_more': show_more,
|
||||
'history': history[:REDUCED_HISTORY_LEN],
|
||||
},
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
||||
def _edit_draft_stream(request, draft, form_class=DraftTagsStateForm):
|
||||
user = request.user
|
||||
workflow = get_workflow_for_draft(draft)
|
||||
if not workflow:
|
||||
form_class = NoWorkflowStateForm
|
||||
if request.method == 'POST':
|
||||
form = form_class(user=user, draft=draft, data=request.POST)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
return HttpResponseRedirect('.')
|
||||
else:
|
||||
form = form_class(user=user, draft=draft)
|
||||
state = get_state_for_draft(draft)
|
||||
stream = get_stream_from_draft(draft)
|
||||
history = get_workflow_history_for_draft(draft, 'objectworkflowhistoryentry')
|
||||
tags = get_annotation_tags_for_draft(draft)
|
||||
return render_to_response('ietfworkflows/state_edit.html',
|
||||
{'draft': draft,
|
||||
'state': state,
|
||||
'stream': stream,
|
||||
'workflow': workflow,
|
||||
'history': history,
|
||||
'tags': tags,
|
||||
'form': form,
|
||||
},
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
||||
def edit_state(request, name):
|
||||
draft = get_object_or_404(InternetDraft, filename=name)
|
||||
if not can_edit_state(request.user, draft):
|
||||
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)
|
|
@ -119,6 +119,8 @@ INSTALLED_APPS = (
|
|||
'django.contrib.admindocs',
|
||||
'django.contrib.humanize',
|
||||
'south',
|
||||
'workflows',
|
||||
'permissions',
|
||||
'ietf.announcements',
|
||||
'ietf.idindex',
|
||||
'ietf.idtracker',
|
||||
|
@ -133,6 +135,8 @@ INSTALLED_APPS = (
|
|||
'ietf.idrfc',
|
||||
'ietf.wginfo',
|
||||
'ietf.submit',
|
||||
'ietf.ietfworkflows',
|
||||
'ietf.wgchairs',
|
||||
)
|
||||
|
||||
INTERNAL_IPS = (
|
||||
|
@ -156,6 +160,9 @@ SERVER_MODE = 'development'
|
|||
# The name of the method to use to invoke the test suite
|
||||
TEST_RUNNER = 'ietf.utils.test_runner.run_tests'
|
||||
|
||||
# WG Chair configuration
|
||||
MAX_WG_DELEGATES = 3
|
||||
|
||||
# Override this in settings_local.py if needed
|
||||
# *_PATH variables ends with a slash/ .
|
||||
INTERNET_DRAFT_PATH = '/a/www/ietf-ftp/internet-drafts/'
|
||||
|
|
|
@ -32,26 +32,30 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
{% endcomment %}
|
||||
{% load ietf_filters %}
|
||||
{% load ietf_filters ietf_streams %}
|
||||
|
||||
{% block title %}{{ doc.draft_name_and_revision }}{% endblock %}
|
||||
{% block doc_meta_description %}{{ doc.title }} ({{info.type}}; {{doc.publication_date|date:"Y"}}){% endblock %}
|
||||
{% block doc_h1 %}{{ doc.title|escape }}<br/>{{ doc.draft_name_and_revision }}{% endblock %}
|
||||
|
||||
{% block doc_metatable %}
|
||||
<tr><td style="width:18ex;">Document type:</td><td>{{ info.type|escape }}
|
||||
{% with doc.replaces as r %}{% if r %}<br />Replaces {% filter urlize_ietf_docs %}{{ r|join:", "}}{% endfilter %}{% endif %}{% endwith %}
|
||||
</td></tr>
|
||||
<tr><td>Last updated:</td><td> {{ doc.publication_date|default:"(data missing)" }}</td></tr>
|
||||
<tr><td><a href="/idtracker/help/state/">State</>:</td><td>
|
||||
{{ doc.friendly_state|safe }}
|
||||
{% if doc.rfc_editor_state %}<br />RFC Editor State: <a href="http://www.rfc-editor.org/queue2.html#{{doc.draft_name}}">{{ doc.rfc_editor_state|escape }}</a>{% endif %}
|
||||
<tr><td>Document Stream:</td><td> {{ stream_info.stream.name|default:"No stream defined" }}</td></tr>
|
||||
<tr><td>I-D availability status:</td><td> {{ doc.draft_status }}
|
||||
{% ifequal doc.draft_status "Expired" %}
|
||||
{% if doc.resurrect_requested_by %}(resurrect requested by {{ doc.resurrect_requested_by }}){% endif %}
|
||||
{% endifequal %}
|
||||
{% with doc.replaces as r %}{% if r %}<br />Replaces {% filter urlize_ietf_docs %}{{ r|join:", "}}{% endfilter %}{% endif %}{% endwith %}
|
||||
</td></tr>
|
||||
<tr><td>Last updated:</td><td> {{ doc.publication_date|default:"(data missing)" }}</td></tr>
|
||||
<tr><td>IETF WG status:</td><td>{{ stream_info.state.name }} ({{ stream_info.streamed.group }})
|
||||
{% if stream_info.tags %}<br /><i>{% for tag in stream_info.tags %}{{ tag.name }}{% if not forloop.last %}, {% endif %}{% endfor %}{% endif %}
|
||||
</td></tr>
|
||||
<tr><td>Intended RFC status:</td><td>{% if doc.in_ietf_process %}{{ doc.ietf_process.intended_maturity_level|default:"-" }}{% else %}-{%endif%}</td></tr>
|
||||
<tr><td>Document shepherd:</td><td>{{ stream_info.shepherd }}</td></tr>
|
||||
<tr><td><a href="/idtracker/help/state/">IESG State</>:</td><td> {{ doc.friendly_state|safe }}
|
||||
{% if doc.rfc_editor_state %}<br />RFC Editor State: <a href="http://www.rfc-editor.org/queue2.html#{{doc.draft_name}}">{{ doc.rfc_editor_state|escape }}</a>{% endif %}
|
||||
{% if doc.in_ietf_process %}{% if doc.ietf_process.telechat_date %}<br/>On agenda of {{ doc.ietf_process.telechat_date }} IESG telechat {% if doc.ietf_process.telechat_returning_item %} (returning item){%endif%}{%endif%}{% if doc.ietf_process.has_active_iesg_ballot %}<br/><i>({{ doc.ietf_process.iesg_ballot_needed }})</i>{%endif%}{%endif%}
|
||||
</td></tr>
|
||||
<tr><td>Intended status:</td><td>{% if doc.in_ietf_process %}{{ doc.ietf_process.intended_maturity_level|default:"-" }}{% else %}-{%endif%}</td></tr>
|
||||
<tr><td>Submission:</td><td>{{ doc.submission }}</td></tr>
|
||||
<tr><td>Responsible AD:</td><td>{% if doc.in_ietf_process %}{{ doc.ietf_process.ad_name|default:"-"|escape }}{%else%}-{%endif%}</td></tr>
|
||||
{% if doc.in_ietf_process and doc.ietf_process.iesg_note %}<tr><td>IESG Note:</td><td>{{ doc.ietf_process.iesg_note|format_textarea|safe }}</td></tr>{% endif %}
|
||||
|
@ -76,6 +80,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
{% endblock doc_metatable %}
|
||||
|
||||
{% block doc_metalinks %}
|
||||
{% edit_actions doc %}
|
||||
<div>
|
||||
<a href="mailto:{{doc.draft_name}}@tools.ietf.org?subject=Mail%20regarding%20{{doc.draft_name}}" rel="nofollow">Email Authors</a>
|
||||
| <a href="/ipr/search/?option=document_search&id_document_tag={{doc.tracker_id}}" rel="nofollow">IPR Disclosures</a>
|
||||
|
|
|
@ -31,7 +31,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
{% endcomment %}
|
||||
{% load ietf_filters %}{% load ballot_icon %}
|
||||
{% load ietf_filters ietf_streams %}{% load ballot_icon %}
|
||||
<td class="status">
|
||||
{{ doc.friendly_state|safe }} {% if not doc.rfc %}{{ doc.id|state_age_colored|safe }}{% endif %}
|
||||
{% if not hide_telechat_date %}{% if doc.telechat_date %}<br/>IESG Telechat: {{ doc.telechat_date }}{% endif %}{% endif %}
|
||||
|
@ -43,6 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
{% if doc.rfc.has_errata %}<br /><a href="http://www.rfc-editor.org/errata_search.php?rfc={{doc.rfc.rfc_number}}" rel="nofollow">Errata</a>{% endif %}
|
||||
{% else %}{# not rfc #}
|
||||
{% if doc.id.rfc_editor_state %}<br />RFC Editor State: <a href="http://www.rfc-editor.org/queue2.html#{{doc.id.draft_name}}">{{ doc.id.rfc_editor_state|escape }}</a>{% endif %}
|
||||
{% stream_state doc %}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="ballot">
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
The annotation tags of document {{ doc }} have been updated. See more information below.
|
||||
|
||||
Annotation tags set: {{ entry.setted }}
|
||||
Annotation tags reset: {{ entry.unsetted }}
|
||||
Date of the change: {{ entry.change_date }}
|
||||
Author of the change: {{ entry.person }}
|
||||
|
||||
Comment:
|
||||
{{ entry.comment }}
|
7
ietf/templates/ietfworkflows/edit_actions.html
Normal file
7
ietf/templates/ietfworkflows/edit_actions.html
Normal file
|
@ -0,0 +1,7 @@
|
|||
<div style="margin-bottom: 1em;">
|
||||
{% if can_edit_state %} <a href="{% url edit_state doc.draft_name %}">Change state</a> {% endif %}
|
||||
{% if can_edit_stream %}{% if can_edit_state %} | {% endif %}<a href="{% url edit_stream doc.draft_name %}">Change draft stream</a>{% endif %}
|
||||
{% if can_shepherd %}{% if can_edit_state or can_edit_stream %} | {% endif %}<a href="{% url doc_managing_shepherd draft.group.acronym draft.filename %}">Change draft shepherd</a>{% endif %}
|
||||
{% if can_writeup %}{% if can_edit_state or can_edit_stream or can_writeup %} | {% endif %}<a href="{% url doc_managing_writeup draft.group.acronym draft.filename %}">Change draft writeup</a>{% endif %}
|
||||
</div>
|
||||
|
26
ietf/templates/ietfworkflows/noworkflow_state_form.html
Normal file
26
ietf/templates/ietfworkflows/noworkflow_state_form.html
Normal file
|
@ -0,0 +1,26 @@
|
|||
<form action="" method="post">
|
||||
<table class="ietf-table edit-form" style="width: 100%;">
|
||||
<tr>
|
||||
<th>Adopt this draft in your WG</th>
|
||||
</tr>
|
||||
<tr style="vertical-align: top;"><td style="width: 50%;">
|
||||
<div class="field{% if form.errors.comment %} error{% endif %}">
|
||||
{{ form.errors.comment }}
|
||||
Comment: <span class="required">*</span><br />
|
||||
<textarea name="comment">{{ form.data.comment }}</textarea>
|
||||
</div>
|
||||
<div class="field{% if form.errors.weeks %} error{% endif %}">
|
||||
{{ form.errors.weeks }}
|
||||
Estimated time in 'Call for Adoption by WG Issued': <input type="text" name="weeks" value="{{ form.data.weeks }}" /> (in weeks)
|
||||
</div>
|
||||
<div class="field{% if form.errors.wg %} error{% endif %}">
|
||||
<p>
|
||||
You can manage different WGs, please select the WG in wich you want to call for adoption this draft
|
||||
</p>
|
||||
{{ form.errors.wg }}
|
||||
Select a WG: {{ form.wg }}
|
||||
</div>
|
||||
<input type="submit" name="change" value="Call for adoption" />
|
||||
</td></tr>
|
||||
</table>
|
||||
</form>
|
70
ietf/templates/ietfworkflows/state_edit.html
Normal file
70
ietf/templates/ietfworkflows/state_edit.html
Normal file
|
@ -0,0 +1,70 @@
|
|||
{% extends "base.html" %}
|
||||
{% load ietf_streams %}
|
||||
|
||||
{% block morecss %}
|
||||
table.state-history p { margin: 0px; }
|
||||
table.edit-form ul { padding: 0px; list-style-type: none; margin: 0px; margin-bottom: 2em; }
|
||||
table.edit-form ul li, table.edit-form div.free-change { padding: 0px 2em; }
|
||||
table.edit-form ul li.evenrow { background-color: #edf5ff; }
|
||||
table.edit-form textarea { width: 95%; height: 120px; }
|
||||
table.edit-form span.required { color: red; }
|
||||
table.edit-form ul.errorlist { border-width: 0px; padding: 0px; margin: 0px;}
|
||||
table.edit-form ul.errorlist li { color: red; margin: 0px; padding: 0px;}
|
||||
table.edit-form div.field { margin: 1em 0px; }
|
||||
table.edit-form div.submit-row { margin: 0px 2em; }
|
||||
table.edit-form div.error { border: 1px solid red; background-color: #ffeebb; padding: 5px 10px; }
|
||||
table.edit-form-tags tr { vertical-align: top; }
|
||||
table.edit-form-tags textarea { height: 200px; }
|
||||
table.edit-form-tags ul { border-width: 0px; padding: 0px 2em; }
|
||||
table.edit-form-tags ul li { padding: 0px; }
|
||||
{% endblock morecss %}
|
||||
|
||||
{% block title %}Change state for {{ draft }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Change state for {{ draft }}</h1>
|
||||
|
||||
<div class="return-to-document">
|
||||
<p>
|
||||
<a href="{% url doc_view draft.filename %}">Return to document view</a>
|
||||
</p>
|
||||
</div>
|
||||
<table class="ietf-table" style="width: 100%;">
|
||||
<tr>
|
||||
<th>Current stream</th>
|
||||
<th>Current state</th>
|
||||
<th>Annotation tags</th>
|
||||
</tr>
|
||||
<tr><td style="width: 25%;">
|
||||
{{ stream.name|default:"None" }}
|
||||
</td>
|
||||
<td style="width: 25%;">
|
||||
{{ state.name|default:"None" }}
|
||||
</td><td>
|
||||
<ul style="list-style-type: none; padding: 0px;">
|
||||
{% for tag in tags%}
|
||||
<li>{{ tag.annotation_tag }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</td></tr></table>
|
||||
<br />
|
||||
|
||||
{{ form }}
|
||||
|
||||
<br />
|
||||
<strong>State history</strong>
|
||||
<table class="ietf-table state-history" style="width: 100%">
|
||||
{% if history %}
|
||||
<tr><th>Date</th><th>Person</th><th>Change</th><th>Comment</th></tr>
|
||||
{% for baseentry in history %}
|
||||
{% with baseentry.get_real_instance as entry %}
|
||||
<tr class="{% cycle oddrow,evenrow %}"><td>{{ entry.date }}</td><td>{{ entry.person }}</td>
|
||||
<td>{{ entry.describe_change|safe }}</td><td>{{ entry.comment }}</td>
|
||||
</tr>
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<tr><td>There is no state history for this document.</td></th>
|
||||
{% endif %}
|
||||
</table>
|
||||
{% endblock %}
|
60
ietf/templates/ietfworkflows/state_form.html
Normal file
60
ietf/templates/ietfworkflows/state_form.html
Normal file
|
@ -0,0 +1,60 @@
|
|||
<form action="" method="post">
|
||||
<table class="ietf-table edit-form" style="width: 100%;">
|
||||
<tr>
|
||||
<th>1. Input information about change</th>
|
||||
<th>2. Change annotation tags if needed</th>
|
||||
</tr>
|
||||
<tr style="vertical-align: top;"><td style="width: 50%;">
|
||||
<div class="field{% if form.errors.comment %} error{% endif %}">
|
||||
{{ form.errors.comment }}
|
||||
Comment: <span class="required">*</span><br />
|
||||
<textarea name="comment">{{ form.data.comment }}</textarea>
|
||||
</div>
|
||||
<div class="field{% if form.errors.weeks %} error{% endif %}">
|
||||
{{ form.errors.weeks }}
|
||||
Estimated time in next status:<br />
|
||||
<input type="text" name="weeks" value="{{ form.data.weeks }}" /> (in weeks)
|
||||
</div>
|
||||
</td><td>
|
||||
<div class="field">
|
||||
{{ form.tags }}
|
||||
</div>
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
<br />
|
||||
|
||||
<table class="ietf-table edit-form edit-form-tags" style="width: 100%;">
|
||||
<tr>
|
||||
<th>3. Select one action</th>
|
||||
</tr>
|
||||
<tr><td>
|
||||
<div class="only-tags field">
|
||||
<ul>
|
||||
<li><input type="submit" name="only_tags" value="Update annotation tags" /> State remains unchanged: <strong>{{ form.state.name }}</strong></li>
|
||||
</ul>
|
||||
</div>
|
||||
{% with form.get_transitions as transitions %}
|
||||
{% if transitions %}
|
||||
<ul>
|
||||
{% for transition in transitions %}
|
||||
<li class="{% cycle oddrow,evenrow %}">
|
||||
<input type="submit" name="transition_{{ transition.pk }}" value="{{ transition.name }}" />
|
||||
Changes state to: <strong>{{ transition.destination.name }}</strong>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endwith %}
|
||||
<div class="free-change field{% if form.errors.new_state %} error{% endif %}">
|
||||
{{ form.errors.new_state }}
|
||||
<select name="new_state">
|
||||
{% for value, name in form.get_states %}
|
||||
<option value="{{ value }}">{{ name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<input type="submit" name="change" value="State change" />
|
||||
</div>
|
||||
</td></tr>
|
||||
</table>
|
||||
</form>
|
9
ietf/templates/ietfworkflows/state_updated_mail.txt
Normal file
9
ietf/templates/ietfworkflows/state_updated_mail.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
The state of document {{ doc }} has been updated. See more information below.
|
||||
|
||||
Previous state: {{ entry.from_state }}
|
||||
Current state: {{ entry.to_state }}
|
||||
Transition date: {{ entry.transition_date }}
|
||||
Author of the change: {{ entry.person }}
|
||||
|
||||
Comment:
|
||||
{{ entry.comment }}
|
21
ietf/templates/ietfworkflows/stream_form.html
Normal file
21
ietf/templates/ietfworkflows/stream_form.html
Normal file
|
@ -0,0 +1,21 @@
|
|||
<form action="" method="post">
|
||||
<table class="ietf-table edit-form" style="width: 100%;">
|
||||
<tr>
|
||||
<th>Select the new stream</th>
|
||||
</tr>
|
||||
<tr><td>
|
||||
<div class="field{% if form.errors.comment %} error{% endif %}">
|
||||
{{ form.errors.comment }}
|
||||
Comment: <span class="required">*</span><br />
|
||||
<textarea name="comment">{{ form.data.comment }}</textarea>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<td>
|
||||
<div class="field{% if form.errors.stream %} error{% endif %}">
|
||||
{{ form.errors.stream }}
|
||||
{{ form.stream }} <input type="submit" value="Change stream" />
|
||||
</div>
|
||||
</td></tr>
|
||||
</table>
|
||||
</form>
|
44
ietf/templates/ietfworkflows/stream_history.html
Normal file
44
ietf/templates/ietfworkflows/stream_history.html
Normal file
|
@ -0,0 +1,44 @@
|
|||
{% load ietf_streams %}
|
||||
<table class="ietf-ballot ietf-stream">
|
||||
<tr>
|
||||
<td class="left">
|
||||
{% if workflow %}
|
||||
<ul class="ietf-stream-tag-list">
|
||||
{% for tag in tags %}
|
||||
<li{% if tag.setted %} class="tag_set"{% endif %}>{{ tag }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="right">
|
||||
<div class="ietf-stream-head">
|
||||
{% if stream %}
|
||||
<h2>
|
||||
{{ stream|default:"Without stream" }}{% if stream.with_groups and streamed.group %} :: {{ streamed.group|default:"" }}{% endif %}
|
||||
</h2>
|
||||
<h3>Current state: {{ state|default:"None" }}</h3>
|
||||
{% else %}
|
||||
<h2>Without stream</h2>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if history %}
|
||||
<div class="ietf-stream-history">
|
||||
{% if show_more %}
|
||||
<p> Viewing the last 20 entries. <a href="">Show full log</a>.</p>
|
||||
{% endif %}
|
||||
{% for entry in history %}
|
||||
{% workflow_history_entry entry %}
|
||||
{% endfor %}
|
||||
{% if show_more %}
|
||||
<p> Viewing the last 20 entries. <a href="">Show full log</a>.</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<p>
|
||||
There is no stream history for this document.
|
||||
</p>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
10
ietf/templates/ietfworkflows/stream_state.html
Normal file
10
ietf/templates/ietfworkflows/stream_state.html
Normal file
|
@ -0,0 +1,10 @@
|
|||
{% if draft %}
|
||||
<div class="stream_state" style="border: 1px solid black; padding: 0px 5px; margin: 5px 0px;">
|
||||
<div class="stream_state_more" style="float: right; margin-left: 2em;"><a href="{% url stream_history draft.filename %}" class="show_stream_info" title="Stream information for {{ draft.filename }}" style="text-decoration: none; color: black;">+</a></div>
|
||||
{% if stream %}
|
||||
{{ stream }} {% if state %}:: {{ state }}{% endif %}
|
||||
{% else %}
|
||||
No stream asigned
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
9
ietf/templates/ietfworkflows/stream_updated_mail.txt
Normal file
9
ietf/templates/ietfworkflows/stream_updated_mail.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
The stream of document {{ doc }} has been updated. See more information below.
|
||||
|
||||
Previous stream: {{ entry.from_stream }}
|
||||
Current stream: {{ entry.to_stream }}
|
||||
Transition date: {{ entry.transition_date }}
|
||||
Author of the change: {{ entry.person }}
|
||||
|
||||
Comment:
|
||||
{{ entry.comment }}
|
22
ietf/templates/ietfworkflows/tags_form.html
Normal file
22
ietf/templates/ietfworkflows/tags_form.html
Normal file
|
@ -0,0 +1,22 @@
|
|||
<form action="" method="post">
|
||||
<table class="ietf-table edit-form edit-form-tags" style="width: 100%;">
|
||||
<tr>
|
||||
<th>1. Input information about change</th>
|
||||
<th>2. Select annotation tags</th>
|
||||
</tr>
|
||||
<tr><td style="width: 50%;">
|
||||
<div class="field comment{% if form.errors.comment %} error{% endif %}">
|
||||
{{ form.errors.comment }}
|
||||
Comment: <span class="required">*</span><br />
|
||||
<textarea name="comment">{{ form.data.comment }}</textarea>
|
||||
</div>
|
||||
</td><td style="padding: 0px; vertical-align: top;">
|
||||
<div class="field">
|
||||
{{ form.tags }}
|
||||
</div>
|
||||
<div class="submit-row">
|
||||
<input type="submit" value="Edit tags" />
|
||||
</div>
|
||||
</td></tr>
|
||||
</table>
|
||||
</form>
|
12
ietf/templates/ietfworkflows/workflow_history_entry.html
Normal file
12
ietf/templates/ietfworkflows/workflow_history_entry.html
Normal file
|
@ -0,0 +1,12 @@
|
|||
<div class="workflow-history-entry workflow-history-entry-{{ entry_class }}">
|
||||
<div class="entry-title">
|
||||
<span class="entry-date">{{ entry.date }}</span>
|
||||
{{ entry.person }}
|
||||
</div>
|
||||
<div class="entry-action">
|
||||
{{ entry.describe_change|safe }}
|
||||
</div>
|
||||
<div class="entry-comment">
|
||||
{{ entry.comment }}
|
||||
</div>
|
||||
</pre>
|
55
ietf/templates/wgchairs/confirm_management_writeup.html
Normal file
55
ietf/templates/wgchairs/confirm_management_writeup.html
Normal file
|
@ -0,0 +1,55 @@
|
|||
{% extends "wginfo/wg_base.html" %}
|
||||
{% load ietf_filters wgchairs_tags %}
|
||||
|
||||
{% block title %}Chage shepherd for {{ doc }}{% endblock %}
|
||||
|
||||
{% block wg_content %}
|
||||
|
||||
<p>
|
||||
<a href="{% url manage_shepherds wg.group_acronym.acronym %}">Return to shepherd list</a>
|
||||
</p>
|
||||
|
||||
<h1>Updatting write-up for {{ doc }}</h1>
|
||||
|
||||
<p>
|
||||
Before you modify the protocol write-up <strong>please revise the 'Doc Shepherd Follow-up Underway' annotation tag and set or reset it if appropriate</strong>.
|
||||
</p>
|
||||
<p>
|
||||
Remember that you must provide a comment if you change the annotation tag state.
|
||||
</p>
|
||||
|
||||
<form action="" method="POST">
|
||||
<table style="width: 100%;"><tr style="vertical-align: top;"><td style="width: 50%;">
|
||||
<table class="ietf-table" style="width: 100%;">
|
||||
<tr><th>Doc Shepherd Follow-up Underway</th></tr>
|
||||
{% if form.message %}
|
||||
<tr><td class="message message-{{ form.message.type }}">
|
||||
{{ form.message.value }}
|
||||
</td></tr>
|
||||
{% endif %}
|
||||
|
||||
<tr><td>
|
||||
<input type="hidden" value="{{ form.get_writeup }}" name="writeup" />
|
||||
<input type="hidden" value="confirm" name="confirm" />
|
||||
<input type="checkbox" name="followup" id="followup_id" value="1"{% if followup %} checked="checked"{% endif %} />
|
||||
<label for="followup_id">Doc Shepherd Follow-up Underway</label>
|
||||
</td></tr><tr><td>
|
||||
{{ form.comment }}
|
||||
</td></tr>
|
||||
</table>
|
||||
<p>
|
||||
<strong>Change write-up and ...</strong><br />
|
||||
<input type="submit" name="modify_tag" value="Modify 'Doc Shepherd Follow-up Underway'" />
|
||||
<input type="submit" name="change_writeup" value="Leave 'Doc Shepherd Follow-up Underway' untouched" /><br />
|
||||
<a href="">Cancel, I don't want to do any change!</a>
|
||||
</p>
|
||||
|
||||
</td><td style="width: 50%;">
|
||||
<table class="ietf-table" style="width: 100%;">
|
||||
<tr><th>New protocol write-up</th></tr>
|
||||
<tr style="vertical-align: top;"><td>{{ form.get_writeup|linebreaksbr }}</td></tr>
|
||||
</table>
|
||||
|
||||
</td></tr></table>
|
||||
</form>
|
||||
{% endblock %}
|
1
ietf/templates/wgchairs/draft_state.html
Normal file
1
ietf/templates/wgchairs/draft_state.html
Normal file
|
@ -0,0 +1 @@
|
|||
{{ state.name }}
|
40
ietf/templates/wgchairs/edit_management_shepherd.html
Normal file
40
ietf/templates/wgchairs/edit_management_shepherd.html
Normal file
|
@ -0,0 +1,40 @@
|
|||
{% extends "wginfo/wg_base.html" %}
|
||||
{% load ietf_filters %}
|
||||
|
||||
{% block title %}Chage shepherd for {{ doc }}{% endblock %}
|
||||
|
||||
{% block wg_content %}
|
||||
|
||||
<p>
|
||||
<a href="{% url manage_shepherds wg.group_acronym.acronym %}">Return to shepherd list</a>
|
||||
</p>
|
||||
|
||||
<h1>Change shepherd for {{ doc }}</h1>
|
||||
|
||||
<table style="width: 100%;"><tr style="vertical-align: top;"><td style="width: 50%;">
|
||||
<form action="" method="POST">
|
||||
<table class="ietf-table" style="width: 100%;">
|
||||
<tr><th>Actual shepherd</th></tr>
|
||||
<tr><td>{% if doc.shepherd %}{{ doc.shepherd }}{% else %}No shephered assigned{% endif %}</td></tr>
|
||||
</table>
|
||||
<input type="hidden" name="update_shepherd" value="1" />
|
||||
<input type="submit" name="remove_shepherd" value="Unassign shepherd" />
|
||||
<input type="submit" name="setme" value="Set me as shepherd of this document" />
|
||||
</form>
|
||||
</td><td style="width: 50%;">
|
||||
<form action="" method="POST">
|
||||
<table class="ietf-table" style="width: 100%;">
|
||||
<tr><th>Change shepherd</th></tr>
|
||||
{% if form.message %}
|
||||
<tr><td class="message message-{{ form.message.type }}">
|
||||
{{ form.message.value }}
|
||||
</td></tr>
|
||||
{% endif %}
|
||||
|
||||
<tr><td>{{ form.as_p }}</td></tr>
|
||||
</table>
|
||||
<input type="submit" name="change_sheperd" value="Change shepherd" />
|
||||
{% if form.can_cancel %}<a href="">No! I don't want to continue</a>{% endif %}
|
||||
</form>
|
||||
</td></tr></table>
|
||||
{% endblock %}
|
65
ietf/templates/wgchairs/edit_management_writeup.html
Normal file
65
ietf/templates/wgchairs/edit_management_writeup.html
Normal file
|
@ -0,0 +1,65 @@
|
|||
{% extends "wginfo/wg_base.html" %}
|
||||
{% load ietf_filters wgchairs_tags %}
|
||||
|
||||
{% block title %}Chage shepherd for {{ doc }}{% endblock %}
|
||||
|
||||
{% block wg_content %}
|
||||
|
||||
<p>
|
||||
<a href="{% url manage_shepherds wg.group_acronym.acronym %}">Return to shepherd list</a>
|
||||
</p>
|
||||
|
||||
<h1>Change protocol write-up for {{ doc }}</h1>
|
||||
|
||||
<table class="ietf-table" style="width: 100%;">
|
||||
<tr><th>Draft state</th><th>Actual protocol write-up</th><th>Last updated</th></tr>
|
||||
<tr style="vertical-align: top;"><td>{% show_state doc %}</td><td>{{ writeup.writeup|linebreaksbr }}</td><td>{% if writeup %}{{ writeup.date }} by {{ writeup.person }}{% endif %}</td></tr>
|
||||
</table>
|
||||
|
||||
<p>
|
||||
Please, <strong>note</strong> that the <strong>'Doc Shepherd Follow-up Underway'</strong> annotation tag is {% if not followup %}<strong>NOT</strong>{% endif %} setted for {{ doc }}.
|
||||
</p>
|
||||
|
||||
{% if can_edit %}
|
||||
<table style="width: 100%;"><tr style="vertical-align: top;"><td style="width: 75%;">
|
||||
<form action="" method="POST">
|
||||
<table class="ietf-table" style="width: 100%;">
|
||||
<tr><th>Edit protocol write-up</th></tr>
|
||||
{% if form.message %}
|
||||
<tr><td class="message message-{{ form.message.type }}">
|
||||
{{ form.message.value }}
|
||||
</td></tr>
|
||||
{% endif %}
|
||||
|
||||
<tr><td>
|
||||
<textarea name="writeup" style="border: 1px solid #cccccc; width: 100%; height: 15em;">{{ form.get_writeup }}</textarea></td></tr>
|
||||
</table>
|
||||
<input type="submit" name="change_writeup" value="Change write-up" />
|
||||
</form>
|
||||
|
||||
</td><td style="width: 25%;">
|
||||
|
||||
<form action="" method="POST" enctype="multipart/form-data">
|
||||
<table class="ietf-table" style="width: 100%;">
|
||||
<tr><th>Upload a new protocol write-up</th></tr>
|
||||
<tr><td>
|
||||
<p>Replace the current write-up with the contents of a plain ascii file:</p>
|
||||
<input type="file" name="uploaded_writeup" /></td></tr>
|
||||
</table>
|
||||
<input type="submit" name="upload_writeup" value="Upload write-up" />
|
||||
</form>
|
||||
</td></tr></table>
|
||||
{% else %}
|
||||
<table class="ietf-table" style="width: 100%;">
|
||||
<tr><th>Edit protocol write-up</th></tr>
|
||||
<tr><td>
|
||||
<p>
|
||||
You can not edit or upload the protocol write-up for {{ doc }} cause the draft is not on "WG Consensus: Waiting for Write-Up" state.
|
||||
</p>
|
||||
<p>
|
||||
Please contact with the {{ wg }} Working Group chair.
|
||||
</p>
|
||||
</td></tr>
|
||||
</table>
|
||||
{% endif %}
|
||||
{% endblock %}
|
60
ietf/templates/wgchairs/manage_delegates.html
Normal file
60
ietf/templates/wgchairs/manage_delegates.html
Normal file
|
@ -0,0 +1,60 @@
|
|||
{% extends "wginfo/wg_base.html" %}
|
||||
|
||||
|
||||
{% block wg_titledetail %}Delegates{% endblock %}
|
||||
|
||||
{% block wg_content %}
|
||||
<div class="wg-chair-management">
|
||||
|
||||
<h2>Manage delegates</h2>
|
||||
<p>
|
||||
Sometimes, a WG has one (or more) WG Secretaries, in addition to the WG Chairs.
|
||||
This page lets the WG Chairs delegate the authority to do updates to the WG state of WG documents in the datatracker.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
You may at most delegate the datatracker update rights to {{ max_delegates }} persons at any given time.
|
||||
</p>
|
||||
|
||||
<table style="width: 100%;">
|
||||
<tr style="vertical-align: top;"><td>
|
||||
{% if delegates %}
|
||||
<form action="" method="POST">
|
||||
<table class="ietf-table" style="width: 100%">
|
||||
<tr><th>Remove</th><th style="Width: 100%">Delegate name</th></tr>
|
||||
{% for delegate in delegates %}
|
||||
<tr class="{% cycle "oddrow" "evenrow" %}"><td><input type="checkbox" name="delete" value="{{ delegate.pk }}" /></td><td>{{ delegate.person }}</td></tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
<input type="submit" value="Remove delegate(s)" name="remove" />
|
||||
</form>
|
||||
{% else %}
|
||||
No delegates
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
<table class="ietf-table" style="width: 100%;">
|
||||
<tr><th>Add new delegate</th></tr>
|
||||
{% if add_form.message %}
|
||||
<tr><td class="message message-{{ add_form.message.type }}">
|
||||
{{ add_form.message.value }}
|
||||
</td></tr>
|
||||
{% endif %}
|
||||
<tr><td>
|
||||
{% if can_add %}
|
||||
<form action="" method="POST">
|
||||
{{ add_form.as_p }}
|
||||
<p>
|
||||
<input type="submit" value="{% if add_form.submit_msg %}{{ add_form.submit_msg }}{% else %}Add delegate{% endif %}" name="add" />
|
||||
{% if add_form.can_cancel %}<a href="">No! I don't want to continue</a>{% endif %}
|
||||
</p>
|
||||
</form>
|
||||
{% else %}
|
||||
You can only assign {{ max_delegates }} delegates. Please remove delegates to add a new one.
|
||||
{% endif %}
|
||||
</td></tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
{% endblock %}
|
165
ietf/templates/wgchairs/manage_workflow.html
Normal file
165
ietf/templates/wgchairs/manage_workflow.html
Normal file
|
@ -0,0 +1,165 @@
|
|||
{% extends "wginfo/wg_base.html" %}
|
||||
|
||||
{% block wg_titledetail %}Manage Workflow{% endblock %}
|
||||
|
||||
{% block pagehead %}
|
||||
{{ block.super }}
|
||||
<script type="text/javascript" src="/js/lib/jquery-1.4.2.min.js"></script>
|
||||
<script type="text/javascript" src="/js/yui/yui-20100305.js"></script>
|
||||
<script type="text/javascript" src="/js/base.js"></script>
|
||||
{% endblock pagehead %}
|
||||
|
||||
{% block wg_content %}
|
||||
<div class="wg-workflow-management">
|
||||
<h2>Edit workflow</h2>
|
||||
<div id="mytabs" class="yui-navset">
|
||||
<ul class="yui-nav">
|
||||
<li class="selected"><a href="#info"><em>Info</em></a></li>
|
||||
<li><a href="#states"><em>Select states</em></a></li>
|
||||
<li><a href="#transitions"><em>Edit transitions</em></a></li>
|
||||
<li><a href="#tags"><em>Select Annotation Tags</em></a></li>
|
||||
</ul>
|
||||
|
||||
<div class="yui-content">
|
||||
<div id="info">
|
||||
<table style="width: 100%;"><tr style="vertical-align: top;"><td>
|
||||
<table class="ietf-table" style="width: 100%">
|
||||
<tr>
|
||||
<th>States used in {{ wg }} Working Group</th>
|
||||
</tr>
|
||||
{% for state in states %}
|
||||
<tr class="{% cycle "oddrow" "evenrow" %}">
|
||||
<td>{{ state.name }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table><br />
|
||||
<table class="ietf-table" style="width: 100%;">
|
||||
<tr>
|
||||
<th>Annotation tags used in {{ wg }} Working Group</th>
|
||||
</tr>
|
||||
{% for tag in tags %}
|
||||
<tr class="{% cycle "oddrow" "evenrow" %}">
|
||||
<td>{{ tag.name }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</td><td>
|
||||
<table class="ietf-table" style="width: 100%;">
|
||||
<tr>
|
||||
<th>Transition name</th><th>Initial states</th><th>Destination state</th>
|
||||
</tr>
|
||||
{% for transition in workflow.transitions.all %}
|
||||
<tr class="{% cycle "oddrow" "evenrow" %}">
|
||||
<td>
|
||||
{{ transition.name }}
|
||||
</td>
|
||||
<td>
|
||||
{% for state in transition.states.all %}
|
||||
{{state.name }}{% if not forloop.last %}<br />{% endif %}
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td>
|
||||
{{ transition.destination.name }}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% if not workflow.transitions.all.count %}
|
||||
<tr class="oddrow"><td colspan="3">There are no transitions defined so any state change is allowed</td></tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
</td></tr></table>
|
||||
</div>
|
||||
|
||||
<div id="states">
|
||||
<p>
|
||||
Please note that the states you can not uncheck are needed in all IETF WGs.
|
||||
</p>
|
||||
<p>
|
||||
You can see the default Working Group I-D State Diagram in <a href="http://tools.ietf.org/html/rfc6174#section-4.1">Section 4.1 of RFC6174</a>
|
||||
</p>
|
||||
<form action="#info" method="POST">
|
||||
<table class="ietf-table">
|
||||
<tr>
|
||||
<th>Used in {{ wg }}</th><th>Available states</th><th>Definition</th>
|
||||
</tr>
|
||||
{% for state in default_states %}
|
||||
<tr class="{% cycle "oddrow" "evenrow" %}" style="vertical-align: top;">
|
||||
<td><input type="checkbox" id="id_states_{{ state.pk }}" name="states" value="{{ state.pk }}" {% if state.used %}checked="checked" {% endif %}{% if state.freeze %} disabled="disabled"{% endif %}/></td>
|
||||
<td><label for="id_states_{{ state.pk }}">{{ state.name }}</label></td>
|
||||
<td>
|
||||
<div class="statedefinition" style="height: 1em; overflow: hidden;">
|
||||
<pre style="margin-top: 0px;"><a class="showDefinition" href="#">[+]</a><a class="hideDefinition" style="display: none;" href="#">[-]</a> {{ state.statedescription_set.all.0.definition|safe }}</pre>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
<input type="submit" name="update_states" value="Update states" />
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="transitions">
|
||||
<p>
|
||||
You can see the default Working Group I-D State Diagram in <a href="http://tools.ietf.org/html/rfc6174#section-4.1">Section 4.1 of RFC6174</a>
|
||||
</p>
|
||||
<form action="#transitions" method="POST">
|
||||
<table class="ietf-table">
|
||||
<tr>
|
||||
<th>Delete</th><th>Transition name</th><th>Initial states</th><th>Destination state</th>
|
||||
</tr>
|
||||
{{ formset.as_table }}
|
||||
</table>
|
||||
<input type="submit" name="update_transitions" value="Update transitions" />
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="tags">
|
||||
<form action="#info" method="POST">
|
||||
<table class="ietf-table">
|
||||
<tr>
|
||||
<th>Used in {{ wg }}</th><th>Available annotation tags</th>
|
||||
</tr>
|
||||
{% for tag in default_tags %}
|
||||
<tr class="{% cycle "oddrow" "evenrow" %}">
|
||||
<td><input type="checkbox" id="id_tags_{{ tag.pk }}" name="tags" value="{{ tag.pk }}" {% if tag.used %}checked="checked" {% endif %}/></td>
|
||||
<td><label for="id_tags_{{ tag.pk }}">{{ tag.name }}</label></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
<input type="submit" name="update_tags" value="Update tags" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
var tabView = new YAHOO.widget.TabView('mytabs');
|
||||
var url = location.href.split('#');
|
||||
if (url[1]) {
|
||||
url[1] = "#"+url[1];
|
||||
var tabs = tabView.get('tabs');
|
||||
for (var i = 0; i < tabs.length; i++) {
|
||||
if (url[1].indexOf(tabs[i].get('href')) == 0) {
|
||||
tabView.set('activeIndex', i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
jQuery('.showDefinition').click(function() {
|
||||
jQuery(this).parent().parent().css('height', 'auto');
|
||||
jQuery(this).hide();
|
||||
jQuery(this).next().show();
|
||||
return false;
|
||||
});
|
||||
jQuery('.hideDefinition').click(function() {
|
||||
jQuery(this).parent().parent().css('height', '1em');
|
||||
jQuery(this).hide();
|
||||
jQuery(this).prev().show();
|
||||
return false;
|
||||
});
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
28
ietf/templates/wgchairs/notexistdelegate.html
Normal file
28
ietf/templates/wgchairs/notexistdelegate.html
Normal file
|
@ -0,0 +1,28 @@
|
|||
{% if shepherd %}
|
||||
<p>
|
||||
The shepherd you are trying to designate does not have a personal user-id and password to log-on to the Datatracker.
|
||||
</p>
|
||||
<p>
|
||||
An email will be sent to the following addresses to inform that
|
||||
the person you have designated to be one of your document shepherds
|
||||
currently does not have login credentials for the Datatracker
|
||||
and should contact the Secretariat to obtain their own user-id and
|
||||
password for the Datatracker.
|
||||
</p>
|
||||
{% else %}
|
||||
<p>
|
||||
The delegate you are trying to designate does not have a personal user-id and password to log-on to the Datatracker.
|
||||
</p>
|
||||
<p>
|
||||
An email will be sent to the following addresses to inform that
|
||||
the person you have designated to be one of your delegates
|
||||
currently does not have login credentials for the Datatracker
|
||||
and should contact the Secretariat to obtain their own user-id and
|
||||
password for the Datatracker.
|
||||
</p>
|
||||
{% endif %}
|
||||
<ul>
|
||||
{% for email in email_list %}
|
||||
<li>{{ email }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
|
@ -0,0 +1,9 @@
|
|||
{{ chair }} as a WG Chair of {{ wg }} wants to add you as a {{ wg }} {% if shepherd %}shepherd of document {{ shepherd }}{% else %}WG Delegate{% endif %}.
|
||||
|
||||
You don't have an user/password to log into the datatracker so you must contact
|
||||
the Secretariat at iesg-secretary@ietf.org in order to get your credentials.
|
||||
|
||||
When you get your credentials, please inform {{ chair }} at
|
||||
{{ chair.email.1 }} so he/she can finish the designate process.
|
||||
|
||||
Thank you.
|
|
@ -0,0 +1,14 @@
|
|||
{{ chair }} as a WG Chair of {{ wg }} wants to add a person with email
|
||||
{{ delegate_email }} as a {% if shepherd %}shepherd of document {{ shepherd }}{% else %}WG Delegate{% endif %}.
|
||||
|
||||
This person don't have an user/password to log into the datatracker so
|
||||
an email has been seent to {{ delegate_email }} in order to he/she contacs the
|
||||
Secretariat to request his/her credentials.
|
||||
|
||||
{% if delegate_persons %}
|
||||
Please, note that the following persons with {{ delegate_email }} email address
|
||||
already exists in the system but they can not log in.
|
||||
{% for person in delegate_persons %}
|
||||
{{ person.pk }} - {{ person }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
11
ietf/templates/wgchairs/notexistsdelegate_wgchairs_email.txt
Normal file
11
ietf/templates/wgchairs/notexistsdelegate_wgchairs_email.txt
Normal file
|
@ -0,0 +1,11 @@
|
|||
{{ chair }} as a WG Chair of {{ wg }} wants to add a person with email
|
||||
{{ delegate_email }} as a {% if shepherd %}shepherd of document {{ shepherd }}{% else %}WG Delegate{% endif %}.
|
||||
|
||||
This person don't have an user/password to log into the datatracker so
|
||||
an email has been seent to {{ delegate_email }} in order to he/she contacs the
|
||||
Secretariat to request his/her credentials.
|
||||
|
||||
When he/she gets her credentials then he/she will send an email to
|
||||
{{ chair }} at {{ chair.email.1 }}.
|
||||
|
||||
{{ chair }} could then assign this person as {% if shepherd %}shepherd of document {{ shepherd }}{% else %}WG Delegate{% endif %}.
|
17
ietf/templates/wgchairs/shepherd_document_row.html
Normal file
17
ietf/templates/wgchairs/shepherd_document_row.html
Normal file
|
@ -0,0 +1,17 @@
|
|||
{% load wgchairs_tags %}
|
||||
|
||||
<tr class="{% cycle oddrow,evenrow %}">
|
||||
<td class="title">
|
||||
<a href="{% url doc_view doc.filename %}">{{ doc.title }}</a>
|
||||
</td>
|
||||
<td class="shepherd">
|
||||
<a href="{% url doc_managing_shepherd wg.group_acronym.acronym doc %}">Change shepherd</a>
|
||||
</td>
|
||||
<td class="writeup">
|
||||
{% writeup doc %}
|
||||
<a href="{% url doc_managing_writeup wg.group_acronym.acronym doc %}" style="display: block;" href="">[Edit]</a>
|
||||
</td>
|
||||
<td class="writeup_date">
|
||||
{% writeupdate doc %}
|
||||
</td>
|
||||
</tr>
|
122
ietf/templates/wgchairs/wg_shepherd_documents.html
Normal file
122
ietf/templates/wgchairs/wg_shepherd_documents.html
Normal file
|
@ -0,0 +1,122 @@
|
|||
{% extends "wginfo/wg_base.html" %}
|
||||
{% comment %}
|
||||
Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
All rights reserved. Contact: Pasi Eronen <pasi.eronen@nokia.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
|
||||
* Neither the name of the Nokia Corporation and/or its
|
||||
subsidiary(-ies) nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
{% endcomment %}
|
||||
{% block wg_titledetail %}Documents{% endblock %}
|
||||
|
||||
{% block pagehead %}
|
||||
{{ block.super }}
|
||||
<script type="text/javascript" src="/js/lib/jquery-1.4.2.min.js"></script>
|
||||
<script type="text/javascript" src="/js/yui/yui-20100305.js"></script>
|
||||
<script type="text/javascript" src="/js/base.js"></script>
|
||||
{% endblock pagehead %}
|
||||
|
||||
{% block wg_content %}
|
||||
|
||||
<h2>Documents by its shepherd</h2>
|
||||
<div id="mytabs" class="yui-navset">
|
||||
<ul class="yui-nav">
|
||||
<li class="selected"><a href="#noshepherd"><em>Without shepherd</em></a></li>
|
||||
<li><a href="#mydocs"><em>Shepherded by me</em></a></li>
|
||||
<li><a href="#othershepherds"><em>Shepherded by others</em></a></li>
|
||||
</ul>
|
||||
|
||||
<div class="yui-content">
|
||||
<div id="noshepherd">
|
||||
<table class="ietf-table ietf-doctable" style="margin-top:16px; width: 100%;">
|
||||
<tr>
|
||||
<th class="title">Document</th>
|
||||
<th class="shepherd">Change shepherd</th>
|
||||
<th class="writeup">Protocol write-up</th>
|
||||
<th class="writeup_date">Protocol write-up last update</th>
|
||||
</tr>
|
||||
|
||||
{% for doc in no_shepherd %}
|
||||
{% include "wgchairs/shepherd_document_row.html" %}
|
||||
{% endfor %}
|
||||
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div id="mydocs">
|
||||
<table class="ietf-table ietf-doctable" style="margin-top:16px; width: 100%;">
|
||||
<tr>
|
||||
<th class="title">Document</th>
|
||||
<th class="status">Status</th>
|
||||
<th class="writeup">Protocol write-up</th>
|
||||
<th class="writeup_date">Protocol write-up last update</th>
|
||||
</tr>
|
||||
|
||||
{% for doc in my_documents %}
|
||||
{% include "wgchairs/shepherd_document_row.html" %}
|
||||
{% endfor %}
|
||||
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div id="othershepherds">
|
||||
{% regroup other_shepherds by shepherd as regrouped %}
|
||||
{% for documents in regrouped %}
|
||||
<h3 style="margin-bottom: 0px;">{{ documents.grouper }}</h3>
|
||||
<table class="ietf-table ietf-doctable" style="width: 100%;">
|
||||
<tr>
|
||||
<th class="title">Document</th>
|
||||
<th class="status">Status</th>
|
||||
<th class="writeup">Protocol write-up</th>
|
||||
<th class="writeup_date">Protocol write-up last update</th>
|
||||
</tr>
|
||||
{% for doc in documents.list %}
|
||||
{% include "wgchairs/shepherd_document_row.html" %}
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
var tabView = new YAHOO.widget.TabView('mytabs');
|
||||
var url = location.href.split('#');
|
||||
if (url[1]) {
|
||||
url[1] = "#"+url[1];
|
||||
var tabs = tabView.get('tabs');
|
||||
for (var i = 0; i < tabs.length; i++) {
|
||||
if (url[1].indexOf(tabs[i].get('href')) == 0) {
|
||||
tabView.set('activeIndex', i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//]]>
|
||||
</script>
|
||||
{% endblock wg_content %}
|
||||
|
23
ietf/templates/wgchairs/wgchairs_admin_options.html
Normal file
23
ietf/templates/wgchairs/wgchairs_admin_options.html
Normal file
|
@ -0,0 +1,23 @@
|
|||
{% if can_manage_workflow %}
|
||||
{% ifequal selected "manage_workflow" %}
|
||||
<span class="selected">Manage workflow</span>
|
||||
{% else %}
|
||||
<a href="{% url manage_workflow wg.group_acronym.acronym %}">Manage workflow</a>
|
||||
{% endifequal %} |
|
||||
{% endif %}
|
||||
|
||||
{% if can_manage_delegates %}
|
||||
{% ifequal selected "manage_delegates" %}
|
||||
<span class="selected">Manage delegations</span>
|
||||
{% else %}
|
||||
<a href="{% url manage_delegates wg.group_acronym.acronym %}">Manage delegations</a>
|
||||
{% endifequal %} |
|
||||
{% endif %}
|
||||
|
||||
{% if can_manage_shepherds %}
|
||||
{% ifequal selected "manage_shepherds" %}
|
||||
<span class="selected">Manage shepherds</span>
|
||||
{% else %}
|
||||
<a href="{% url manage_shepherds wg.group_acronym.acronym %}">Manage shepherds</a>
|
||||
{% endifequal %} |
|
||||
{% endif %}
|
|
@ -32,7 +32,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
{% endcomment %}
|
||||
{% load ietf_filters %}
|
||||
{% load ietf_filters wgchairs_tags %}
|
||||
{% block title %}{{wg.group_acronym.name}} ({{wg.group_acronym.acronym}}) - {% block wg_titledetail %}{% endblock %}{% endblock %}
|
||||
|
||||
{% block morecss %}
|
||||
|
@ -58,6 +58,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
<div class="ietf-navset">
|
||||
{% ifequal selected "documents" %}<span class="selected">Documents</span>{% else %}<a href="/wg/{{wg}}/">Documents</a>{% endifequal %} |
|
||||
{% ifequal selected "charter" %}<span class="selected">Charter</span>{% else %}<a href="/wg/{{wg}}/charter/">Charter</a>{% endifequal %} |
|
||||
{% wgchairs_admin_options wg %}
|
||||
{% if wg.clean_email_archive|startswith:"http:" or wg.clean_email_archive|startswith:"ftp:" %}
|
||||
<a href="{{ wg.clean_email_archive }}">List Archive »</a> |
|
||||
{% endif %}
|
||||
|
|
|
@ -58,7 +58,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
<tr class="header"><td colspan="7">{{doc_group.grouper}}s</td></tr>
|
||||
|
||||
{% for doc in doc_group.list %}
|
||||
{% include "idrfc/search_result_row.html" %}
|
||||
{% include "idrfc/search_result_row.html" %}
|
||||
{% endfor %}
|
||||
|
||||
{% endfor %}
|
||||
|
|
|
@ -58,6 +58,7 @@ urlpatterns = patterns('',
|
|||
(r'^wg/', include('ietf.wginfo.urls')),
|
||||
(r'^cookies/', include('ietf.cookies.urls')),
|
||||
(r'^submit/', include('ietf.submit.urls')),
|
||||
(r'^streams/', include('ietf.ietfworkflows.urls')),
|
||||
|
||||
(r'^$', 'ietf.idrfc.views.main'),
|
||||
(r'^admin/doc/', include('django.contrib.admindocs.urls')),
|
||||
|
|
0
ietf/wgchairs/__init__.py
Normal file
0
ietf/wgchairs/__init__.py
Normal file
90
ietf/wgchairs/accounts.py
Normal file
90
ietf/wgchairs/accounts.py
Normal file
|
@ -0,0 +1,90 @@
|
|||
def is_secretariat(user):
|
||||
if not user or not user.is_authenticated():
|
||||
return False
|
||||
return bool(user.groups.filter(name='Secretariat'))
|
||||
|
||||
|
||||
def is_area_director_for_group(person, group):
|
||||
return bool(group.area.area.areadirector_set.filter(person=person).count())
|
||||
|
||||
|
||||
def is_group_chair(person, group):
|
||||
if group.chairs().filter(person=person):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def is_group_delegate(person, group):
|
||||
return bool(group.wgdelegate_set.filter(person=person).count())
|
||||
|
||||
|
||||
def is_document_shepherd(person, document):
|
||||
return person == document.shepherd
|
||||
|
||||
|
||||
def get_person_for_user(user):
|
||||
try:
|
||||
return user.get_profile().person()
|
||||
except:
|
||||
return None
|
||||
|
||||
|
||||
def can_do_wg_workflow_in_group(user, group):
|
||||
person = get_person_for_user(user)
|
||||
if not person:
|
||||
return False
|
||||
return (is_secretariat(user) or is_group_chair(person, group))
|
||||
|
||||
|
||||
def can_do_wg_workflow_in_document(user, document):
|
||||
person = get_person_for_user(user)
|
||||
if not person or not document.group:
|
||||
return False
|
||||
return (is_secretariat(user) or can_do_wg_workflow_in_group(document.group.ietfwg))
|
||||
|
||||
|
||||
def can_manage_workflow_in_group(user, group):
|
||||
person = get_person_for_user(user)
|
||||
if not person:
|
||||
return False
|
||||
return (is_secretariat(user) or is_group_chair(person, group))
|
||||
|
||||
|
||||
def can_manage_delegates_in_group(user, group):
|
||||
person = get_person_for_user(user)
|
||||
if not person:
|
||||
return False
|
||||
return (is_secretariat(user) or is_group_chair(person, group))
|
||||
|
||||
|
||||
def can_manage_shepherds_in_group(user, group):
|
||||
person = get_person_for_user(user)
|
||||
if not person:
|
||||
return False
|
||||
return (is_secretariat(user) or is_group_chair(person, group))
|
||||
|
||||
|
||||
def can_manage_shepherd_of_a_document(user, document):
|
||||
person = get_person_for_user(user)
|
||||
if not person or not document.group:
|
||||
return False
|
||||
return can_manage_shepherds_in_group(user, document.group.ietfwg)
|
||||
|
||||
|
||||
def can_manage_writeup_of_a_document_no_state(user, document):
|
||||
person = get_person_for_user(user)
|
||||
if not person or not document.group:
|
||||
return False
|
||||
group = document.group.ietfwg
|
||||
return (is_secretariat(user) or
|
||||
is_group_chair(person, group) or
|
||||
is_area_director_for_group(person, group) or
|
||||
is_group_delegate(person, group))
|
||||
|
||||
|
||||
def can_manage_writeup_of_a_document(user, document):
|
||||
person = get_person_for_user(user)
|
||||
if not person or not document.group:
|
||||
return False
|
||||
return (can_manage_writeup_of_a_document_no_state(user, document) or
|
||||
is_document_shepherd(person, document))
|
388
ietf/wgchairs/forms.py
Normal file
388
ietf/wgchairs/forms.py
Normal file
|
@ -0,0 +1,388 @@
|
|||
from django import forms
|
||||
from django.conf import settings
|
||||
from django.core.mail import EmailMessage
|
||||
from django.forms.models import BaseModelFormSet
|
||||
from django.template.loader import render_to_string
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
from ietf.wgchairs.models import WGDelegate, ProtoWriteUp
|
||||
from ietf.wgchairs.accounts import get_person_for_user
|
||||
from ietf.ietfworkflows.constants import REQUIRED_STATES
|
||||
from ietf.ietfworkflows.utils import (get_default_workflow_for_wg, get_workflow_for_wg,
|
||||
update_tags, FOLLOWUP_TAG, get_state_by_name)
|
||||
from ietf.idtracker.models import PersonOrOrgInfo
|
||||
|
||||
from workflows.models import Transition
|
||||
|
||||
|
||||
class RelatedWGForm(forms.Form):
|
||||
|
||||
can_cancel = False
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.wg = kwargs.pop('wg', None)
|
||||
self.user = kwargs.pop('user', None)
|
||||
self.message = {}
|
||||
super(RelatedWGForm, self).__init__(*args, **kwargs)
|
||||
|
||||
def get_message(self):
|
||||
return self.message
|
||||
|
||||
def set_message(self, msg_type, msg_value):
|
||||
self.message = {'type': msg_type,
|
||||
'value': msg_value,
|
||||
}
|
||||
|
||||
|
||||
class TagForm(RelatedWGForm):
|
||||
|
||||
tags = forms.ModelMultipleChoiceField(get_default_workflow_for_wg().annotation_tags.all(),
|
||||
widget=forms.CheckboxSelectMultiple, required=False)
|
||||
|
||||
def save(self):
|
||||
workflow = get_workflow_for_wg(self.wg)
|
||||
workflow.selected_tags.clear()
|
||||
for tag in self.cleaned_data['tags']:
|
||||
workflow.selected_tags.add(tag)
|
||||
return workflow
|
||||
|
||||
|
||||
class StateForm(RelatedWGForm):
|
||||
|
||||
states = forms.ModelMultipleChoiceField(get_default_workflow_for_wg().states.all(),
|
||||
widget=forms.CheckboxSelectMultiple, required=False)
|
||||
|
||||
def update_transitions(self, workflow):
|
||||
for transition in workflow.transitions.all():
|
||||
if not workflow.selected_states.filter(pk=transition.destination.pk).count():
|
||||
transition.delete()
|
||||
continue
|
||||
for state in transition.states.all():
|
||||
if not workflow.selected_states.filter(pk=state.pk).count():
|
||||
transition.states.remove(state)
|
||||
if not transition.states.count():
|
||||
transition.delete()
|
||||
continue
|
||||
|
||||
def save(self):
|
||||
workflow = get_workflow_for_wg(self.wg)
|
||||
workflow.selected_states.clear()
|
||||
for state in self.cleaned_data['states']:
|
||||
workflow.selected_states.add(state)
|
||||
for name in REQUIRED_STATES:
|
||||
rstate = get_state_by_name(name)
|
||||
if rstate:
|
||||
workflow.selected_states.add(rstate)
|
||||
self.update_transitions(workflow)
|
||||
return workflow
|
||||
|
||||
|
||||
class DeleteTransitionForm(RelatedWGForm):
|
||||
|
||||
transitions = forms.ModelMultipleChoiceField(Transition.objects.all(),
|
||||
widget=forms.CheckboxSelectMultiple)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(DeleteTransitionForm, self).__init__(*args, **kwargs)
|
||||
workflow = get_workflow_for_wg(self.wg)
|
||||
self.fields['transitions'].queryset = self.fields['transitions'].queryset.filter(workflow=workflow)
|
||||
|
||||
def save(self):
|
||||
for transition in self.cleaned_data['transitions']:
|
||||
transition.delete()
|
||||
|
||||
|
||||
class TransitionForm(forms.ModelForm):
|
||||
|
||||
states = forms.ModelMultipleChoiceField(get_default_workflow_for_wg().states.all())
|
||||
|
||||
class Meta:
|
||||
model = Transition
|
||||
fields = ('DELETE', 'name', 'states', 'destination', )
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.wg = kwargs.pop('wg', None)
|
||||
self.user = kwargs.pop('user', None)
|
||||
super(TransitionForm, self).__init__(*args, **kwargs)
|
||||
workflow = get_workflow_for_wg(self.wg)
|
||||
self.fields['states'].queryset = workflow.selected_states.all()
|
||||
self.fields['destination'].queryset = workflow.selected_states.all()
|
||||
self.fields['destination'].required = True
|
||||
if self.instance.pk:
|
||||
self.fields['states'].initial = [i.pk for i in self.instance.states.all()]
|
||||
self.instance.workflow = workflow
|
||||
|
||||
def as_row(self):
|
||||
return self._html_output(u'<td>%(errors)s%(field)s%(help_text)s</td>', u'<td colspan="2">%s</td>', '</td>', u'<br />%s', False)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
instance = super(TransitionForm, self).save(*args, **kwargs)
|
||||
for state in self.cleaned_data['states']:
|
||||
state.transitions.add(instance)
|
||||
|
||||
|
||||
class TransitionFormSet(BaseModelFormSet):
|
||||
|
||||
form = TransitionForm
|
||||
can_delete = True
|
||||
extra = 2
|
||||
max_num = 0
|
||||
can_order = False
|
||||
model = Transition
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.wg = kwargs.pop('wg', None)
|
||||
self.user = kwargs.pop('user', None)
|
||||
super(TransitionFormSet, self).__init__(*args, **kwargs)
|
||||
|
||||
def _construct_form(self, i, **kwargs):
|
||||
kwargs = kwargs or {}
|
||||
kwargs.update({'wg': self.wg, 'user': self.user})
|
||||
return super(TransitionFormSet, self)._construct_form(i, **kwargs)
|
||||
|
||||
def as_table(self):
|
||||
html = u''
|
||||
csscl = 'oddrow'
|
||||
for form in self.forms:
|
||||
html += u'<tr class="%s">' % csscl
|
||||
html += form.as_row()
|
||||
html += u'</tr>'
|
||||
if csscl == 'oddrow':
|
||||
csscl = 'evenrow'
|
||||
else:
|
||||
csscl = 'oddrow'
|
||||
return mark_safe(u'\n'.join([unicode(self.management_form), html]))
|
||||
|
||||
|
||||
def workflow_form_factory(request, wg, user):
|
||||
|
||||
if request.POST.get('update_transitions', None):
|
||||
return TransitionFormSet(wg=wg, user=user, data=request.POST)
|
||||
elif request.POST.get('update_states', None):
|
||||
return StateForm(wg=wg, user=user, data=request.POST)
|
||||
return TagForm(wg=wg, user=user, data=request.POST)
|
||||
|
||||
|
||||
class RemoveDelegateForm(RelatedWGForm):
|
||||
|
||||
delete = forms.MultipleChoiceField()
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(RemoveDelegateForm, self).__init__(*args, **kwargs)
|
||||
self.fields['delete'].choices = [(i.pk, i.pk) for i in self.wg.wgdelegate_set.all()]
|
||||
|
||||
def save(self):
|
||||
delegates = self.cleaned_data.get('delete')
|
||||
WGDelegate.objects.filter(pk__in=delegates).delete()
|
||||
self.set_message('success', 'Delegates removed')
|
||||
|
||||
|
||||
class AddDelegateForm(RelatedWGForm):
|
||||
|
||||
email = forms.EmailField()
|
||||
form_type = forms.CharField(widget=forms.HiddenInput, initial='single')
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.shepherd = kwargs.pop('shepherd', False)
|
||||
super(AddDelegateForm, self).__init__(*args, **kwargs)
|
||||
self.next_form = self
|
||||
|
||||
def get_next_form(self):
|
||||
return self.next_form
|
||||
|
||||
def get_person(self, email):
|
||||
persons = PersonOrOrgInfo.objects.filter(emailaddress__address=email, iesglogin__isnull=False).distinct()
|
||||
if not persons:
|
||||
raise PersonOrOrgInfo.DoesNotExist
|
||||
if len(persons) > 1:
|
||||
raise PersonOrOrgInfo.MultipleObjectsReturned
|
||||
return persons[0]
|
||||
|
||||
def save(self):
|
||||
email = self.cleaned_data.get('email')
|
||||
try:
|
||||
person = self.get_person(email)
|
||||
except PersonOrOrgInfo.DoesNotExist:
|
||||
self.next_form = NotExistDelegateForm(wg=self.wg, user=self.user, email=email, shepherd=self.shepherd)
|
||||
self.next_form.set_message('doesnotexist', 'There is no user with this email allowed to login to the system')
|
||||
return
|
||||
except PersonOrOrgInfo.MultipleObjectsReturned:
|
||||
self.next_form = MultipleDelegateForm(wg=self.wg, user=self.user, email=email, shepherd=self.shepherd)
|
||||
self.next_form.set_message('multiple', 'There are multiple users with this email in the system')
|
||||
return
|
||||
if self.shepherd:
|
||||
self.assign_shepherd(person)
|
||||
else:
|
||||
self.create_delegate(person)
|
||||
|
||||
def assign_shepherd(self, person):
|
||||
self.shepherd.shepherd = person
|
||||
self.shepherd.save()
|
||||
self.next_form = AddDelegateForm(wg=self.wg, user=self.user, shepherd=self.shepherd)
|
||||
self.next_form.set_message('success', 'Shepherd assigned successfully')
|
||||
|
||||
def create_delegate(self, person):
|
||||
(delegate, created) = WGDelegate.objects.get_or_create(wg=self.wg,
|
||||
person=person)
|
||||
if not created:
|
||||
self.set_message('error', 'The email belongs to a person who is already a delegate')
|
||||
else:
|
||||
self.next_form = AddDelegateForm(wg=self.wg, user=self.user)
|
||||
self.next_form.set_message('success', 'A new delegate has been added')
|
||||
|
||||
|
||||
class MultipleDelegateForm(AddDelegateForm):
|
||||
|
||||
email = forms.EmailField(widget=forms.HiddenInput)
|
||||
form_type = forms.CharField(widget=forms.HiddenInput, initial='multiple')
|
||||
persons = forms.ChoiceField(widget=forms.RadioSelect, help_text='Please select one person from the list')
|
||||
submit_msg = 'Designate as delegate'
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.email = kwargs.pop('email', None)
|
||||
super(MultipleDelegateForm, self).__init__(*args, **kwargs)
|
||||
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')]
|
||||
|
||||
def save(self):
|
||||
person_id = self.cleaned_data.get('persons')
|
||||
person = PersonOrOrgInfo.objects.get(pk=person_id)
|
||||
if self.shepherd:
|
||||
self.assign_shepherd(person)
|
||||
else:
|
||||
self.create_delegate(person)
|
||||
|
||||
|
||||
class NotExistDelegateForm(MultipleDelegateForm):
|
||||
|
||||
email = forms.EmailField(widget=forms.HiddenInput)
|
||||
form_type = forms.CharField(widget=forms.HiddenInput, initial='notexist')
|
||||
can_cancel = True
|
||||
submit_msg = 'Send email to these addresses'
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(NotExistDelegateForm, self).__init__(*args, **kwargs)
|
||||
self.email_list = []
|
||||
del(self.fields['persons'])
|
||||
|
||||
def get_email_list(self):
|
||||
if self.email_list:
|
||||
return self.email_list
|
||||
email_list = [self.email]
|
||||
email_list.append('IETF Secretariat <iesg-secretary@ietf.org>')
|
||||
email_list += ['%s <%s>' % i.person.email() for i in self.wg.wgchair_set.all() if i.person.email()]
|
||||
self.email_list = email_list
|
||||
return email_list
|
||||
|
||||
def as_p(self):
|
||||
email_list = self.get_email_list()
|
||||
info = render_to_string('wgchairs/notexistdelegate.html', {'email_list': email_list, 'shepherd': self.shepherd})
|
||||
return info + super(NotExistDelegateForm, self).as_p()
|
||||
|
||||
def send_email(self, email, template):
|
||||
if self.shepherd:
|
||||
subject = 'WG shepherd needs system credentials'
|
||||
else:
|
||||
subject = 'WG Delegate needs system credentials'
|
||||
persons = PersonOrOrgInfo.objects.filter(emailaddress__address=self.email).distinct()
|
||||
body = render_to_string(template,
|
||||
{'chair': get_person_for_user(self.user),
|
||||
'delegate_email': self.email,
|
||||
'shepherd': self.shepherd,
|
||||
'delegate_persons': persons,
|
||||
'wg': self.wg,
|
||||
})
|
||||
mail = EmailMessage(subject=subject,
|
||||
body=body,
|
||||
to=email,
|
||||
from_email=settings.DEFAULT_FROM_EMAIL)
|
||||
mail.send()
|
||||
|
||||
def send_email_to_delegate(self, email):
|
||||
self.send_email(email, 'wgchairs/notexistsdelegate_delegate_email.txt')
|
||||
|
||||
def send_email_to_secretariat(self, email):
|
||||
self.send_email(email, 'wgchairs/notexistsdelegate_secretariat_email.txt')
|
||||
|
||||
def send_email_to_wgchairs(self, email):
|
||||
self.send_email(email, 'wgchairs/notexistsdelegate_wgchairs_email.txt')
|
||||
|
||||
def save(self):
|
||||
self.next_form = AddDelegateForm(wg=self.wg, user=self.user)
|
||||
if settings.DEBUG:
|
||||
self.next_form.set_message('warning', 'Email was not sent cause tool is in DEBUG mode')
|
||||
else:
|
||||
email_list = self.get_email_list()
|
||||
self.send_email_to_delegate([email_list[0]])
|
||||
self.send_email_to_secretariat([email_list[1]])
|
||||
self.send_email_to_wgchairs(email_list[2:])
|
||||
self.next_form.set_message('success', 'Email sent successfully')
|
||||
|
||||
|
||||
def add_form_factory(request, wg, user, shepherd=False):
|
||||
if request.method != 'POST' or request.POST.get('update_shepehrd'):
|
||||
return AddDelegateForm(wg=wg, user=user, shepherd=shepherd)
|
||||
|
||||
if request.POST.get('form_type', None) == 'multiple':
|
||||
return MultipleDelegateForm(wg=wg, user=user, data=request.POST.copy(), shepherd=shepherd)
|
||||
elif request.POST.get('form_type', None) == 'notexist':
|
||||
return NotExistDelegateForm(wg=wg, user=user, data=request.POST.copy(), shepherd=shepherd)
|
||||
elif request.POST.get('form_type', None) == 'single':
|
||||
return AddDelegateForm(wg=wg, user=user, data=request.POST.copy(), shepherd=shepherd)
|
||||
|
||||
return AddDelegateForm(wg=wg, user=user, shepherd=shepherd)
|
||||
|
||||
|
||||
class WriteUpEditForm(RelatedWGForm):
|
||||
|
||||
writeup = forms.CharField(widget=forms.Textarea, required=False)
|
||||
followup = forms.BooleanField(required=False)
|
||||
comment = forms.CharField(widget=forms.Textarea, required=False)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.doc = kwargs.pop('doc', None)
|
||||
self.doc_writeup = self.doc.protowriteup_set.all()
|
||||
if self.doc_writeup.count():
|
||||
self.doc_writeup = self.doc_writeup[0]
|
||||
else:
|
||||
self.doc_writeup = None
|
||||
super(WriteUpEditForm, self).__init__(*args, **kwargs)
|
||||
self.person = get_person_for_user(self.user)
|
||||
|
||||
def get_writeup(self):
|
||||
return self.data.get('writeup', self.doc_writeup and self.doc_writeup.writeup or '')
|
||||
|
||||
def save(self):
|
||||
if not self.doc_writeup:
|
||||
self.doc_writeup = ProtoWriteUp.objects.create(
|
||||
person=self.person,
|
||||
draft=self.doc,
|
||||
writeup=self.cleaned_data['writeup'])
|
||||
else:
|
||||
self.doc_writeup.writeup = self.cleaned_data['writeup']
|
||||
self.doc_writeup.save()
|
||||
if self.data.get('modify_tag', False):
|
||||
followup = self.cleaned_data.get('followup', False)
|
||||
comment = self.cleaned_data.get('comment', False)
|
||||
try:
|
||||
shepherd = self.doc.shepherd
|
||||
except PersonOrOrgInfo.DoesNotExist:
|
||||
shepherd = None
|
||||
if shepherd:
|
||||
extra_notify = ['%s <%s>' % shepherd.email()]
|
||||
else:
|
||||
extra_notify = []
|
||||
if followup:
|
||||
update_tags(self.doc, comment, self.person, set_tags=[FOLLOWUP_TAG], extra_notify=extra_notify)
|
||||
else:
|
||||
update_tags(self.doc, comment, self.person, reset_tags=[FOLLOWUP_TAG], extra_notify=extra_notify)
|
||||
return self.doc_writeup
|
||||
|
||||
def is_valid(self):
|
||||
if self.data.get('confirm', False) and self.data.get('modify_tag', False):
|
||||
self.fields['comment'].required = True
|
||||
else:
|
||||
self.fields['comment'].required = False
|
||||
return super(WriteUpEditForm, self).is_valid()
|
110
ietf/wgchairs/migrations/0001_initial.py
Normal file
110
ietf/wgchairs/migrations/0001_initial.py
Normal file
|
@ -0,0 +1,110 @@
|
|||
|
||||
from south.db import db
|
||||
from django.db import models
|
||||
from ietf.wgchairs.models import *
|
||||
|
||||
class Migration:
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Adding model 'WGDelegate'
|
||||
db.create_table('wgchairs_wgdelegate', (
|
||||
('id', orm['wgchairs.WGDelegate:id']),
|
||||
('person', orm['wgchairs.WGDelegate:person']),
|
||||
('wg', orm['wgchairs.WGDelegate:wg']),
|
||||
))
|
||||
db.send_create_signal('wgchairs', ['WGDelegate'])
|
||||
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Deleting model 'WGDelegate'
|
||||
db.delete_table('wgchairs_wgdelegate')
|
||||
|
||||
|
||||
|
||||
models = {
|
||||
'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.area': {
|
||||
'Meta': {'db_table': "'areas'"},
|
||||
'area_acronym': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['idtracker.Acronym']", 'unique': 'True', 'primary_key': 'True'}),
|
||||
'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'concluded_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'extra_email_addresses': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'last_modified_date': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'blank': 'True'}),
|
||||
'start_date': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.AreaStatus']"})
|
||||
},
|
||||
'idtracker.areadirector': {
|
||||
'Meta': {'db_table': "'area_directors'"},
|
||||
'area': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Area']", 'null': 'True', 'db_column': "'area_acronym_id'"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"})
|
||||
},
|
||||
'idtracker.areastatus': {
|
||||
'Meta': {'db_table': "'area_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.ietfwg': {
|
||||
'Meta': {'db_table': "'groups_ietf'"},
|
||||
'area_director': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.AreaDirector']", 'null': 'True'}),
|
||||
'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'concluded_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'dormant_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'email_address': ('django.db.models.fields.CharField', [], {'max_length': '60', 'blank': 'True'}),
|
||||
'email_archive': ('django.db.models.fields.CharField', [], {'max_length': '95', 'blank': 'True'}),
|
||||
'email_keyword': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
|
||||
'email_subscribe': ('django.db.models.fields.CharField', [], {'max_length': '120', 'blank': 'True'}),
|
||||
'group_acronym': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['idtracker.Acronym']", 'unique': 'True', 'primary_key': 'True'}),
|
||||
'group_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.WGType']"}),
|
||||
'last_modified_date': ('django.db.models.fields.DateField', [], {}),
|
||||
'meeting_scheduled': ('django.db.models.fields.CharField', [], {'max_length': '3', 'blank': 'True'}),
|
||||
'meeting_scheduled_old': ('django.db.models.fields.CharField', [], {'max_length': '3', 'blank': 'True'}),
|
||||
'proposed_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.WGStatus']"})
|
||||
},
|
||||
'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'})
|
||||
},
|
||||
'idtracker.wgstatus': {
|
||||
'Meta': {'db_table': "'g_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.wgtype': {
|
||||
'Meta': {'db_table': "'g_type'"},
|
||||
'group_type_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'type': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'group_type'"})
|
||||
},
|
||||
'wgchairs.wgdelegate': {
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}),
|
||||
'wg': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IETFWG']"})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['wgchairs']
|
163
ietf/wgchairs/migrations/0002_add_writeup.py
Normal file
163
ietf/wgchairs/migrations/0002_add_writeup.py
Normal file
|
@ -0,0 +1,163 @@
|
|||
|
||||
from south.db import db
|
||||
from django.db import models
|
||||
from ietf.wgchairs.models import *
|
||||
|
||||
class Migration:
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Adding model 'ProtoWriteUp'
|
||||
db.create_table('wgchairs_protowriteup', (
|
||||
('id', orm['wgchairs.protowriteup:id']),
|
||||
('person', orm['wgchairs.protowriteup:person']),
|
||||
('draft', orm['wgchairs.protowriteup:draft']),
|
||||
('date', orm['wgchairs.protowriteup:date']),
|
||||
('writeup', orm['wgchairs.protowriteup:writeup']),
|
||||
))
|
||||
db.send_create_signal('wgchairs', ['ProtoWriteUp'])
|
||||
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Deleting model 'ProtoWriteUp'
|
||||
db.delete_table('wgchairs_protowriteup')
|
||||
|
||||
|
||||
|
||||
models = {
|
||||
'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.area': {
|
||||
'Meta': {'db_table': "'areas'"},
|
||||
'area_acronym': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['idtracker.Acronym']", 'unique': 'True', 'primary_key': 'True'}),
|
||||
'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'concluded_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'extra_email_addresses': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'last_modified_date': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'blank': 'True'}),
|
||||
'start_date': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.AreaStatus']"})
|
||||
},
|
||||
'idtracker.areadirector': {
|
||||
'Meta': {'db_table': "'area_directors'"},
|
||||
'area': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.Area']", 'null': 'True', 'db_column': "'area_acronym_id'"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']", 'db_column': "'person_or_org_tag'"})
|
||||
},
|
||||
'idtracker.areastatus': {
|
||||
'Meta': {'db_table': "'area_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.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.ietfwg': {
|
||||
'Meta': {'db_table': "'groups_ietf'"},
|
||||
'area_director': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.AreaDirector']", 'null': 'True'}),
|
||||
'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'concluded_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'dormant_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'email_address': ('django.db.models.fields.CharField', [], {'max_length': '60', 'blank': 'True'}),
|
||||
'email_archive': ('django.db.models.fields.CharField', [], {'max_length': '95', 'blank': 'True'}),
|
||||
'email_keyword': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
|
||||
'email_subscribe': ('django.db.models.fields.CharField', [], {'max_length': '120', 'blank': 'True'}),
|
||||
'group_acronym': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['idtracker.Acronym']", 'unique': 'True', 'primary_key': 'True'}),
|
||||
'group_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.WGType']"}),
|
||||
'last_modified_date': ('django.db.models.fields.DateField', [], {}),
|
||||
'meeting_scheduled': ('django.db.models.fields.CharField', [], {'max_length': '3', 'blank': 'True'}),
|
||||
'meeting_scheduled_old': ('django.db.models.fields.CharField', [], {'max_length': '3', 'blank': 'True'}),
|
||||
'proposed_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.WGStatus']"})
|
||||
},
|
||||
'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', [], {'to': "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'})
|
||||
},
|
||||
'idtracker.wgstatus': {
|
||||
'Meta': {'db_table': "'g_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.wgtype': {
|
||||
'Meta': {'db_table': "'g_type'"},
|
||||
'group_type_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'type': ('django.db.models.fields.CharField', [], {'max_length': '25', 'db_column': "'group_type'"})
|
||||
},
|
||||
'wgchairs.protowriteup': {
|
||||
'date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now()'}),
|
||||
'draft': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.InternetDraft']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}),
|
||||
'writeup': ('django.db.models.fields.TextField', [], {})
|
||||
},
|
||||
'wgchairs.wgdelegate': {
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.PersonOrOrgInfo']"}),
|
||||
'wg': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['idtracker.IETFWG']"})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['wgchairs']
|
0
ietf/wgchairs/migrations/__init__.py
Normal file
0
ietf/wgchairs/migrations/__init__.py
Normal file
45
ietf/wgchairs/models.py
Normal file
45
ietf/wgchairs/models.py
Normal file
|
@ -0,0 +1,45 @@
|
|||
import datetime
|
||||
|
||||
from django.db import models
|
||||
|
||||
from ietf.idtracker.models import (IETFWG, PersonOrOrgInfo,
|
||||
InternetDraft)
|
||||
|
||||
|
||||
class WGDelegate(models.Model):
|
||||
person = models.ForeignKey(
|
||||
PersonOrOrgInfo,
|
||||
)
|
||||
|
||||
wg = models.ForeignKey(IETFWG)
|
||||
|
||||
def __unicode__(self):
|
||||
return "%s" % self.person
|
||||
|
||||
class Meta:
|
||||
verbose_name = "WG Delegate"
|
||||
|
||||
|
||||
class ProtoWriteUp(models.Model):
|
||||
person = models.ForeignKey(
|
||||
PersonOrOrgInfo,
|
||||
blank=False,
|
||||
null=False,
|
||||
)
|
||||
|
||||
draft = models.ForeignKey(
|
||||
InternetDraft,
|
||||
blank=False,
|
||||
null=False,
|
||||
)
|
||||
|
||||
date = models.DateTimeField(
|
||||
default=datetime.datetime.now(),
|
||||
blank=False,
|
||||
null=False,
|
||||
)
|
||||
|
||||
writeup = models.TextField(
|
||||
blank=False,
|
||||
null=False,
|
||||
)
|
0
ietf/wgchairs/templatetags/__init__.py
Normal file
0
ietf/wgchairs/templatetags/__init__.py
Normal file
46
ietf/wgchairs/templatetags/wgchairs_tags.py
Normal file
46
ietf/wgchairs/templatetags/wgchairs_tags.py
Normal file
|
@ -0,0 +1,46 @@
|
|||
from django import template
|
||||
|
||||
from ietf.ietfworkflows.utils import get_state_for_draft
|
||||
from ietf.wgchairs.accounts import (can_manage_workflow_in_group,
|
||||
can_manage_delegates_in_group,
|
||||
can_manage_shepherds_in_group)
|
||||
|
||||
|
||||
register = template.Library()
|
||||
|
||||
|
||||
@register.inclusion_tag('wgchairs/wgchairs_admin_options.html', takes_context=True)
|
||||
def wgchairs_admin_options(context, wg):
|
||||
request = context.get('request', None)
|
||||
user = request and request.user
|
||||
return {'user': user,
|
||||
'can_manage_delegates': can_manage_delegates_in_group(user, wg),
|
||||
'can_manage_workflow': can_manage_workflow_in_group(user, wg),
|
||||
'can_manage_shepherds': can_manage_shepherds_in_group(user, wg),
|
||||
'wg': wg,
|
||||
'selected': context.get('selected', None),
|
||||
}
|
||||
|
||||
@register.simple_tag
|
||||
def writeup(doc):
|
||||
writeup = doc.protowriteup_set.all()
|
||||
if not writeup.count():
|
||||
return ''
|
||||
else:
|
||||
return writeup[0].writeup
|
||||
|
||||
|
||||
@register.simple_tag
|
||||
def writeupdate(doc):
|
||||
writeup = doc.protowriteup_set.all()
|
||||
if not writeup.count():
|
||||
return ''
|
||||
else:
|
||||
return writeup[0].date
|
||||
|
||||
|
||||
@register.inclusion_tag('wgchairs/draft_state.html', takes_context=True)
|
||||
def show_state(context, doc):
|
||||
return {'doc': doc,
|
||||
'state': get_state_for_draft(doc),
|
||||
}
|
11
ietf/wgchairs/urls.py
Normal file
11
ietf/wgchairs/urls.py
Normal file
|
@ -0,0 +1,11 @@
|
|||
# Copyright The IETF Trust 2008, All Rights Reserved
|
||||
|
||||
from django.conf.urls.defaults import patterns, url
|
||||
|
||||
urlpatterns = patterns('ietf.wgchairs.views',
|
||||
url(r'^workflows/$', 'manage_workflow', name='manage_workflow'),
|
||||
url(r'^delegates/$', 'manage_delegates', name='manage_delegates'),
|
||||
url(r'^shepherds/$', 'wg_shepherd_documents', name='manage_shepherds'),
|
||||
url(r'^shepherds/(?P<name>[^/]+)/$', 'managing_shepherd', name='doc_managing_shepherd'),
|
||||
url(r'^shepherds/(?P<name>[^/]+)/writeup/$', 'managing_writeup', name='doc_managing_writeup'),
|
||||
)
|
214
ietf/wgchairs/views.py
Normal file
214
ietf/wgchairs/views.py
Normal file
|
@ -0,0 +1,214 @@
|
|||
from django.conf import settings
|
||||
from ietf.idtracker.models import IETFWG, InternetDraft
|
||||
from django.shortcuts import get_object_or_404, render_to_response
|
||||
from django.template import RequestContext
|
||||
from django.http import HttpResponseForbidden, Http404
|
||||
|
||||
from ietf.idrfc.views_search import SearchForm, search_query
|
||||
from ietf.wgchairs.forms import (RemoveDelegateForm, add_form_factory,
|
||||
workflow_form_factory, TransitionFormSet,
|
||||
WriteUpEditForm)
|
||||
from ietf.wgchairs.accounts import (can_manage_delegates_in_group, get_person_for_user,
|
||||
can_manage_shepherds_in_group,
|
||||
can_manage_workflow_in_group,
|
||||
can_manage_shepherd_of_a_document,
|
||||
can_manage_writeup_of_a_document,
|
||||
can_manage_writeup_of_a_document_no_state,
|
||||
)
|
||||
from ietf.ietfworkflows.constants import REQUIRED_STATES
|
||||
from ietf.ietfworkflows.utils import (get_workflow_for_wg,
|
||||
get_default_workflow_for_wg,
|
||||
get_state_by_name,
|
||||
get_annotation_tags_for_draft,
|
||||
get_state_for_draft, WAITING_WRITEUP,
|
||||
FOLLOWUP_TAG)
|
||||
|
||||
|
||||
def manage_delegates(request, acronym):
|
||||
wg = get_object_or_404(IETFWG, group_acronym__acronym=acronym, group_type=1)
|
||||
user = request.user
|
||||
if not can_manage_delegates_in_group(user, wg):
|
||||
return HttpResponseForbidden('You have no permission to access this view')
|
||||
delegates = wg.wgdelegate_set.all()
|
||||
add_form = add_form_factory(request, wg, user)
|
||||
if request.method == 'POST':
|
||||
if request.POST.get('remove', None):
|
||||
form = RemoveDelegateForm(wg=wg, data=request.POST.copy())
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
elif add_form.is_valid():
|
||||
add_form.save()
|
||||
add_form = add_form.get_next_form()
|
||||
max_delegates = getattr(settings, 'MAX_WG_DELEGATES', 3)
|
||||
return render_to_response('wgchairs/manage_delegates.html',
|
||||
{'wg': wg,
|
||||
'delegates': delegates,
|
||||
'selected': 'manage_delegates',
|
||||
'can_add': delegates.count() < max_delegates,
|
||||
'max_delegates': max_delegates,
|
||||
'add_form': add_form,
|
||||
}, RequestContext(request))
|
||||
|
||||
|
||||
def manage_workflow(request, acronym):
|
||||
wg = get_object_or_404(IETFWG, group_acronym__acronym=acronym, group_type=1)
|
||||
user = request.user
|
||||
if not can_manage_workflow_in_group(user, wg):
|
||||
return HttpResponseForbidden('You have no permission to access this view')
|
||||
workflow = get_workflow_for_wg(wg)
|
||||
default_workflow = get_default_workflow_for_wg()
|
||||
formset = None
|
||||
if request.method == 'POST':
|
||||
form = workflow_form_factory(request, wg=wg, user=user)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
elif isinstance(form, TransitionFormSet):
|
||||
formset = form
|
||||
tags = workflow.selected_tags.all()
|
||||
default_tags = default_workflow.annotation_tags.all()
|
||||
states = workflow.selected_states.all().order_by('statedescription__order')
|
||||
default_states = default_workflow.states.all().order_by('statedescription__order')
|
||||
for i in default_states:
|
||||
if states.filter(name=i.name).count() == 1:
|
||||
i.used = True
|
||||
if i.name in REQUIRED_STATES:
|
||||
i.freeze = True
|
||||
for i in default_tags:
|
||||
if tags.filter(name=i.name).count() == 1:
|
||||
i.used = True
|
||||
if not formset:
|
||||
formset = TransitionFormSet(queryset=workflow.transitions.all(), user=user, wg=wg)
|
||||
|
||||
return render_to_response('wgchairs/manage_workflow.html',
|
||||
{'wg': wg,
|
||||
'workflow': workflow,
|
||||
'default_workflow': default_workflow,
|
||||
'states': states,
|
||||
'tags': tags,
|
||||
'default_states': default_states,
|
||||
'default_tags': default_tags,
|
||||
'formset': formset,
|
||||
'selected': 'manage_workflow',
|
||||
}, RequestContext(request))
|
||||
|
||||
|
||||
def managing_shepherd(request, acronym, name):
|
||||
"""
|
||||
View for managing the assigned shepherd of a document.
|
||||
"""
|
||||
wg = get_object_or_404(IETFWG, group_acronym__acronym=acronym, group_type=1)
|
||||
user = request.user
|
||||
person = get_person_for_user(user)
|
||||
if not can_manage_shepherds_in_group(user, wg):
|
||||
return HttpResponseForbidden('You have no permission to access this view')
|
||||
doc = get_object_or_404(InternetDraft, filename=name)
|
||||
if not can_manage_shepherd_of_a_document(user, doc):
|
||||
raise Http404
|
||||
add_form = add_form_factory(request, wg, user, shepherd=doc)
|
||||
if request.method == 'POST':
|
||||
if request.POST.get('remove_shepherd'):
|
||||
doc.shepherd = None
|
||||
doc.save()
|
||||
elif request.POST.get('setme'):
|
||||
doc.shepherd = person
|
||||
doc.save()
|
||||
elif add_form.is_valid():
|
||||
add_form.save()
|
||||
add_form = add_form.get_next_form()
|
||||
return render_to_response('wgchairs/edit_management_shepherd.html',
|
||||
dict(doc=doc,
|
||||
form=add_form,
|
||||
user=user,
|
||||
selected='manage_shepherds',
|
||||
wg=wg,
|
||||
),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
||||
def wg_shepherd_documents(request, acronym):
|
||||
wg = get_object_or_404(IETFWG, group_acronym__acronym=acronym, group_type=1)
|
||||
user = request.user
|
||||
if not can_manage_shepherds_in_group(user, wg):
|
||||
return HttpResponseForbidden('You have no permission to access this view')
|
||||
current_person = get_person_for_user(user)
|
||||
|
||||
form = SearchForm({'by': 'group', 'group': str(wg.group_acronym.acronym),
|
||||
'activeDrafts': 'on'})
|
||||
if not form.is_valid():
|
||||
raise ValueError("form did not validate")
|
||||
(docs, meta) = search_query(form.cleaned_data)
|
||||
|
||||
base_qs = InternetDraft.objects.filter(pk__in=[i.id._draft.pk for i in docs if i.id]).select_related('status')
|
||||
documents_no_shepherd = base_qs.filter(shepherd__isnull=True)
|
||||
documents_my = base_qs.filter(shepherd=current_person)
|
||||
documents_other = base_qs.exclude(shepherd__isnull=True).exclude(shepherd__pk__in=[current_person.pk, 0])
|
||||
context = {
|
||||
'no_shepherd': documents_no_shepherd,
|
||||
'my_documents': documents_my,
|
||||
'other_shepherds': documents_other,
|
||||
'selected': 'manage_shepherds',
|
||||
'wg': wg,
|
||||
}
|
||||
return render_to_response('wgchairs/wg_shepherd_documents.html', context, RequestContext(request))
|
||||
|
||||
|
||||
def managing_writeup(request, acronym, name):
|
||||
wg = get_object_or_404(IETFWG, group_acronym__acronym=acronym, group_type=1)
|
||||
user = request.user
|
||||
doc = get_object_or_404(InternetDraft, filename=name)
|
||||
if not can_manage_writeup_of_a_document(user, doc):
|
||||
raise Http404
|
||||
current_state = get_state_for_draft(doc)
|
||||
can_edit = True
|
||||
if current_state != get_state_by_name(WAITING_WRITEUP) and not can_manage_writeup_of_a_document_no_state(user, doc):
|
||||
can_edit = False
|
||||
writeup = doc.protowriteup_set.all()
|
||||
if writeup.count():
|
||||
writeup = writeup[0]
|
||||
else:
|
||||
writeup = None
|
||||
error = False
|
||||
followup_tag = get_annotation_tags_for_draft(doc).filter(annotation_tag__name=FOLLOWUP_TAG)
|
||||
followup = bool(followup_tag.count())
|
||||
if request.method == 'POST':
|
||||
form = WriteUpEditForm(wg=wg, doc=doc, user=user, data=request.POST, files=request.FILES)
|
||||
if request.FILES.get('uploaded_writeup', None):
|
||||
try:
|
||||
newwriteup = request.FILES['uploaded_writeup'].read().encode('ascii')
|
||||
form.data.update({'writeup': newwriteup})
|
||||
except:
|
||||
form.set_message('error', 'You have try to upload a non ascii file')
|
||||
error = True
|
||||
valid = form.is_valid()
|
||||
if (valid and not error and not request.POST.get('confirm', None)) or (not valid and not error):
|
||||
if not valid:
|
||||
form.set_message('error', 'You have to specify a comment')
|
||||
return render_to_response('wgchairs/confirm_management_writeup.html',
|
||||
dict(doc=doc,
|
||||
user=user,
|
||||
selected='manage_shepherds',
|
||||
wg=wg,
|
||||
followup=followup,
|
||||
form=form,
|
||||
writeup=writeup,
|
||||
can_edit=can_edit,
|
||||
),
|
||||
context_instance=RequestContext(request))
|
||||
elif valid and not error:
|
||||
writeup = form.save()
|
||||
form = WriteUpEditForm(wg=wg, doc=doc, user=user)
|
||||
followup_tag = get_annotation_tags_for_draft(doc).filter(annotation_tag__name=FOLLOWUP_TAG)
|
||||
followup = bool(followup_tag.count())
|
||||
else:
|
||||
form = WriteUpEditForm(wg=wg, doc=doc, user=user)
|
||||
return render_to_response('wgchairs/edit_management_writeup.html',
|
||||
dict(doc=doc,
|
||||
user=user,
|
||||
selected='manage_shepherds',
|
||||
wg=wg,
|
||||
form=form,
|
||||
writeup=writeup,
|
||||
followup=followup,
|
||||
can_edit=can_edit,
|
||||
),
|
||||
context_instance=RequestContext(request))
|
|
@ -1,6 +1,6 @@
|
|||
# Copyright The IETF Trust 2008, All Rights Reserved
|
||||
|
||||
from django.conf.urls.defaults import patterns
|
||||
from django.conf.urls.defaults import patterns, include
|
||||
from ietf.wginfo import views
|
||||
from django.views.generic.simple import redirect_to
|
||||
|
||||
|
@ -16,4 +16,5 @@ urlpatterns = patterns('',
|
|||
(r'^(?P<acronym>[a-z0-9-]+)/documents/txt/$', views.wg_documents_txt),
|
||||
(r'^(?P<acronym>[a-z0-9-]+)/$', views.wg_documents_html),
|
||||
(r'^(?P<acronym>[a-z0-9-]+)/charter/$', views.wg_charter),
|
||||
(r'^(?P<acronym>[^/]+)/management/', include('ietf.wgchairs.urls')),
|
||||
)
|
||||
|
|
148
permissions/__init__.py
Normal file
148
permissions/__init__.py
Normal file
|
@ -0,0 +1,148 @@
|
|||
import permissions.utils
|
||||
|
||||
class PermissionBase(object):
|
||||
"""Mix-in class for permissions.
|
||||
"""
|
||||
def grant_permission(self, role, permission):
|
||||
"""Grants passed permission to passed role. Returns True if the
|
||||
permission was able to be added, otherwise False.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
role
|
||||
The role for which the permission should be granted.
|
||||
|
||||
permission
|
||||
The permission which should be granted. Either a permission
|
||||
object or the codename of a permission.
|
||||
"""
|
||||
return permissions.utils.grant_permission(self, role, permission)
|
||||
|
||||
def remove_permission(self, role, permission):
|
||||
"""Removes passed permission from passed role. Returns True if the
|
||||
permission has been removed.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
role
|
||||
The role for which a permission should be removed.
|
||||
|
||||
permission
|
||||
The permission which should be removed. Either a permission object
|
||||
or the codename of a permission.
|
||||
"""
|
||||
return permissions.utils.remove_permission(self, role, permission)
|
||||
|
||||
def has_permission(self, user, permission, roles=[]):
|
||||
"""Returns True if the passed user has passed permission for this
|
||||
instance. Otherwise False.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
permission
|
||||
The permission's codename which should be checked. Must be a
|
||||
string with a valid codename.
|
||||
|
||||
user
|
||||
The user for which the permission should be checked.
|
||||
|
||||
roles
|
||||
If passed, these roles will be assigned to the user temporarily
|
||||
before the permissions are checked.
|
||||
"""
|
||||
return permissions.utils.has_permission(self, user, permission, roles)
|
||||
|
||||
def check_permission(self, user, permission, roles=[]):
|
||||
"""Raise Unauthorized if the the passed user hasn't passed permission
|
||||
for this instance.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
permission
|
||||
The permission's codename which should be checked. Must be a
|
||||
string with a valid codename.
|
||||
|
||||
user
|
||||
The user for which the permission should be checked.
|
||||
|
||||
roles
|
||||
If passed, these roles will be assigned to the user temporarily
|
||||
before the permissions are checked.
|
||||
"""
|
||||
if not self.has_permission(user, permission, roles):
|
||||
raise Unauthorized("User %s doesn't have permission %s for object %s" % (user, permission, obj.slug))
|
||||
|
||||
def add_inheritance_block(self, permission):
|
||||
"""Adds an inheritance block for the passed permission.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
permission
|
||||
The permission for which an inheritance block should be added.
|
||||
Either a permission object or the codename of a permission.
|
||||
"""
|
||||
return permissions.utils.add_inheritance_block(self, permission)
|
||||
|
||||
def remove_inheritance_block(self, permission):
|
||||
"""Removes a inheritance block for the passed permission.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
permission
|
||||
The permission for which an inheritance block should be removed.
|
||||
Either a permission object or the codename of a permission.
|
||||
"""
|
||||
return permissions.utils.remove_inheritance_block(self, permission)
|
||||
|
||||
def is_inherited(self, codename):
|
||||
"""Returns True if the passed permission is inherited.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
codename
|
||||
The permission which should be checked. Must be the codename of
|
||||
the permission.
|
||||
"""
|
||||
return permissions.utils.is_inherited(self, codename)
|
||||
|
||||
def add_role(self, principal, role):
|
||||
"""Adds a local role for the principal.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
principal
|
||||
The principal (user or group) which gets the role.
|
||||
|
||||
role
|
||||
The role which is assigned.
|
||||
"""
|
||||
return permissions.utils.add_local_role(self, principal, role)
|
||||
|
||||
def get_roles(self, principal):
|
||||
"""Returns *direct* local roles for passed principal (user or group).
|
||||
"""
|
||||
return permissions.utils.get_local_roles(self, principal)
|
||||
|
||||
def remove_role(self, principal, role):
|
||||
"""Adds a local role for the principal to the object.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
principal
|
||||
The principal (user or group) from which the role is removed.
|
||||
|
||||
role
|
||||
The role which is removed.
|
||||
"""
|
||||
return permissions.utils.remove_local_role(self, principal, role)
|
||||
|
||||
def remove_roles(self, principal):
|
||||
"""Removes all local roles for the passed principal from the object.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
principal
|
||||
The principal (user or group) from which all local roles are
|
||||
removed.
|
||||
"""
|
||||
return permissions.utils.remove_local_roles(self, principal)
|
13
permissions/admin.py
Normal file
13
permissions/admin.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
from django.contrib import admin
|
||||
|
||||
from permissions.models import ObjectPermission
|
||||
admin.site.register(ObjectPermission)
|
||||
|
||||
from permissions.models import Permission
|
||||
admin.site.register(Permission)
|
||||
|
||||
from permissions.models import Role
|
||||
admin.site.register(Role)
|
||||
|
||||
from permissions.models import PrincipalRoleRelation
|
||||
admin.site.register(PrincipalRoleRelation)
|
45
permissions/backend.py
Normal file
45
permissions/backend.py
Normal file
|
@ -0,0 +1,45 @@
|
|||
# permissions imports
|
||||
import permissions.utils
|
||||
|
||||
class ObjectPermissionsBackend(object):
|
||||
"""Django backend for object permissions. Needs Django 1.2.
|
||||
|
||||
|
||||
Use it together with the default ModelBackend like so::
|
||||
|
||||
AUTHENTICATION_BACKENDS = (
|
||||
'django.contrib.auth.backends.ModelBackend',
|
||||
'permissions.backend.ObjectPermissionsBackend',
|
||||
)
|
||||
|
||||
Then you can use it like:
|
||||
|
||||
user.has_perm("view", your_object)
|
||||
|
||||
"""
|
||||
supports_object_permissions = True
|
||||
supports_anonymous_user = True
|
||||
|
||||
def authenticate(self, username, password):
|
||||
return None
|
||||
|
||||
def has_perm(self, user_obj, perm, obj=None):
|
||||
"""Checks whether the passed user has passed permission for passed
|
||||
object (obj).
|
||||
|
||||
This should be the primary method to check wether a user has a certain
|
||||
permission.
|
||||
|
||||
Parameters
|
||||
==========
|
||||
|
||||
perm
|
||||
The permission's codename which should be checked.
|
||||
|
||||
user_obj
|
||||
The user for which the permission should be checked.
|
||||
|
||||
obj
|
||||
The object for which the permission should be checked.
|
||||
"""
|
||||
return permissions.utils.has_permission(obj, user_obj, perm)
|
3
permissions/exceptions.py
Normal file
3
permissions/exceptions.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
class Unauthorized(Exception):
|
||||
def __init__(self, str):
|
||||
super(Unauthorized, self).__init__(str)
|
23
permissions/fixtures/initial.xml
Normal file
23
permissions/fixtures/initial.xml
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<django-objects version="1.0">
|
||||
<object pk="1" model="permissions.permission">
|
||||
<field type="CharField" name="name">View</field>
|
||||
<field type="CharField" name="codename">view</field>
|
||||
</object>
|
||||
<object pk="2" model="permissions.permission">
|
||||
<field type="CharField" name="name">Edit</field>
|
||||
<field type="CharField" name="codename">edit</field>
|
||||
</object>
|
||||
<object pk="3" model="permissions.permission">
|
||||
<field type="CharField" name="name">Delete</field>
|
||||
<field type="CharField" name="codename">delete</field>
|
||||
</object>
|
||||
<object pk="4" model="permissions.permission">
|
||||
<field type="CharField" name="name">Cut</field>
|
||||
<field type="CharField" name="codename">cut</field>
|
||||
</object>
|
||||
<object pk="5" model="permissions.permission">
|
||||
<field type="CharField" name="name">Copy</field>
|
||||
<field type="CharField" name="codename">copy</field>
|
||||
</object>
|
||||
</django-objects>
|
BIN
permissions/locale/de/LC_MESSAGES/django.mo
Normal file
BIN
permissions/locale/de/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
52
permissions/locale/de/LC_MESSAGES/django.po
Normal file
52
permissions/locale/de/LC_MESSAGES/django.po
Normal file
|
@ -0,0 +1,52 @@
|
|||
# German translations for django-permissions
|
||||
# Copyright (C) 2010 Kai Diefenbach
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# Kai Diefenbach <kai.diefenbach@iqpp.de>, 2010.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 1.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2010-03-30 23:12+0200\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: models.py:154
|
||||
msgid "Name"
|
||||
msgstr "Name"
|
||||
|
||||
#: models.py:155
|
||||
msgid "Codename"
|
||||
msgstr "Codename"
|
||||
|
||||
#: models.py:156
|
||||
msgid "Content Types"
|
||||
msgstr "Inhaltstypen"
|
||||
|
||||
#: models.py:175 models.py:280
|
||||
msgid "Role"
|
||||
msgstr "Rolle"
|
||||
|
||||
#: models.py:176 models.py:216
|
||||
msgid "Permission"
|
||||
msgstr "Recht"
|
||||
|
||||
#: models.py:178 models.py:218 models.py:282
|
||||
msgid "Content type"
|
||||
msgstr "Inhaltstyp"
|
||||
|
||||
#: models.py:179 models.py:219 models.py:283
|
||||
msgid "Content id"
|
||||
msgstr "Inhalts-ID"
|
||||
|
||||
#: models.py:278
|
||||
msgid "User"
|
||||
msgstr "Benutzer"
|
||||
|
||||
#: models.py:279
|
||||
msgid "Group"
|
||||
msgstr "Gruppe"
|
154
permissions/migrations/0001_initial.py
Normal file
154
permissions/migrations/0001_initial.py
Normal file
|
@ -0,0 +1,154 @@
|
|||
|
||||
from south.db import db
|
||||
from django.db import models
|
||||
from permissions.models import *
|
||||
|
||||
class Migration:
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Adding model 'Role'
|
||||
db.create_table('permissions_role', (
|
||||
('id', orm['permissions.Role:id']),
|
||||
('name', orm['permissions.Role:name']),
|
||||
))
|
||||
db.send_create_signal('permissions', ['Role'])
|
||||
|
||||
# Adding model 'ObjectPermissionInheritanceBlock'
|
||||
db.create_table('permissions_objectpermissioninheritanceblock', (
|
||||
('id', orm['permissions.ObjectPermissionInheritanceBlock:id']),
|
||||
('permission', orm['permissions.ObjectPermissionInheritanceBlock:permission']),
|
||||
('content_type', orm['permissions.ObjectPermissionInheritanceBlock:content_type']),
|
||||
('content_id', orm['permissions.ObjectPermissionInheritanceBlock:content_id']),
|
||||
))
|
||||
db.send_create_signal('permissions', ['ObjectPermissionInheritanceBlock'])
|
||||
|
||||
# Adding model 'ObjectPermission'
|
||||
db.create_table('permissions_objectpermission', (
|
||||
('id', orm['permissions.ObjectPermission:id']),
|
||||
('role', orm['permissions.ObjectPermission:role']),
|
||||
('permission', orm['permissions.ObjectPermission:permission']),
|
||||
('content_type', orm['permissions.ObjectPermission:content_type']),
|
||||
('content_id', orm['permissions.ObjectPermission:content_id']),
|
||||
))
|
||||
db.send_create_signal('permissions', ['ObjectPermission'])
|
||||
|
||||
# Adding model 'Permission'
|
||||
db.create_table('permissions_permission', (
|
||||
('id', orm['permissions.Permission:id']),
|
||||
('name', orm['permissions.Permission:name']),
|
||||
('codename', orm['permissions.Permission:codename']),
|
||||
))
|
||||
db.send_create_signal('permissions', ['Permission'])
|
||||
|
||||
# Adding model 'PrincipalRoleRelation'
|
||||
db.create_table('permissions_principalrolerelation', (
|
||||
('id', orm['permissions.PrincipalRoleRelation:id']),
|
||||
('user', orm['permissions.PrincipalRoleRelation:user']),
|
||||
('group', orm['permissions.PrincipalRoleRelation:group']),
|
||||
('role', orm['permissions.PrincipalRoleRelation:role']),
|
||||
('content_type', orm['permissions.PrincipalRoleRelation:content_type']),
|
||||
('content_id', orm['permissions.PrincipalRoleRelation:content_id']),
|
||||
))
|
||||
db.send_create_signal('permissions', ['PrincipalRoleRelation'])
|
||||
|
||||
# Adding ManyToManyField 'Permission.content_types'
|
||||
db.create_table('permissions_permission_content_types', (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('permission', models.ForeignKey(orm.Permission, null=False)),
|
||||
('contenttype', models.ForeignKey(orm['contenttypes.ContentType'], null=False))
|
||||
))
|
||||
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Deleting model 'Role'
|
||||
db.delete_table('permissions_role')
|
||||
|
||||
# Deleting model 'ObjectPermissionInheritanceBlock'
|
||||
db.delete_table('permissions_objectpermissioninheritanceblock')
|
||||
|
||||
# Deleting model 'ObjectPermission'
|
||||
db.delete_table('permissions_objectpermission')
|
||||
|
||||
# Deleting model 'Permission'
|
||||
db.delete_table('permissions_permission')
|
||||
|
||||
# Deleting model 'PrincipalRoleRelation'
|
||||
db.delete_table('permissions_principalrolerelation')
|
||||
|
||||
# Dropping ManyToManyField 'Permission.content_types'
|
||||
db.delete_table('permissions_permission_content_types')
|
||||
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'blank': 'True'})
|
||||
},
|
||||
'auth.permission': {
|
||||
'Meta': {'unique_together': "(('content_type', 'codename'),)"},
|
||||
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
'auth.user': {
|
||||
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
|
||||
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
|
||||
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
|
||||
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'blank': 'True'}),
|
||||
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||
},
|
||||
'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'})
|
||||
},
|
||||
'permissions.objectpermission': {
|
||||
'content_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||
'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']", 'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
'permissions.objectpermissioninheritanceblock': {
|
||||
'content_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'permission': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Permission']"})
|
||||
},
|
||||
'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.principalrolerelation': {
|
||||
'content_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}),
|
||||
'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'role': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['permissions.Role']"}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
'permissions.role': {
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['permissions']
|
0
permissions/migrations/__init__.py
Normal file
0
permissions/migrations/__init__.py
Normal file
193
permissions/models.py
Normal file
193
permissions/models.py
Normal file
|
@ -0,0 +1,193 @@
|
|||
# python imports
|
||||
import sets
|
||||
|
||||
# django imports
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth.models import Group
|
||||
from django.contrib.contenttypes import generic
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
class Permission(models.Model):
|
||||
"""A permission which can be granted to users/groups and objects.
|
||||
|
||||
**Attributes:**
|
||||
|
||||
name
|
||||
The unique name of the permission. This is displayed to users.
|
||||
|
||||
codename
|
||||
The unique codename of the permission. This is used internal to
|
||||
identify a permission.
|
||||
|
||||
content_types
|
||||
The content types for which the permission is active. This can be
|
||||
used to display only reasonable permissions for an object.
|
||||
"""
|
||||
name = models.CharField(_(u"Name"), max_length=100, unique=True)
|
||||
codename = models.CharField(_(u"Codename"), max_length=100, unique=True)
|
||||
content_types = models.ManyToManyField(ContentType, verbose_name=_(u"Content Types"), blank=True, null=True, related_name="content_types")
|
||||
|
||||
def __unicode__(self):
|
||||
return "%s (%s)" % (self.name, self.codename)
|
||||
|
||||
class ObjectPermission(models.Model):
|
||||
"""Grants permission for specific user/group and object.
|
||||
|
||||
**Attributes:**
|
||||
|
||||
role
|
||||
The role for which the permission is granted.
|
||||
|
||||
permission
|
||||
The permission which is granted.
|
||||
|
||||
content
|
||||
The object for which the permission is granted.
|
||||
"""
|
||||
role = models.ForeignKey("Role", verbose_name=_(u"Role"), blank=True, null=True)
|
||||
permission = models.ForeignKey(Permission, verbose_name=_(u"Permission"))
|
||||
|
||||
content_type = models.ForeignKey(ContentType, verbose_name=_(u"Content type"))
|
||||
content_id = models.PositiveIntegerField(verbose_name=_(u"Content id"))
|
||||
content = generic.GenericForeignKey(ct_field="content_type", fk_field="content_id")
|
||||
|
||||
def __unicode__(self):
|
||||
if self.role:
|
||||
principal = self.role
|
||||
else:
|
||||
principal = self.user
|
||||
|
||||
return "%s / %s / %s - %s" % (self.permission.name, principal, self.content_type, self.content_id)
|
||||
|
||||
def get_principal(self):
|
||||
"""Returns the principal.
|
||||
"""
|
||||
return self.user or self.group
|
||||
|
||||
def set_principal(self, principal):
|
||||
"""Sets the principal.
|
||||
"""
|
||||
if isinstance(principal, User):
|
||||
self.user = principal
|
||||
else:
|
||||
self.group = principal
|
||||
|
||||
principal = property(get_principal, set_principal)
|
||||
|
||||
class ObjectPermissionInheritanceBlock(models.Model):
|
||||
"""Blocks the inheritance for specific permission and object.
|
||||
|
||||
**Attributes:**
|
||||
|
||||
permission
|
||||
The permission for which inheritance is blocked.
|
||||
|
||||
content
|
||||
The object for which the inheritance is blocked.
|
||||
"""
|
||||
permission = models.ForeignKey(Permission, verbose_name=_(u"Permission"))
|
||||
|
||||
content_type = models.ForeignKey(ContentType, verbose_name=_(u"Content type"))
|
||||
content_id = models.PositiveIntegerField(verbose_name=_(u"Content id"))
|
||||
content = generic.GenericForeignKey(ct_field="content_type", fk_field="content_id")
|
||||
|
||||
def __unicode__(self):
|
||||
return "%s / %s - %s" % (self.permission, self.content_type, self.content_id)
|
||||
|
||||
class Role(models.Model):
|
||||
"""A role gets permissions to do something. Principals (users and groups)
|
||||
can only get permissions via roles.
|
||||
|
||||
**Attributes:**
|
||||
|
||||
name
|
||||
The unique name of the role
|
||||
"""
|
||||
name = models.CharField(max_length=100, unique=True)
|
||||
|
||||
class Meta:
|
||||
ordering = ("name", )
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
def add_principal(self, principal, content=None):
|
||||
"""Addes the given principal (user or group) ot the Role.
|
||||
"""
|
||||
if isinstance(principal, User):
|
||||
PrincipalRoleRelation.objects.create(user=principal, role=self)
|
||||
else:
|
||||
PrincipalRoleRelation.objects.create(group=principal, role=self)
|
||||
|
||||
def get_groups(self, content=None):
|
||||
"""Returns all groups which has this role assigned. If content is given
|
||||
it returns also the local roles.
|
||||
"""
|
||||
if content:
|
||||
ctype = ContentType.objects.get_for_model(content)
|
||||
prrs = PrincipalRoleRelation.objects.filter(role=self,
|
||||
content_id__in = (None, content.pk),
|
||||
content_type__in = (None, ctype)).exclude(group=None)
|
||||
else:
|
||||
prrs = PrincipalRoleRelation.objects.filter(role=self,
|
||||
content_id=None, content_type=None).exclude(group=None)
|
||||
|
||||
return [prr.group for prr in prrs]
|
||||
|
||||
def get_users(self, content=None):
|
||||
"""Returns all users which has this role assigned. If content is given
|
||||
it returns also the local roles.
|
||||
"""
|
||||
if content:
|
||||
ctype = ContentType.objects.get_for_model(content)
|
||||
prrs = PrincipalRoleRelation.objects.filter(role=self,
|
||||
content_id__in = (None, content.pk),
|
||||
content_type__in = (None, ctype)).exclude(user=None)
|
||||
else:
|
||||
prrs = PrincipalRoleRelation.objects.filter(role=self,
|
||||
content_id=None, content_type=None).exclude(user=None)
|
||||
|
||||
return [prr.user for prr in prrs]
|
||||
|
||||
class PrincipalRoleRelation(models.Model):
|
||||
"""A role given to a principal (user or group). If a content object is
|
||||
given this is a local role, i.e. the principal has this role only for this
|
||||
content object. Otherwise it is a global role, i.e. the principal has
|
||||
this role generally.
|
||||
|
||||
user
|
||||
A user instance. Either a user xor a group needs to be given.
|
||||
|
||||
group
|
||||
A group instance. Either a user xor a group needs to be given.
|
||||
|
||||
role
|
||||
The role which is given to the principal for content.
|
||||
|
||||
content
|
||||
The content object which gets the local role (optional).
|
||||
"""
|
||||
user = models.ForeignKey(User, verbose_name=_(u"User"), blank=True, null=True)
|
||||
group = models.ForeignKey(Group, verbose_name=_(u"Group"), blank=True, null=True)
|
||||
role = models.ForeignKey(Role, verbose_name=_(u"Role"))
|
||||
|
||||
content_type = models.ForeignKey(ContentType, verbose_name=_(u"Content type"), blank=True, null=True)
|
||||
content_id = models.PositiveIntegerField(verbose_name=_(u"Content id"), blank=True, null=True)
|
||||
content = generic.GenericForeignKey(ct_field="content_type", fk_field="content_id")
|
||||
|
||||
def get_principal(self):
|
||||
"""Returns the principal.
|
||||
"""
|
||||
return self.user or self.group
|
||||
|
||||
def set_principal(self, principal):
|
||||
"""Sets the principal.
|
||||
"""
|
||||
if isinstance(principal, User):
|
||||
self.user = principal
|
||||
else:
|
||||
self.group = principal
|
||||
|
||||
principal = property(get_principal, set_principal)
|
0
permissions/templatetags/__init__.py
Normal file
0
permissions/templatetags/__init__.py
Normal file
48
permissions/templatetags/permissions_tags.py
Normal file
48
permissions/templatetags/permissions_tags.py
Normal file
|
@ -0,0 +1,48 @@
|
|||
# django imports
|
||||
from django import template
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.contrib.auth.models import User, AnonymousUser
|
||||
|
||||
import permissions.utils
|
||||
register = template.Library()
|
||||
|
||||
class PermissionComparisonNode(template.Node):
|
||||
"""Implements a node to provide an if current user has passed permission
|
||||
for current object.
|
||||
"""
|
||||
@classmethod
|
||||
def handle_token(cls, parser, token):
|
||||
bits = token.contents.split()
|
||||
if len(bits) != 2:
|
||||
raise template.TemplateSyntaxError(
|
||||
"'%s' tag takes one argument" % bits[0])
|
||||
end_tag = 'endifhasperm'
|
||||
nodelist_true = parser.parse(('else', end_tag))
|
||||
token = parser.next_token()
|
||||
if token.contents == 'else': # there is an 'else' clause in the tag
|
||||
nodelist_false = parser.parse((end_tag,))
|
||||
parser.delete_first_token()
|
||||
else:
|
||||
nodelist_false = ""
|
||||
|
||||
return cls(bits[1], nodelist_true, nodelist_false)
|
||||
|
||||
def __init__(self, permission, nodelist_true, nodelist_false):
|
||||
self.permission = permission
|
||||
self.nodelist_true = nodelist_true
|
||||
self.nodelist_false = nodelist_false
|
||||
|
||||
def render(self, context):
|
||||
obj = context.get("obj")
|
||||
request = context.get("request")
|
||||
if permissions.utils.has_permission(self.permission, request.user, obj):
|
||||
return self.nodelist_true.render(context)
|
||||
else:
|
||||
return self.nodelist_false
|
||||
|
||||
@register.tag
|
||||
def ifhasperm(parser, token):
|
||||
"""This function provides functionality for the 'ifhasperm' template tag.
|
||||
"""
|
||||
return PermissionComparisonNode.handle_token(parser, token)
|
||||
|
783
permissions/tests.py
Normal file
783
permissions/tests.py
Normal file
|
@ -0,0 +1,783 @@
|
|||
# django imports
|
||||
from django.contrib.flatpages.models import FlatPage
|
||||
from django.contrib.auth.models import Group
|
||||
from django.contrib.auth.models import User
|
||||
from django.conf import settings
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.test import TestCase
|
||||
from django.test.client import Client
|
||||
|
||||
# permissions imports
|
||||
from permissions.models import Permission
|
||||
from permissions.models import ObjectPermission
|
||||
from permissions.models import ObjectPermissionInheritanceBlock
|
||||
from permissions.models import Role
|
||||
|
||||
import permissions.utils
|
||||
|
||||
class BackendTestCase(TestCase):
|
||||
"""
|
||||
"""
|
||||
def setUp(self):
|
||||
"""
|
||||
"""
|
||||
settings.AUTHENTICATION_BACKENDS = (
|
||||
'django.contrib.auth.backends.ModelBackend',
|
||||
'permissions.backend.ObjectPermissionsBackend',
|
||||
)
|
||||
|
||||
self.role_1 = permissions.utils.register_role("Role 1")
|
||||
self.user = User.objects.create(username="john")
|
||||
self.page_1 = FlatPage.objects.create(url="/page-1/", title="Page 1")
|
||||
self.view = permissions.utils.register_permission("View", "view")
|
||||
|
||||
# Add user to role
|
||||
self.role_1.add_principal(self.user)
|
||||
|
||||
def test_has_perm(self):
|
||||
"""Tests has perm of the backend.
|
||||
"""
|
||||
result = self.user.has_perm(self.view, self.page_1)
|
||||
self.assertEqual(result, False)
|
||||
|
||||
# assign view permission to role 1
|
||||
permissions.utils.grant_permission(self.page_1, self.role_1, self.view)
|
||||
|
||||
result = self.user.has_perm("view", self.page_1)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
class RoleTestCase(TestCase):
|
||||
"""
|
||||
"""
|
||||
def setUp(self):
|
||||
"""
|
||||
"""
|
||||
self.role_1 = permissions.utils.register_role("Role 1")
|
||||
self.role_2 = permissions.utils.register_role("Role 2")
|
||||
|
||||
self.user = User.objects.create(username="john")
|
||||
self.group = Group.objects.create(name="brights")
|
||||
|
||||
self.user.groups.add(self.group)
|
||||
|
||||
self.page_1 = FlatPage.objects.create(url="/page-1/", title="Page 1")
|
||||
self.page_2 = FlatPage.objects.create(url="/page-1/", title="Page 2")
|
||||
|
||||
def test_getter(self):
|
||||
"""
|
||||
"""
|
||||
result = permissions.utils.get_group(self.group.id)
|
||||
self.assertEqual(result, self.group)
|
||||
|
||||
result = permissions.utils.get_group(42)
|
||||
self.assertEqual(result, None)
|
||||
|
||||
result = permissions.utils.get_role(self.role_1.id)
|
||||
self.assertEqual(result, self.role_1)
|
||||
|
||||
result = permissions.utils.get_role(42)
|
||||
self.assertEqual(result, None)
|
||||
|
||||
result = permissions.utils.get_user(self.user.id)
|
||||
self.assertEqual(result, self.user)
|
||||
|
||||
result = permissions.utils.get_user(42)
|
||||
self.assertEqual(result, None)
|
||||
|
||||
def test_global_roles_user(self):
|
||||
"""
|
||||
"""
|
||||
# Add role 1
|
||||
result = permissions.utils.add_role(self.user, self.role_1)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
# Add role 1 again
|
||||
result = permissions.utils.add_role(self.user, self.role_1)
|
||||
self.assertEqual(result, False)
|
||||
|
||||
result = permissions.utils.get_roles(self.user)
|
||||
self.assertEqual(result, [self.role_1])
|
||||
|
||||
# Add role 2
|
||||
result = permissions.utils.add_role(self.user, self.role_2)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
result = permissions.utils.get_roles(self.user)
|
||||
self.assertEqual(result, [self.role_1, self.role_2])
|
||||
|
||||
# Remove role 1
|
||||
result = permissions.utils.remove_role(self.user, self.role_1)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
# Remove role 1 again
|
||||
result = permissions.utils.remove_role(self.user, self.role_1)
|
||||
self.assertEqual(result, False)
|
||||
|
||||
result = permissions.utils.get_roles(self.user)
|
||||
self.assertEqual(result, [self.role_2])
|
||||
|
||||
# Remove role 2
|
||||
result = permissions.utils.remove_role(self.user, self.role_2)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
result = permissions.utils.get_roles(self.user)
|
||||
self.assertEqual(result, [])
|
||||
|
||||
def test_global_roles_group(self):
|
||||
"""
|
||||
"""
|
||||
# Add role 1
|
||||
result = permissions.utils.add_role(self.group, self.role_1)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
# Add role 1 again
|
||||
result = permissions.utils.add_role(self.group, self.role_1)
|
||||
self.assertEqual(result, False)
|
||||
|
||||
result = permissions.utils.get_roles(self.group)
|
||||
self.assertEqual(result, [self.role_1])
|
||||
|
||||
# Add role 2
|
||||
result = permissions.utils.add_role(self.group, self.role_2)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
result = permissions.utils.get_roles(self.group)
|
||||
self.assertEqual(result, [self.role_1, self.role_2])
|
||||
|
||||
# Remove role 1
|
||||
result = permissions.utils.remove_role(self.group, self.role_1)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
# Remove role 1 again
|
||||
result = permissions.utils.remove_role(self.group, self.role_1)
|
||||
self.assertEqual(result, False)
|
||||
|
||||
result = permissions.utils.get_roles(self.group)
|
||||
self.assertEqual(result, [self.role_2])
|
||||
|
||||
# Remove role 2
|
||||
result = permissions.utils.remove_role(self.group, self.role_2)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
result = permissions.utils.get_roles(self.group)
|
||||
self.assertEqual(result, [])
|
||||
|
||||
def test_remove_roles_user(self):
|
||||
"""
|
||||
"""
|
||||
# Add role 1
|
||||
result = permissions.utils.add_role(self.user, self.role_1)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
# Add role 2
|
||||
result = permissions.utils.add_role(self.user, self.role_2)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
result = permissions.utils.get_roles(self.user)
|
||||
self.assertEqual(result, [self.role_1, self.role_2])
|
||||
|
||||
# Remove roles
|
||||
result = permissions.utils.remove_roles(self.user)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
result = permissions.utils.get_roles(self.user)
|
||||
self.assertEqual(result, [])
|
||||
|
||||
# Remove roles
|
||||
result = permissions.utils.remove_roles(self.user)
|
||||
self.assertEqual(result, False)
|
||||
|
||||
def test_remove_roles_group(self):
|
||||
"""
|
||||
"""
|
||||
# Add role 1
|
||||
result = permissions.utils.add_role(self.group, self.role_1)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
# Add role 2
|
||||
result = permissions.utils.add_role(self.group, self.role_2)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
result = permissions.utils.get_roles(self.group)
|
||||
self.assertEqual(result, [self.role_1, self.role_2])
|
||||
|
||||
# Remove roles
|
||||
result = permissions.utils.remove_roles(self.group)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
result = permissions.utils.get_roles(self.group)
|
||||
self.assertEqual(result, [])
|
||||
|
||||
# Remove roles
|
||||
result = permissions.utils.remove_roles(self.group)
|
||||
self.assertEqual(result, False)
|
||||
|
||||
def test_local_role_user(self):
|
||||
"""
|
||||
"""
|
||||
# Add local role to page 1
|
||||
result = permissions.utils.add_local_role(self.page_1, self.user, self.role_1)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
# Again
|
||||
result = permissions.utils.add_local_role(self.page_1, self.user, self.role_1)
|
||||
self.assertEqual(result, False)
|
||||
|
||||
result = permissions.utils.get_local_roles(self.page_1, self.user)
|
||||
self.assertEqual(result, [self.role_1])
|
||||
|
||||
# Add local role 2
|
||||
result = permissions.utils.add_local_role(self.page_1, self.user, self.role_2)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
result = permissions.utils.get_local_roles(self.page_1, self.user)
|
||||
self.assertEqual(result, [self.role_1, self.role_2])
|
||||
|
||||
# Remove role 1
|
||||
result = permissions.utils.remove_local_role(self.page_1, self.user, self.role_1)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
# Remove role 1 again
|
||||
result = permissions.utils.remove_local_role(self.page_1, self.user, self.role_1)
|
||||
self.assertEqual(result, False)
|
||||
|
||||
result = permissions.utils.get_local_roles(self.page_1, self.user)
|
||||
self.assertEqual(result, [self.role_2])
|
||||
|
||||
# Remove role 2
|
||||
result = permissions.utils.remove_local_role(self.page_1, self.user, self.role_2)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
result = permissions.utils.get_local_roles(self.page_1, self.user)
|
||||
self.assertEqual(result, [])
|
||||
|
||||
def test_local_role_group(self):
|
||||
"""
|
||||
"""
|
||||
# Add local role to page 1
|
||||
result = permissions.utils.add_local_role(self.page_1, self.group, self.role_1)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
# Again
|
||||
result = permissions.utils.add_local_role(self.page_1, self.group, self.role_1)
|
||||
self.assertEqual(result, False)
|
||||
|
||||
result = permissions.utils.get_local_roles(self.page_1, self.group)
|
||||
self.assertEqual(result, [self.role_1])
|
||||
|
||||
# Add local role 2
|
||||
result = permissions.utils.add_local_role(self.page_1, self.group, self.role_2)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
result = permissions.utils.get_local_roles(self.page_1, self.group)
|
||||
self.assertEqual(result, [self.role_1, self.role_2])
|
||||
|
||||
# Remove role 1
|
||||
result = permissions.utils.remove_local_role(self.page_1, self.group, self.role_1)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
# Remove role 1 again
|
||||
result = permissions.utils.remove_local_role(self.page_1, self.group, self.role_1)
|
||||
self.assertEqual(result, False)
|
||||
|
||||
result = permissions.utils.get_local_roles(self.page_1, self.group)
|
||||
self.assertEqual(result, [self.role_2])
|
||||
|
||||
# Remove role 2
|
||||
result = permissions.utils.remove_local_role(self.page_1, self.group, self.role_2)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
result = permissions.utils.get_local_roles(self.page_1, self.group)
|
||||
self.assertEqual(result, [])
|
||||
|
||||
def test_remove_local_roles_user(self):
|
||||
"""
|
||||
"""
|
||||
# Add local role to page 1
|
||||
result = permissions.utils.add_local_role(self.page_1, self.user, self.role_1)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
# Add local role 2
|
||||
result = permissions.utils.add_local_role(self.page_1, self.user, self.role_2)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
result = permissions.utils.get_local_roles(self.page_1, self.user)
|
||||
self.assertEqual(result, [self.role_1, self.role_2])
|
||||
|
||||
# Remove all local roles
|
||||
result = permissions.utils.remove_local_roles(self.page_1, self.user)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
result = permissions.utils.get_local_roles(self.page_1, self.user)
|
||||
self.assertEqual(result, [])
|
||||
|
||||
# Remove all local roles again
|
||||
result = permissions.utils.remove_local_roles(self.page_1, self.user)
|
||||
self.assertEqual(result, False)
|
||||
|
||||
def test_get_groups_1(self):
|
||||
"""Tests global roles for groups.
|
||||
"""
|
||||
result = self.role_1.get_groups()
|
||||
self.assertEqual(len(result), 0)
|
||||
|
||||
result = permissions.utils.add_role(self.group, self.role_1)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
result = self.role_1.get_groups()
|
||||
self.assertEqual(result[0].name, "brights")
|
||||
|
||||
# Add another group
|
||||
self.group_2 = Group.objects.create(name="atheists")
|
||||
result = permissions.utils.add_role(self.group_2, self.role_1)
|
||||
|
||||
result = self.role_1.get_groups()
|
||||
self.assertEqual(result[0].name, "brights")
|
||||
self.assertEqual(result[1].name, "atheists")
|
||||
self.assertEqual(len(result), 2)
|
||||
|
||||
# Add the role to an user
|
||||
result = permissions.utils.add_role(self.user, self.role_1)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
# This shouldn't have an effect on the result
|
||||
result = self.role_1.get_groups()
|
||||
self.assertEqual(result[0].name, "brights")
|
||||
self.assertEqual(result[1].name, "atheists")
|
||||
self.assertEqual(len(result), 2)
|
||||
|
||||
def test_get_groups_2(self):
|
||||
"""Tests local roles for groups.
|
||||
"""
|
||||
result = self.role_1.get_groups(self.page_1)
|
||||
self.assertEqual(len(result), 0)
|
||||
|
||||
result = permissions.utils.add_local_role(self.page_1, self.group, self.role_1)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
result = self.role_1.get_groups(self.page_1)
|
||||
self.assertEqual(result[0].name, "brights")
|
||||
|
||||
# Add another local group
|
||||
self.group_2 = Group.objects.create(name="atheists")
|
||||
result = permissions.utils.add_local_role(self.page_1, self.group_2, self.role_1)
|
||||
|
||||
result = self.role_1.get_groups(self.page_1)
|
||||
self.assertEqual(result[0].name, "brights")
|
||||
self.assertEqual(result[1].name, "atheists")
|
||||
|
||||
# A the global role to group
|
||||
result = permissions.utils.add_role(self.group, self.role_1)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
# Nontheless there are just two groups returned (and no duplicate)
|
||||
result = self.role_1.get_groups(self.page_1)
|
||||
self.assertEqual(result[0].name, "brights")
|
||||
self.assertEqual(result[1].name, "atheists")
|
||||
self.assertEqual(len(result), 2)
|
||||
|
||||
# Andere there should one global role
|
||||
result = self.role_1.get_groups()
|
||||
self.assertEqual(result[0].name, "brights")
|
||||
|
||||
# Add the role to an user
|
||||
result = permissions.utils.add_local_role(self.page_1, self.user, self.role_1)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
# This shouldn't have an effect on the result
|
||||
result = self.role_1.get_groups(self.page_1)
|
||||
self.assertEqual(result[0].name, "brights")
|
||||
self.assertEqual(result[1].name, "atheists")
|
||||
self.assertEqual(len(result), 2)
|
||||
|
||||
def test_get_users_1(self):
|
||||
"""Tests global roles for users.
|
||||
"""
|
||||
result = self.role_1.get_users()
|
||||
self.assertEqual(len(result), 0)
|
||||
|
||||
result = permissions.utils.add_role(self.user, self.role_1)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
result = self.role_1.get_users()
|
||||
self.assertEqual(result[0].username, "john")
|
||||
|
||||
# Add another role to an user
|
||||
self.user_2 = User.objects.create(username="jane")
|
||||
result = permissions.utils.add_role(self.user_2, self.role_1)
|
||||
|
||||
result = self.role_1.get_users()
|
||||
self.assertEqual(result[0].username, "john")
|
||||
self.assertEqual(result[1].username, "jane")
|
||||
self.assertEqual(len(result), 2)
|
||||
|
||||
# Add the role to an user
|
||||
result = permissions.utils.add_role(self.group, self.role_1)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
# This shouldn't have an effect on the result
|
||||
result = self.role_1.get_users()
|
||||
self.assertEqual(result[0].username, "john")
|
||||
self.assertEqual(result[1].username, "jane")
|
||||
self.assertEqual(len(result), 2)
|
||||
|
||||
def test_get_users_2(self):
|
||||
"""Tests local roles for users.
|
||||
"""
|
||||
result = self.role_1.get_users(self.page_1)
|
||||
self.assertEqual(len(result), 0)
|
||||
|
||||
result = permissions.utils.add_local_role(self.page_1, self.user, self.role_1)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
result = self.role_1.get_users(self.page_1)
|
||||
self.assertEqual(result[0].username, "john")
|
||||
|
||||
# Add another local role to an user
|
||||
self.user_2 = User.objects.create(username="jane")
|
||||
result = permissions.utils.add_local_role(self.page_1, self.user_2, self.role_1)
|
||||
|
||||
result = self.role_1.get_users(self.page_1)
|
||||
self.assertEqual(result[0].username, "john")
|
||||
self.assertEqual(result[1].username, "jane")
|
||||
|
||||
# A the global role to user
|
||||
result = permissions.utils.add_role(self.user, self.role_1)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
# Nontheless there are just two users returned (and no duplicate)
|
||||
result = self.role_1.get_users(self.page_1)
|
||||
self.assertEqual(result[0].username, "john")
|
||||
self.assertEqual(result[1].username, "jane")
|
||||
self.assertEqual(len(result), 2)
|
||||
|
||||
# Andere there should one user for the global role
|
||||
result = self.role_1.get_users()
|
||||
self.assertEqual(result[0].username, "john")
|
||||
|
||||
# Add the role to an group
|
||||
result = permissions.utils.add_local_role(self.page_1, self.group, self.role_1)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
# This shouldn't have an effect on the result
|
||||
result = self.role_1.get_users(self.page_1)
|
||||
self.assertEqual(result[0].username, "john")
|
||||
self.assertEqual(result[1].username, "jane")
|
||||
self.assertEqual(len(result), 2)
|
||||
|
||||
class PermissionTestCase(TestCase):
|
||||
"""
|
||||
"""
|
||||
def setUp(self):
|
||||
"""
|
||||
"""
|
||||
self.role_1 = permissions.utils.register_role("Role 1")
|
||||
self.role_2 = permissions.utils.register_role("Role 2")
|
||||
|
||||
self.user = User.objects.create(username="john")
|
||||
permissions.utils.add_role(self.user, self.role_1)
|
||||
self.user.save()
|
||||
|
||||
self.page_1 = FlatPage.objects.create(url="/page-1/", title="Page 1")
|
||||
self.page_2 = FlatPage.objects.create(url="/page-1/", title="Page 2")
|
||||
|
||||
self.permission = permissions.utils.register_permission("View", "view")
|
||||
|
||||
def test_add_permissions(self):
|
||||
"""
|
||||
"""
|
||||
# Add per object
|
||||
result = permissions.utils.grant_permission(self.page_1, self.role_1, self.permission)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
# Add per codename
|
||||
result = permissions.utils.grant_permission(self.page_1, self.role_1, "view")
|
||||
self.assertEqual(result, True)
|
||||
|
||||
# Add ermission which does not exist
|
||||
result = permissions.utils.grant_permission(self.page_1, self.role_1, "hurz")
|
||||
self.assertEqual(result, False)
|
||||
|
||||
def test_remove_permission(self):
|
||||
"""
|
||||
"""
|
||||
# Add
|
||||
result = permissions.utils.grant_permission(self.page_1, self.role_1, "view")
|
||||
self.assertEqual(result, True)
|
||||
|
||||
# Remove
|
||||
result = permissions.utils.remove_permission(self.page_1, self.role_1, "view")
|
||||
self.assertEqual(result, True)
|
||||
|
||||
# Remove again
|
||||
result = permissions.utils.remove_permission(self.page_1, self.role_1, "view")
|
||||
self.assertEqual(result, False)
|
||||
|
||||
def test_has_permission_role(self):
|
||||
"""
|
||||
"""
|
||||
result = permissions.utils.has_permission(self.page_1, self.user, "view")
|
||||
self.assertEqual(result, False)
|
||||
|
||||
result = permissions.utils.grant_permission(self.page_1, self.role_1, self.permission)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
result = permissions.utils.has_permission(self.page_1, self.user, "view")
|
||||
self.assertEqual(result, True)
|
||||
|
||||
result = permissions.utils.remove_permission(self.page_1, self.role_1, "view")
|
||||
self.assertEqual(result, True)
|
||||
|
||||
result = permissions.utils.has_permission(self.page_1, self.user, "view")
|
||||
self.assertEqual(result, False)
|
||||
|
||||
def test_has_permission_owner(self):
|
||||
"""
|
||||
"""
|
||||
creator = User.objects.create(username="jane")
|
||||
|
||||
result = permissions.utils.has_permission(self.page_1, creator, "view")
|
||||
self.assertEqual(result, False)
|
||||
|
||||
owner = permissions.utils.register_role("Owner")
|
||||
permissions.utils.grant_permission(self.page_1, owner, "view")
|
||||
|
||||
result = permissions.utils.has_permission(self.page_1, creator, "view", [owner])
|
||||
self.assertEqual(result, True)
|
||||
|
||||
def test_local_role(self):
|
||||
"""
|
||||
"""
|
||||
result = permissions.utils.has_permission(self.page_1, self.user, "view")
|
||||
self.assertEqual(result, False)
|
||||
|
||||
permissions.utils.grant_permission(self.page_1, self.role_2, self.permission)
|
||||
permissions.utils.add_local_role(self.page_1, self.user, self.role_2)
|
||||
|
||||
result = permissions.utils.has_permission(self.page_1, self.user, "view")
|
||||
self.assertEqual(result, True)
|
||||
|
||||
def test_ineritance(self):
|
||||
"""
|
||||
"""
|
||||
result = permissions.utils.is_inherited(self.page_1, "view")
|
||||
self.assertEqual(result, True)
|
||||
|
||||
# per permission
|
||||
permissions.utils.add_inheritance_block(self.page_1, self.permission)
|
||||
|
||||
result = permissions.utils.is_inherited(self.page_1, "view")
|
||||
self.assertEqual(result, False)
|
||||
|
||||
permissions.utils.remove_inheritance_block(self.page_1, self.permission)
|
||||
|
||||
result = permissions.utils.is_inherited(self.page_1, "view")
|
||||
self.assertEqual(result, True)
|
||||
|
||||
# per codename
|
||||
permissions.utils.add_inheritance_block(self.page_1, "view")
|
||||
|
||||
result = permissions.utils.is_inherited(self.page_1, "view")
|
||||
self.assertEqual(result, False)
|
||||
|
||||
permissions.utils.remove_inheritance_block(self.page_1, "view")
|
||||
|
||||
result = permissions.utils.is_inherited(self.page_1, "view")
|
||||
self.assertEqual(result, True)
|
||||
|
||||
def test_unicode(self):
|
||||
"""
|
||||
"""
|
||||
# Permission
|
||||
self.assertEqual(self.permission.__unicode__(), "View (view)")
|
||||
|
||||
# ObjectPermission
|
||||
permissions.utils.grant_permission(self.page_1, self.role_1, self.permission)
|
||||
opr = ObjectPermission.objects.get(permission=self.permission, role=self.role_1)
|
||||
self.assertEqual(opr.__unicode__(), "View / Role 1 / flat page - 1")
|
||||
|
||||
# ObjectPermissionInheritanceBlock
|
||||
permissions.utils.add_inheritance_block(self.page_1, self.permission)
|
||||
opb = ObjectPermissionInheritanceBlock.objects.get(permission=self.permission)
|
||||
|
||||
self.assertEqual(opb.__unicode__(), "View (view) / flat page - 1")
|
||||
|
||||
def test_reset(self):
|
||||
"""
|
||||
"""
|
||||
result = permissions.utils.grant_permission(self.page_1, self.role_1, "view")
|
||||
self.assertEqual(result, True)
|
||||
|
||||
result = permissions.utils.has_permission(self.page_1, self.user, "view")
|
||||
self.assertEqual(result, True)
|
||||
|
||||
permissions.utils.add_inheritance_block(self.page_1, "view")
|
||||
|
||||
result = permissions.utils.is_inherited(self.page_1, "view")
|
||||
self.assertEqual(result, False)
|
||||
|
||||
permissions.utils.reset(self.page_1)
|
||||
|
||||
result = permissions.utils.has_permission(self.page_1, self.user, "view")
|
||||
self.assertEqual(result, False)
|
||||
|
||||
result = permissions.utils.is_inherited(self.page_1, "view")
|
||||
self.assertEqual(result, True)
|
||||
|
||||
permissions.utils.reset(self.page_1)
|
||||
|
||||
class RegistrationTestCase(TestCase):
|
||||
"""Tests the registration of different components.
|
||||
"""
|
||||
def test_group(self):
|
||||
"""Tests registering/unregistering of a group.
|
||||
"""
|
||||
# Register a group
|
||||
result = permissions.utils.register_group("Brights")
|
||||
self.failUnless(isinstance(result, Group))
|
||||
|
||||
# It's there
|
||||
group = Group.objects.get(name="Brights")
|
||||
self.assertEqual(group.name, "Brights")
|
||||
|
||||
# Trying to register another group with same name
|
||||
result = permissions.utils.register_group("Brights")
|
||||
self.assertEqual(result, False)
|
||||
|
||||
group = Group.objects.get(name="Brights")
|
||||
self.assertEqual(group.name, "Brights")
|
||||
|
||||
# Unregister the group
|
||||
result = permissions.utils.unregister_group("Brights")
|
||||
self.assertEqual(result, True)
|
||||
|
||||
# It's not there anymore
|
||||
self.assertRaises(Group.DoesNotExist, Group.objects.get, name="Brights")
|
||||
|
||||
# Trying to unregister the group again
|
||||
result = permissions.utils.unregister_group("Brights")
|
||||
self.assertEqual(result, False)
|
||||
|
||||
def test_role(self):
|
||||
"""Tests registering/unregistering of a role.
|
||||
"""
|
||||
# Register a role
|
||||
result = permissions.utils.register_role("Editor")
|
||||
self.failUnless(isinstance(result, Role))
|
||||
|
||||
# It's there
|
||||
role = Role.objects.get(name="Editor")
|
||||
self.assertEqual(role.name, "Editor")
|
||||
|
||||
# Trying to register another role with same name
|
||||
result = permissions.utils.register_role("Editor")
|
||||
self.assertEqual(result, False)
|
||||
|
||||
role = Role.objects.get(name="Editor")
|
||||
self.assertEqual(role.name, "Editor")
|
||||
|
||||
# Unregister the role
|
||||
result = permissions.utils.unregister_role("Editor")
|
||||
self.assertEqual(result, True)
|
||||
|
||||
# It's not there anymore
|
||||
self.assertRaises(Role.DoesNotExist, Role.objects.get, name="Editor")
|
||||
|
||||
# Trying to unregister the role again
|
||||
result = permissions.utils.unregister_role("Editor")
|
||||
self.assertEqual(result, False)
|
||||
|
||||
def test_permission(self):
|
||||
"""Tests registering/unregistering of a permission.
|
||||
"""
|
||||
# Register a permission
|
||||
result = permissions.utils.register_permission("Change", "change")
|
||||
self.failUnless(isinstance(result, Permission))
|
||||
|
||||
# Is it there?
|
||||
p = Permission.objects.get(codename="change")
|
||||
self.assertEqual(p.name, "Change")
|
||||
|
||||
# Register a permission with the same codename
|
||||
result = permissions.utils.register_permission("Change2", "change")
|
||||
self.assertEqual(result, False)
|
||||
|
||||
# Is it there?
|
||||
p = Permission.objects.get(codename="change")
|
||||
self.assertEqual(p.name, "Change")
|
||||
|
||||
# Register a permission with the same name
|
||||
result = permissions.utils.register_permission("Change", "change2")
|
||||
self.assertEqual(result, False)
|
||||
|
||||
# Is it there?
|
||||
p = Permission.objects.get(codename="change")
|
||||
self.assertEqual(p.name, "Change")
|
||||
|
||||
# Unregister the permission
|
||||
result = permissions.utils.unregister_permission("change")
|
||||
self.assertEqual(result, True)
|
||||
|
||||
# Is it not there anymore?
|
||||
self.assertRaises(Permission.DoesNotExist, Permission.objects.get, codename="change")
|
||||
|
||||
# Unregister the permission again
|
||||
result = permissions.utils.unregister_permission("change")
|
||||
self.assertEqual(result, False)
|
||||
|
||||
# django imports
|
||||
from django.core.handlers.wsgi import WSGIRequest
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.sessions.backends.file import SessionStore
|
||||
from django.test.client import Client
|
||||
|
||||
# Taken from "http://www.djangosnippets.org/snippets/963/"
|
||||
class RequestFactory(Client):
|
||||
"""
|
||||
Class that lets you create mock Request objects for use in testing.
|
||||
|
||||
Usage:
|
||||
|
||||
rf = RequestFactory()
|
||||
get_request = rf.get('/hello/')
|
||||
post_request = rf.post('/submit/', {'foo': 'bar'})
|
||||
|
||||
This class re-uses the django.test.client.Client interface, docs here:
|
||||
http://www.djangoproject.com/documentation/testing/#the-test-client
|
||||
|
||||
Once you have a request object you can pass it to any view function,
|
||||
just as if that view had been hooked up using a URLconf.
|
||||
|
||||
"""
|
||||
def request(self, **request):
|
||||
"""
|
||||
Similar to parent class, but returns the request object as soon as it
|
||||
has created it.
|
||||
"""
|
||||
environ = {
|
||||
'HTTP_COOKIE': self.cookies,
|
||||
'PATH_INFO': '/',
|
||||
'QUERY_STRING': '',
|
||||
'REQUEST_METHOD': 'GET',
|
||||
'SCRIPT_NAME': '',
|
||||
'SERVER_NAME': 'testserver',
|
||||
'SERVER_PORT': 80,
|
||||
'SERVER_PROTOCOL': 'HTTP/1.1',
|
||||
}
|
||||
environ.update(self.defaults)
|
||||
environ.update(request)
|
||||
return WSGIRequest(environ)
|
||||
|
||||
def create_request():
|
||||
"""
|
||||
"""
|
||||
rf = RequestFactory()
|
||||
request = rf.get('/')
|
||||
request.session = SessionStore()
|
||||
|
||||
user = User()
|
||||
user.is_superuser = True
|
||||
user.save()
|
||||
request.user = user
|
||||
|
||||
return request
|
665
permissions/utils.py
Normal file
665
permissions/utils.py
Normal file
|
@ -0,0 +1,665 @@
|
|||
# django imports
|
||||
from django.db import IntegrityError
|
||||
from django.db.models import Q
|
||||
from django.db import connection
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth.models import Group
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.cache import cache
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
|
||||
# permissions imports
|
||||
from permissions.exceptions import Unauthorized
|
||||
from permissions.models import ObjectPermission
|
||||
from permissions.models import ObjectPermissionInheritanceBlock
|
||||
from permissions.models import Permission
|
||||
from permissions.models import PrincipalRoleRelation
|
||||
from permissions.models import Role
|
||||
|
||||
|
||||
# Roles ######################################################################
|
||||
|
||||
def add_role(principal, role):
|
||||
"""Adds a global role to a principal.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
principal
|
||||
The principal (user or group) which gets the role added.
|
||||
|
||||
role
|
||||
The role which is assigned.
|
||||
"""
|
||||
if isinstance(principal, User):
|
||||
try:
|
||||
ppr = PrincipalRoleRelation.objects.get(user=principal, role=role, content_id=None, content_type=None)
|
||||
except PrincipalRoleRelation.DoesNotExist:
|
||||
PrincipalRoleRelation.objects.create(user=principal, role=role)
|
||||
return True
|
||||
else:
|
||||
try:
|
||||
ppr = PrincipalRoleRelation.objects.get(group=principal, role=role, content_id=None, content_type=None)
|
||||
except PrincipalRoleRelation.DoesNotExist:
|
||||
PrincipalRoleRelation.objects.create(group=principal, role=role)
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def add_local_role(obj, principal, role):
|
||||
"""Adds a local role to a principal.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
obj
|
||||
The object for which the principal gets the role.
|
||||
|
||||
principal
|
||||
The principal (user or group) which gets the role.
|
||||
|
||||
role
|
||||
The role which is assigned.
|
||||
"""
|
||||
ctype = ContentType.objects.get_for_model(obj)
|
||||
if isinstance(principal, User):
|
||||
try:
|
||||
ppr = PrincipalRoleRelation.objects.get(user=principal, role=role, content_id=obj.pk, content_type=ctype)
|
||||
except PrincipalRoleRelation.DoesNotExist:
|
||||
PrincipalRoleRelation.objects.create(user=principal, role=role, content=obj)
|
||||
return True
|
||||
else:
|
||||
try:
|
||||
ppr = PrincipalRoleRelation.objects.get(group=principal, role=role, content_id=obj.pk, content_type=ctype)
|
||||
except PrincipalRoleRelation.DoesNotExist:
|
||||
PrincipalRoleRelation.objects.create(group=principal, role=role, content=obj)
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def remove_role(principal, role):
|
||||
"""Removes role from passed principal.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
principal
|
||||
The principal (user or group) from which the role is removed.
|
||||
|
||||
role
|
||||
The role which is removed.
|
||||
"""
|
||||
try:
|
||||
if isinstance(principal, User):
|
||||
ppr = PrincipalRoleRelation.objects.get(
|
||||
user=principal, role=role, content_id=None, content_type=None)
|
||||
else:
|
||||
ppr = PrincipalRoleRelation.objects.get(
|
||||
group=principal, role=role, content_id=None, content_type=None)
|
||||
|
||||
except PrincipalRoleRelation.DoesNotExist:
|
||||
return False
|
||||
else:
|
||||
ppr.delete()
|
||||
|
||||
return True
|
||||
|
||||
def remove_local_role(obj, principal, role):
|
||||
"""Removes role from passed object and principle.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
obj
|
||||
The object from which the role is removed.
|
||||
|
||||
principal
|
||||
The principal (user or group) from which the role is removed.
|
||||
|
||||
role
|
||||
The role which is removed.
|
||||
"""
|
||||
try:
|
||||
ctype = ContentType.objects.get_for_model(obj)
|
||||
|
||||
if isinstance(principal, User):
|
||||
ppr = PrincipalRoleRelation.objects.get(
|
||||
user=principal, role=role, content_id=obj.pk, content_type=ctype)
|
||||
else:
|
||||
ppr = PrincipalRoleRelation.objects.get(
|
||||
group=principal, role=role, content_id=obj.pk, content_type=ctype)
|
||||
|
||||
except PrincipalRoleRelation.DoesNotExist:
|
||||
return False
|
||||
else:
|
||||
ppr.delete()
|
||||
|
||||
return True
|
||||
|
||||
def remove_roles(principal):
|
||||
"""Removes all roles passed principal (user or group).
|
||||
|
||||
**Parameters:**
|
||||
|
||||
principal
|
||||
The principal (user or group) from which all roles are removed.
|
||||
"""
|
||||
if isinstance(principal, User):
|
||||
ppr = PrincipalRoleRelation.objects.filter(
|
||||
user=principal, content_id=None, content_type=None)
|
||||
else:
|
||||
ppr = PrincipalRoleRelation.objects.filter(
|
||||
group=principal, content_id=None, content_type=None)
|
||||
|
||||
if ppr:
|
||||
ppr.delete()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def remove_local_roles(obj, principal):
|
||||
"""Removes all local roles from passed object and principal (user or
|
||||
group).
|
||||
|
||||
**Parameters:**
|
||||
|
||||
obj
|
||||
The object from which the roles are removed.
|
||||
|
||||
principal
|
||||
The principal (user or group) from which the roles are removed.
|
||||
"""
|
||||
ctype = ContentType.objects.get_for_model(obj)
|
||||
|
||||
if isinstance(principal, User):
|
||||
ppr = PrincipalRoleRelation.objects.filter(
|
||||
user=principal, content_id=obj.pk, content_type=ctype)
|
||||
else:
|
||||
ppr = PrincipalRoleRelation.objects.filter(
|
||||
group=principal, content_id=obj.pk, content_type=ctype)
|
||||
|
||||
if ppr:
|
||||
ppr.delete()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def get_roles(user, obj=None):
|
||||
"""Returns *all* roles of the passed user.
|
||||
|
||||
This takes direct roles and roles via the user's groups into account.
|
||||
|
||||
If an object is passed local roles will also added. Then all local roles
|
||||
from all ancestors and all user's groups are also taken into account.
|
||||
|
||||
This is the method to use if one want to know whether the passed user
|
||||
has a role in general (for the passed object).
|
||||
|
||||
**Parameters:**
|
||||
|
||||
user
|
||||
The user for which the roles are returned.
|
||||
|
||||
obj
|
||||
The object for which local roles will returned.
|
||||
|
||||
"""
|
||||
roles = []
|
||||
groups = user.groups.all()
|
||||
groups_ids_str = ", ".join([str(g.id) for g in groups])
|
||||
|
||||
# Gobal roles for user and the user's groups
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("""SELECT role_id
|
||||
FROM permissions_principalrolerelation
|
||||
WHERE (user_id=%s OR group_id IN (%s))
|
||||
AND content_id is Null""" % (user.id, groups_ids_str))
|
||||
|
||||
for row in cursor.fetchall():
|
||||
roles.append(row[0])
|
||||
|
||||
# Local roles for user and the user's groups and all ancestors of the
|
||||
# passed object.
|
||||
while obj:
|
||||
ctype = ContentType.objects.get_for_model(obj)
|
||||
cursor.execute("""SELECT role_id
|
||||
FROM permissions_principalrolerelation
|
||||
WHERE (user_id='%s' OR group_id IN (%s))
|
||||
AND content_id='%s'
|
||||
AND content_type_id='%s'""" % (user.id, groups_ids_str, obj.pk, ctype.id))
|
||||
|
||||
for row in cursor.fetchall():
|
||||
roles.append(row[0])
|
||||
|
||||
try:
|
||||
obj = obj.get_parent_for_permissions()
|
||||
except AttributeError:
|
||||
obj = None
|
||||
|
||||
return roles
|
||||
|
||||
def get_global_roles(principal):
|
||||
"""Returns *direct* global roles of passed principal (user or group).
|
||||
"""
|
||||
if isinstance(principal, User):
|
||||
return [prr.role for prr in PrincipalRoleRelation.objects.filter(
|
||||
user=principal, content_id=None, content_type=None)]
|
||||
else:
|
||||
if isinstance(principal, Group):
|
||||
principal = (principal,)
|
||||
return [prr.role for prr in PrincipalRoleRelation.objects.filter(
|
||||
group__in=principal, content_id=None, content_type=None)]
|
||||
|
||||
def get_local_roles(obj, principal):
|
||||
"""Returns *direct* local roles for passed principal and content object.
|
||||
"""
|
||||
ctype = ContentType.objects.get_for_model(obj)
|
||||
|
||||
if isinstance(principal, User):
|
||||
return [prr.role for prr in PrincipalRoleRelation.objects.filter(
|
||||
user=principal, content_id=obj.pk, content_type=ctype)]
|
||||
else:
|
||||
return [prr.role for prr in PrincipalRoleRelation.objects.filter(
|
||||
group=principal, content_id=obj.pk, content_type=ctype)]
|
||||
|
||||
# Permissions ################################################################
|
||||
|
||||
def check_permission(obj, user, codename, roles=None):
|
||||
"""Checks whether passed user has passed permission for passed obj.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
obj
|
||||
The object for which the permission should be checked.
|
||||
|
||||
codename
|
||||
The permission's codename which should be checked.
|
||||
|
||||
user
|
||||
The user for which the permission should be checked.
|
||||
|
||||
roles
|
||||
If given these roles will be assigned to the user temporarily before
|
||||
the permissions are checked.
|
||||
"""
|
||||
if not has_permission(obj, user, codename):
|
||||
raise Unauthorized("User '%s' doesn't have permission '%s' for object '%s' (%s)"
|
||||
% (user, codename, obj.slug, obj.__class__.__name__))
|
||||
|
||||
def grant_permission(obj, role, permission):
|
||||
"""Grants passed permission to passed role. Returns True if the permission
|
||||
was able to be added, otherwise False.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
obj
|
||||
The content object for which the permission should be granted.
|
||||
|
||||
role
|
||||
The role for which the permission should be granted.
|
||||
|
||||
permission
|
||||
The permission which should be granted. Either a permission
|
||||
object or the codename of a permission.
|
||||
"""
|
||||
if not isinstance(permission, Permission):
|
||||
try:
|
||||
permission = Permission.objects.get(codename = permission)
|
||||
except Permission.DoesNotExist:
|
||||
return False
|
||||
|
||||
ct = ContentType.objects.get_for_model(obj)
|
||||
try:
|
||||
ObjectPermission.objects.get(role=role, content_type = ct, content_id=obj.pk, permission=permission)
|
||||
except ObjectPermission.DoesNotExist:
|
||||
ObjectPermission.objects.create(role=role, content=obj, permission=permission)
|
||||
|
||||
return True
|
||||
|
||||
def remove_permission(obj, role, permission):
|
||||
"""Removes passed permission from passed role and object. Returns True if
|
||||
the permission has been removed.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
obj
|
||||
The content object for which a permission should be removed.
|
||||
|
||||
role
|
||||
The role for which a permission should be removed.
|
||||
|
||||
permission
|
||||
The permission which should be removed. Either a permission object
|
||||
or the codename of a permission.
|
||||
"""
|
||||
if not isinstance(permission, Permission):
|
||||
try:
|
||||
permission = Permission.objects.get(codename = permission)
|
||||
except Permission.DoesNotExist:
|
||||
return False
|
||||
|
||||
ct = ContentType.objects.get_for_model(obj)
|
||||
|
||||
try:
|
||||
op = ObjectPermission.objects.get(role=role, content_type = ct, content_id=obj.pk, permission = permission)
|
||||
except ObjectPermission.DoesNotExist:
|
||||
return False
|
||||
|
||||
op.delete()
|
||||
return True
|
||||
|
||||
def has_permission(obj, user, codename, roles=None):
|
||||
"""Checks whether the passed user has passed permission for passed object.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
obj
|
||||
The object for which the permission should be checked.
|
||||
|
||||
codename
|
||||
The permission's codename which should be checked.
|
||||
|
||||
request
|
||||
The current request.
|
||||
|
||||
roles
|
||||
If given these roles will be assigned to the user temporarily before
|
||||
the permissions are checked.
|
||||
"""
|
||||
cache_key = "%s-%s-%s" % (obj.content_type, obj.pk, codename)
|
||||
result = _get_cached_permission(user, cache_key)
|
||||
if result is not None:
|
||||
return result
|
||||
|
||||
if roles is None:
|
||||
roles = []
|
||||
|
||||
if user.is_superuser:
|
||||
return True
|
||||
|
||||
if not user.is_anonymous():
|
||||
roles.extend(get_roles(user, obj))
|
||||
|
||||
ct = ContentType.objects.get_for_model(obj)
|
||||
|
||||
result = False
|
||||
while obj is not None:
|
||||
p = ObjectPermission.objects.filter(
|
||||
content_type=ct, content_id=obj.pk, role__in=roles, permission__codename = codename).values("id")
|
||||
|
||||
if len(p) > 0:
|
||||
result = True
|
||||
break
|
||||
|
||||
if is_inherited(obj, codename) == False:
|
||||
result = False
|
||||
break
|
||||
|
||||
try:
|
||||
obj = obj.get_parent_for_permissions()
|
||||
ct = ContentType.objects.get_for_model(obj)
|
||||
except AttributeError:
|
||||
result = False
|
||||
break
|
||||
|
||||
_cache_permission(user, cache_key, result)
|
||||
return result
|
||||
|
||||
# Inheritance ################################################################
|
||||
|
||||
def add_inheritance_block(obj, permission):
|
||||
"""Adds an inheritance for the passed permission on the passed obj.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
permission
|
||||
The permission for which an inheritance block should be added.
|
||||
Either a permission object or the codename of a permission.
|
||||
obj
|
||||
The content object for which an inheritance block should be added.
|
||||
"""
|
||||
if not isinstance(permission, Permission):
|
||||
try:
|
||||
permission = Permission.objects.get(codename = permission)
|
||||
except Permission.DoesNotExist:
|
||||
return False
|
||||
|
||||
ct = ContentType.objects.get_for_model(obj)
|
||||
try:
|
||||
ObjectPermissionInheritanceBlock.objects.get(content_type = ct, content_id=obj.pk, permission=permission)
|
||||
except ObjectPermissionInheritanceBlock.DoesNotExist:
|
||||
try:
|
||||
result = ObjectPermissionInheritanceBlock.objects.create(content=obj, permission=permission)
|
||||
except IntegrityError:
|
||||
return False
|
||||
return True
|
||||
|
||||
def remove_inheritance_block(obj, permission):
|
||||
"""Removes a inheritance block for the passed permission from the passed
|
||||
object.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
obj
|
||||
The content object for which an inheritance block should be added.
|
||||
|
||||
permission
|
||||
The permission for which an inheritance block should be removed.
|
||||
Either a permission object or the codename of a permission.
|
||||
"""
|
||||
if not isinstance(permission, Permission):
|
||||
try:
|
||||
permission = Permission.objects.get(codename = permission)
|
||||
except Permission.DoesNotExist:
|
||||
return False
|
||||
|
||||
ct = ContentType.objects.get_for_model(obj)
|
||||
try:
|
||||
opi = ObjectPermissionInheritanceBlock.objects.get(content_type = ct, content_id=obj.pk, permission=permission)
|
||||
except ObjectPermissionInheritanceBlock.DoesNotExist:
|
||||
return False
|
||||
|
||||
opi.delete()
|
||||
return True
|
||||
|
||||
def is_inherited(obj, codename):
|
||||
"""Returns True if the passed permission is inherited for passed object.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
obj
|
||||
The content object for which the permission should be checked.
|
||||
|
||||
codename
|
||||
The permission which should be checked. Must be the codename of
|
||||
the permission.
|
||||
"""
|
||||
ct = ContentType.objects.get_for_model(obj)
|
||||
try:
|
||||
ObjectPermissionInheritanceBlock.objects.get(
|
||||
content_type=ct, content_id=obj.pk, permission__codename = codename)
|
||||
except ObjectDoesNotExist:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def get_group(id):
|
||||
"""Returns the group with passed id or None.
|
||||
"""
|
||||
try:
|
||||
return Group.objects.get(pk=id)
|
||||
except Group.DoesNotExist:
|
||||
return None
|
||||
|
||||
def get_role(id):
|
||||
"""Returns the role with passed id or None.
|
||||
"""
|
||||
try:
|
||||
return Role.objects.get(pk=id)
|
||||
except Role.DoesNotExist:
|
||||
return None
|
||||
|
||||
def get_user(id):
|
||||
"""Returns the user with passed id or None.
|
||||
"""
|
||||
try:
|
||||
return User.objects.get(pk=id)
|
||||
except User.DoesNotExist:
|
||||
return None
|
||||
|
||||
def has_group(user, group):
|
||||
"""Returns True if passed user has passed group.
|
||||
"""
|
||||
if isinstance(group, str):
|
||||
group = Group.objects.get(name=group)
|
||||
|
||||
return group in user.groups.all()
|
||||
|
||||
def reset(obj):
|
||||
"""Resets all permissions and inheritance blocks of passed object.
|
||||
"""
|
||||
ctype = ContentType.objects.get_for_model(obj)
|
||||
ObjectPermissionInheritanceBlock.objects.filter(content_id=obj.pk, content_type=ctype).delete()
|
||||
ObjectPermission.objects.filter(content_id=obj.pk, content_type=ctype).delete()
|
||||
|
||||
# Registering ################################################################
|
||||
|
||||
def register_permission(name, codename, ctypes=[]):
|
||||
"""Registers a permission to the framework. Returns the permission if the
|
||||
registration was successfully, otherwise False.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
name
|
||||
The unique name of the permission. This is displayed to the
|
||||
customer.
|
||||
codename
|
||||
The unique codename of the permission. This is used internally to
|
||||
identify the permission.
|
||||
content_types
|
||||
The content type for which the permission is active. This can be
|
||||
used to display only reasonable permissions for an object. This
|
||||
must be a Django ContentType
|
||||
"""
|
||||
try:
|
||||
p = Permission.objects.create(name=name, codename=codename)
|
||||
|
||||
ctypes = [ContentType.objects.get_for_model(ctype) for ctype in ctypes]
|
||||
if ctypes:
|
||||
p.content_types = ctypes
|
||||
p.save()
|
||||
except IntegrityError:
|
||||
return False
|
||||
return p
|
||||
|
||||
def unregister_permission(codename):
|
||||
"""Unregisters a permission from the framework
|
||||
|
||||
**Parameters:**
|
||||
|
||||
codename
|
||||
The unique codename of the permission.
|
||||
"""
|
||||
try:
|
||||
permission = Permission.objects.get(codename=codename)
|
||||
except Permission.DoesNotExist:
|
||||
return False
|
||||
permission.delete()
|
||||
return True
|
||||
|
||||
def register_role(name):
|
||||
"""Registers a role with passed name to the framework. Returns the new
|
||||
role if the registration was successfully, otherwise False.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
name
|
||||
The unique role name.
|
||||
"""
|
||||
try:
|
||||
role = Role.objects.create(name=name)
|
||||
except IntegrityError:
|
||||
return False
|
||||
return role
|
||||
|
||||
def unregister_role(name):
|
||||
"""Unregisters the role with passed name.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
name
|
||||
The unique role name.
|
||||
"""
|
||||
try:
|
||||
role = Role.objects.get(name=name)
|
||||
except Role.DoesNotExist:
|
||||
return False
|
||||
|
||||
role.delete()
|
||||
return True
|
||||
|
||||
def register_group(name):
|
||||
"""Registers a group with passed name to the framework. Returns the new
|
||||
group if the registration was successfully, otherwise False.
|
||||
|
||||
Actually this creates just a default Django Group.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
name
|
||||
The unique group name.
|
||||
"""
|
||||
try:
|
||||
group = Group.objects.create(name=name)
|
||||
except IntegrityError:
|
||||
return False
|
||||
return group
|
||||
|
||||
def unregister_group(name):
|
||||
"""Unregisters the group with passed name. Returns True if the
|
||||
unregistration was succesfull otherwise False.
|
||||
|
||||
Actually this deletes just a default Django Group.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
name
|
||||
The unique role name.
|
||||
"""
|
||||
try:
|
||||
group = Group.objects.get(name=name)
|
||||
except Group.DoesNotExist:
|
||||
return False
|
||||
|
||||
group.delete()
|
||||
return True
|
||||
|
||||
def _cache_permission(user, cache_key, data):
|
||||
"""Stores the passed data on the passed user object.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
user
|
||||
The user on which the data is stored.
|
||||
|
||||
cache_key
|
||||
The key under which the data is stored.
|
||||
|
||||
data
|
||||
The data which is stored.
|
||||
"""
|
||||
if not getattr(user, "permissions", None):
|
||||
user.permissions = {}
|
||||
user.permissions[cache_key] = data
|
||||
|
||||
def _get_cached_permission(user, cache_key):
|
||||
"""Returns the stored data from passed user object for passed cache_key.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
user
|
||||
The user from which the data is retrieved.
|
||||
|
||||
cache_key
|
||||
The key under which the data is stored.
|
||||
|
||||
"""
|
||||
permissions = getattr(user, "permissions", None)
|
||||
if permissions:
|
||||
return user.permissions.get(cache_key, None)
|
|
@ -71,6 +71,17 @@ body { margin: 0; }
|
|||
.ietf-ballot .square { border:1px solid black; display: block; float:left;width: 10px; height:10px;font-size:1px;margin-right:4px; margin-top:1px;}
|
||||
.ietf-ballot .was { padding-left: 10px; font-size:85%; }
|
||||
|
||||
.ietf-stream tr { vertical-align: top; }
|
||||
.ietf-stream ul.ietf-stream-tag-list { padding: 10px; margin: 0px; list-style-type: none; font-size: 10px; }
|
||||
.ietf-stream ul.ietf-stream-tag-list li { margin-bottom: 1em; list-style-type: circle; color: #999999; }
|
||||
.ietf-stream ul.ietf-stream-tag-list li.tag_set { font-weight: bold; list-style-type: disc; color: black; }
|
||||
.ietf-stream td.right { padding-top: 1em; }
|
||||
.ietf-stream .ietf-stream-head h2, .ietf-stream .ietf-stream-head h3 { margin: 0px; }
|
||||
.ietf-stream .ietf-stream-head { margin-bottom: 2em; }
|
||||
.ietf-stream .entry-title { background: #2647A0; color:white; padding: 2px 4px; font-size: 108%; margin-top: 0;}
|
||||
.ietf-stream .entry-title .entry-date { float: right; }
|
||||
.ietf-stream .entry-comment { background: #eeeeee; margin: 1em 0px; padding: 1em; }
|
||||
|
||||
.search_form_box {width: 99.5%; margin-top:8px; padding:4px; margin-bottom:1em; padding-left:8px;}
|
||||
form#search_form { padding-top: 4px; padding-bottom: 4px; }
|
||||
#search_form input { padding: 0; padding-left: 2px; border: 1px solid #89d;}
|
||||
|
|
|
@ -74,3 +74,53 @@ function showBallot(draftName, editPositionUrl) {
|
|||
function editBallot(editPositionUrl) {
|
||||
window.open(editPositionUrl);
|
||||
}
|
||||
function showStream(dialogTitle, infoStreamUrl) {
|
||||
var handleClose = function() {
|
||||
IETF.streamDialog.hide();
|
||||
};
|
||||
var el;
|
||||
|
||||
if (!IETF.streamDialog) {
|
||||
el = document.createElement("div");
|
||||
el.innerHTML = '<div id="stream_dialog" style="visibility:hidden;"><div class="hd"><span id="stream_title">' + dialogTitle + '</span></div><div class="bd"> <div id="stream_dialog_body" style="overflow-y:scroll; height:400px;"></div> </div></div>';
|
||||
document.getElementById("ietf-extras").appendChild(el);
|
||||
|
||||
var buttons = [{text:"Close", handler:handleClose, isDefault:true}];
|
||||
var kl = [new YAHOO.util.KeyListener(document, {keys:27}, handleClose)]
|
||||
IETF.streamDialog = new YAHOO.widget.Dialog("stream_dialog", {
|
||||
visible:false, draggable:false, close:true, modal:true,
|
||||
width:"860px", fixedcenter:true, constraintoviewport:true,
|
||||
buttons: buttons, keylisteners:kl});
|
||||
IETF.streamDialog.render();
|
||||
}
|
||||
document.getElementById("stream_title").innerHTML = dialogTitle;
|
||||
IETF.streamDialog.show();
|
||||
|
||||
el = document.getElementById("stream_dialog_body");
|
||||
el.innerHTML = "Loading...";
|
||||
YAHOO.util.Connect.asyncRequest('GET',
|
||||
infoStreamUrl,
|
||||
{ success: function(o) { el.innerHTML = (o.responseText !== undefined) ? o.responseText : "?"; },
|
||||
failure: function(o) { el.innerHTML = "Error: "+o.status+" "+o.statusText; },
|
||||
argument: null
|
||||
}, null);
|
||||
}
|
||||
(function ($) {
|
||||
|
||||
$.fn.StreamInfo = function() {
|
||||
return this.each(function () {
|
||||
var infoStreamUrl = $(this).attr('href');
|
||||
var title = $(this).attr('title');
|
||||
|
||||
$(this).click(function() {
|
||||
showStream(title, infoStreamUrl);
|
||||
return false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
$(document).ready(function () {
|
||||
$('a.show_stream_info').StreamInfo();
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
|
|
61
workflows/__init__.py
Normal file
61
workflows/__init__.py
Normal file
|
@ -0,0 +1,61 @@
|
|||
# workflows imports
|
||||
import workflows.utils
|
||||
|
||||
class WorkflowBase(object):
|
||||
"""Mixin class to make objects workflow aware.
|
||||
"""
|
||||
def get_workflow(self):
|
||||
"""Returns the current workflow of the object.
|
||||
"""
|
||||
return workflows.utils.get_workflow(self)
|
||||
|
||||
def remove_workflow(self):
|
||||
"""Removes the workflow from the object. After this function has been
|
||||
called the object has no *own* workflow anymore (it might have one via
|
||||
its content type).
|
||||
|
||||
"""
|
||||
return workflows.utils.remove_workflow_from_object(self)
|
||||
|
||||
def set_workflow(self, workflow):
|
||||
"""Sets the passed workflow to the object. This will set the local
|
||||
workflow for the object.
|
||||
|
||||
If the object has already the given workflow nothing happens.
|
||||
Otherwise the object gets the passed workflow and the state is set to
|
||||
the workflow's initial state.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
workflow
|
||||
The workflow which should be set to the object. Can be a Workflow
|
||||
instance or a string with the workflow name.
|
||||
obj
|
||||
The object which gets the passed workflow.
|
||||
"""
|
||||
return workflows.utils.set_workflow_for_object(workflow)
|
||||
|
||||
def get_state(self):
|
||||
"""Returns the current workflow state of the object.
|
||||
"""
|
||||
return workflows.utils.get_state(self)
|
||||
|
||||
def set_state(self, state):
|
||||
"""Sets the workflow state of the object.
|
||||
"""
|
||||
return workflows.utils.set_state(self, state)
|
||||
|
||||
def set_initial_state(self):
|
||||
"""Sets the initial state of the current workflow to the object.
|
||||
"""
|
||||
return self.set_state(self.get_workflow().initial_state)
|
||||
|
||||
def get_allowed_transitions(self, user):
|
||||
"""Returns allowed transitions for the current state.
|
||||
"""
|
||||
return workflows.utils.get_allowed_transitions(self, user)
|
||||
|
||||
def do_transition(self, transition, user):
|
||||
"""Processes the passed transition (if allowed).
|
||||
"""
|
||||
return workflows.utils.do_transition(self, transition, user)
|
30
workflows/admin.py
Normal file
30
workflows/admin.py
Normal file
|
@ -0,0 +1,30 @@
|
|||
from django.contrib import admin
|
||||
from workflows.models import State
|
||||
from workflows.models import StateInheritanceBlock
|
||||
from workflows.models import StatePermissionRelation
|
||||
from workflows.models import StateObjectRelation
|
||||
from workflows.models import Transition
|
||||
from workflows.models import Workflow
|
||||
from workflows.models import WorkflowObjectRelation
|
||||
from workflows.models import WorkflowModelRelation
|
||||
from workflows.models import WorkflowPermissionRelation
|
||||
|
||||
class StateInline(admin.TabularInline):
|
||||
model = State
|
||||
|
||||
class WorkflowAdmin(admin.ModelAdmin):
|
||||
inlines = [
|
||||
StateInline,
|
||||
]
|
||||
|
||||
admin.site.register(Workflow, WorkflowAdmin)
|
||||
|
||||
admin.site.register(State)
|
||||
admin.site.register(StateInheritanceBlock)
|
||||
admin.site.register(StateObjectRelation)
|
||||
admin.site.register(StatePermissionRelation)
|
||||
admin.site.register(Transition)
|
||||
admin.site.register(WorkflowObjectRelation)
|
||||
admin.site.register(WorkflowModelRelation)
|
||||
admin.site.register(WorkflowPermissionRelation)
|
||||
|
BIN
workflows/locale/de/LC_MESSAGES/django.mo
Normal file
BIN
workflows/locale/de/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
60
workflows/locale/de/LC_MESSAGES/django.po
Normal file
60
workflows/locale/de/LC_MESSAGES/django.po
Normal file
|
@ -0,0 +1,60 @@
|
|||
# German translations for django-workflows
|
||||
# Copyright (C) 2010 Kai Diefenbach
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# Kai Diefenbach <kai.diefenbach@iqpp.de>, 2010.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 1.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2010-04-02 09:16+0200\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: models.py:98 models.py:199 models.py:237
|
||||
msgid "Name"
|
||||
msgstr "Name"
|
||||
|
||||
#: models.py:200 models.py:238 models.py:285 models.py:307
|
||||
msgid "Workflow"
|
||||
msgstr "Arbeitsablauf"
|
||||
|
||||
#: models.py:201
|
||||
msgid "Transitions"
|
||||
msgstr "Übergänge"
|
||||
|
||||
#: models.py:239
|
||||
msgid "Destination"
|
||||
msgstr "Ziel"
|
||||
|
||||
#: models.py:240
|
||||
msgid "Condition"
|
||||
msgstr "Kondition"
|
||||
|
||||
#: models.py:241 models.py:350 models.py:373
|
||||
msgid "Permission"
|
||||
msgstr "Recht"
|
||||
|
||||
#: models.py:258 models.py:282
|
||||
msgid "Content type"
|
||||
msgstr "Inhaltstyp"
|
||||
|
||||
#: models.py:259 models.py:283
|
||||
msgid "Content id"
|
||||
msgstr "Inhalts-ID"
|
||||
|
||||
#: models.py:261 models.py:349 models.py:372
|
||||
msgid "State"
|
||||
msgstr "Status"
|
||||
|
||||
#: models.py:306
|
||||
msgid "Content Type"
|
||||
msgstr "Inhaltstyp"
|
||||
|
||||
#: models.py:374
|
||||
msgid "Role"
|
||||
msgstr "Rolle"
|
225
workflows/migrations/0001_initial.py
Normal file
225
workflows/migrations/0001_initial.py
Normal file
|
@ -0,0 +1,225 @@
|
|||
|
||||
from south.db import db
|
||||
from django.db import models
|
||||
from workflows.models import *
|
||||
|
||||
class Migration:
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Adding model 'Workflow'
|
||||
db.create_table('workflows_workflow', (
|
||||
('id', orm['workflows.Workflow:id']),
|
||||
('name', orm['workflows.Workflow:name']),
|
||||
('initial_state', orm['workflows.Workflow:initial_state']),
|
||||
))
|
||||
db.send_create_signal('workflows', ['Workflow'])
|
||||
|
||||
# Adding model 'StatePermissionRelation'
|
||||
db.create_table('workflows_statepermissionrelation', (
|
||||
('id', orm['workflows.StatePermissionRelation:id']),
|
||||
('state', orm['workflows.StatePermissionRelation:state']),
|
||||
('permission', orm['workflows.StatePermissionRelation:permission']),
|
||||
('role', orm['workflows.StatePermissionRelation:role']),
|
||||
))
|
||||
db.send_create_signal('workflows', ['StatePermissionRelation'])
|
||||
|
||||
# Adding model 'StateInheritanceBlock'
|
||||
db.create_table('workflows_stateinheritanceblock', (
|
||||
('id', orm['workflows.StateInheritanceBlock:id']),
|
||||
('state', orm['workflows.StateInheritanceBlock:state']),
|
||||
('permission', orm['workflows.StateInheritanceBlock:permission']),
|
||||
))
|
||||
db.send_create_signal('workflows', ['StateInheritanceBlock'])
|
||||
|
||||
# Adding model 'WorkflowModelRelation'
|
||||
db.create_table('workflows_workflowmodelrelation', (
|
||||
('id', orm['workflows.WorkflowModelRelation:id']),
|
||||
('content_type', orm['workflows.WorkflowModelRelation:content_type']),
|
||||
('workflow', orm['workflows.WorkflowModelRelation:workflow']),
|
||||
))
|
||||
db.send_create_signal('workflows', ['WorkflowModelRelation'])
|
||||
|
||||
# Adding model 'WorkflowPermissionRelation'
|
||||
db.create_table('workflows_workflowpermissionrelation', (
|
||||
('id', orm['workflows.WorkflowPermissionRelation:id']),
|
||||
('workflow', orm['workflows.WorkflowPermissionRelation:workflow']),
|
||||
('permission', orm['workflows.WorkflowPermissionRelation:permission']),
|
||||
))
|
||||
db.send_create_signal('workflows', ['WorkflowPermissionRelation'])
|
||||
|
||||
# Adding model 'State'
|
||||
db.create_table('workflows_state', (
|
||||
('id', orm['workflows.State:id']),
|
||||
('name', orm['workflows.State:name']),
|
||||
('workflow', orm['workflows.State:workflow']),
|
||||
))
|
||||
db.send_create_signal('workflows', ['State'])
|
||||
|
||||
# Adding model 'Transition'
|
||||
db.create_table('workflows_transition', (
|
||||
('id', orm['workflows.Transition:id']),
|
||||
('name', orm['workflows.Transition:name']),
|
||||
('workflow', orm['workflows.Transition:workflow']),
|
||||
('destination', orm['workflows.Transition:destination']),
|
||||
('condition', orm['workflows.Transition:condition']),
|
||||
('permission', orm['workflows.Transition:permission']),
|
||||
))
|
||||
db.send_create_signal('workflows', ['Transition'])
|
||||
|
||||
# Adding model 'WorkflowObjectRelation'
|
||||
db.create_table('workflows_workflowobjectrelation', (
|
||||
('id', orm['workflows.WorkflowObjectRelation:id']),
|
||||
('content_type', orm['workflows.WorkflowObjectRelation:content_type']),
|
||||
('content_id', orm['workflows.WorkflowObjectRelation:content_id']),
|
||||
('workflow', orm['workflows.WorkflowObjectRelation:workflow']),
|
||||
))
|
||||
db.send_create_signal('workflows', ['WorkflowObjectRelation'])
|
||||
|
||||
# Adding model 'StateObjectRelation'
|
||||
db.create_table('workflows_stateobjectrelation', (
|
||||
('id', orm['workflows.StateObjectRelation:id']),
|
||||
('content_type', orm['workflows.StateObjectRelation:content_type']),
|
||||
('content_id', orm['workflows.StateObjectRelation:content_id']),
|
||||
('state', orm['workflows.StateObjectRelation:state']),
|
||||
))
|
||||
db.send_create_signal('workflows', ['StateObjectRelation'])
|
||||
|
||||
# Adding ManyToManyField 'State.transitions'
|
||||
db.create_table('workflows_state_transitions', (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('state', models.ForeignKey(orm.State, null=False)),
|
||||
('transition', models.ForeignKey(orm.Transition, null=False))
|
||||
))
|
||||
|
||||
# Creating unique_together for [content_type, content_id] on WorkflowObjectRelation.
|
||||
db.create_unique('workflows_workflowobjectrelation', ['content_type_id', 'content_id'])
|
||||
|
||||
# Creating unique_together for [content_type, content_id, state] on StateObjectRelation.
|
||||
db.create_unique('workflows_stateobjectrelation', ['content_type_id', 'content_id', 'state_id'])
|
||||
|
||||
# Creating unique_together for [workflow, permission] on WorkflowPermissionRelation.
|
||||
db.create_unique('workflows_workflowpermissionrelation', ['workflow_id', 'permission_id'])
|
||||
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Deleting unique_together for [workflow, permission] on WorkflowPermissionRelation.
|
||||
db.delete_unique('workflows_workflowpermissionrelation', ['workflow_id', 'permission_id'])
|
||||
|
||||
# Deleting unique_together for [content_type, content_id, state] on StateObjectRelation.
|
||||
db.delete_unique('workflows_stateobjectrelation', ['content_type_id', 'content_id', 'state_id'])
|
||||
|
||||
# Deleting unique_together for [content_type, content_id] on WorkflowObjectRelation.
|
||||
db.delete_unique('workflows_workflowobjectrelation', ['content_type_id', 'content_id'])
|
||||
|
||||
# Deleting model 'Workflow'
|
||||
db.delete_table('workflows_workflow')
|
||||
|
||||
# Deleting model 'StatePermissionRelation'
|
||||
db.delete_table('workflows_statepermissionrelation')
|
||||
|
||||
# Deleting model 'StateInheritanceBlock'
|
||||
db.delete_table('workflows_stateinheritanceblock')
|
||||
|
||||
# Deleting model 'WorkflowModelRelation'
|
||||
db.delete_table('workflows_workflowmodelrelation')
|
||||
|
||||
# Deleting model 'WorkflowPermissionRelation'
|
||||
db.delete_table('workflows_workflowpermissionrelation')
|
||||
|
||||
# Deleting model 'State'
|
||||
db.delete_table('workflows_state')
|
||||
|
||||
# Deleting model 'Transition'
|
||||
db.delete_table('workflows_transition')
|
||||
|
||||
# Deleting model 'WorkflowObjectRelation'
|
||||
db.delete_table('workflows_workflowobjectrelation')
|
||||
|
||||
# Deleting model 'StateObjectRelation'
|
||||
db.delete_table('workflows_stateobjectrelation')
|
||||
|
||||
# Dropping ManyToManyField 'State.transitions'
|
||||
db.delete_table('workflows_state_transitions')
|
||||
|
||||
|
||||
|
||||
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'})
|
||||
},
|
||||
'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 = ['workflows']
|
0
workflows/migrations/__init__.py
Normal file
0
workflows/migrations/__init__.py
Normal file
357
workflows/models.py
Normal file
357
workflows/models.py
Normal file
|
@ -0,0 +1,357 @@
|
|||
from django.db import models
|
||||
|
||||
# django imports
|
||||
from django.contrib.contenttypes import generic
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
# permissions imports
|
||||
import permissions.utils
|
||||
from permissions.models import Permission
|
||||
from permissions.models import Role
|
||||
|
||||
class Workflow(models.Model):
|
||||
"""A workflow consists of a sequence of connected (through transitions)
|
||||
states. It can be assigned to a model and / or model instances. If a
|
||||
model instance has a workflow it takes precendence over the model's
|
||||
workflow.
|
||||
|
||||
**Attributes:**
|
||||
|
||||
model
|
||||
The model the workflow belongs to. Can be any
|
||||
|
||||
content
|
||||
The object the workflow belongs to.
|
||||
|
||||
name
|
||||
The unique name of the workflow.
|
||||
|
||||
states
|
||||
The states of the workflow.
|
||||
|
||||
initial_state
|
||||
The initial state the model / content gets if created.
|
||||
|
||||
"""
|
||||
name = models.CharField(_(u"Name"), max_length=100, unique=True)
|
||||
initial_state = models.ForeignKey("State", related_name="workflow_state", blank=True, null=True)
|
||||
permissions = models.ManyToManyField(Permission, symmetrical=False, through="WorkflowPermissionRelation")
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
def get_initial_state(self):
|
||||
"""Returns the initial state of the workflow. Takes the first one if
|
||||
no state has been defined.
|
||||
"""
|
||||
if self.initial_state:
|
||||
return self.initial_state
|
||||
else:
|
||||
try:
|
||||
return self.states.all()[0]
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
def get_objects(self):
|
||||
"""Returns all objects which have this workflow assigned. Globally
|
||||
(via the object's content type) or locally (via the object itself).
|
||||
"""
|
||||
import workflows.utils
|
||||
objs = []
|
||||
|
||||
# Get all objects whose content type has this workflow
|
||||
for wmr in WorkflowModelRelation.objects.filter(workflow=self):
|
||||
ctype = wmr.content_type
|
||||
# We have also to check whether the global workflow is not
|
||||
# overwritten.
|
||||
for obj in ctype.model_class().objects.all():
|
||||
if workflows.utils.get_workflow(obj) == self:
|
||||
objs.append(obj)
|
||||
|
||||
# Get all objects whose local workflow this workflow
|
||||
for wor in WorkflowObjectRelation.objects.filter(workflow=self):
|
||||
if wor.content not in objs:
|
||||
objs.append(wor.content)
|
||||
|
||||
return objs
|
||||
|
||||
def set_to(self, ctype_or_obj):
|
||||
"""Sets the workflow to passed content type or object. See the specific
|
||||
methods for more information.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
ctype_or_obj
|
||||
The content type or the object to which the workflow should be set.
|
||||
Can be either a ContentType instance or any Django model instance.
|
||||
"""
|
||||
if isinstance(ctype_or_obj, ContentType):
|
||||
return self.set_to_model(ctype_or_obj)
|
||||
else:
|
||||
return self.set_to_object(ctype_or_obj)
|
||||
|
||||
def set_to_model(self, ctype):
|
||||
"""Sets the workflow to the passed content type. If the content
|
||||
type has already an assigned workflow the workflow is overwritten.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
ctype
|
||||
The content type which gets the workflow. Can be any Django model
|
||||
instance.
|
||||
"""
|
||||
try:
|
||||
wor = WorkflowModelRelation.objects.get(content_type=ctype)
|
||||
except WorkflowModelRelation.DoesNotExist:
|
||||
WorkflowModelRelation.objects.create(content_type=ctype, workflow=self)
|
||||
else:
|
||||
wor.workflow = self
|
||||
wor.save()
|
||||
|
||||
def set_to_object(self, obj):
|
||||
"""Sets the workflow to the passed object.
|
||||
|
||||
If the object has already the given workflow nothing happens. Otherwise
|
||||
the workflow is set to the objectthe state is set to the workflow's
|
||||
initial state.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
obj
|
||||
The object which gets the workflow.
|
||||
"""
|
||||
import workflows.utils
|
||||
|
||||
ctype = ContentType.objects.get_for_model(obj)
|
||||
try:
|
||||
wor = WorkflowObjectRelation.objects.get(content_type=ctype, content_id=obj.pk)
|
||||
except WorkflowObjectRelation.DoesNotExist:
|
||||
WorkflowObjectRelation.objects.create(content = obj, workflow=self)
|
||||
workflows.utils.set_state(obj, self.initial_state)
|
||||
else:
|
||||
if wor.workflow != self:
|
||||
wor.workflow = self
|
||||
wor.save()
|
||||
workflows.utils.set_state(self.initial_state)
|
||||
|
||||
class State(models.Model):
|
||||
"""A certain state within workflow.
|
||||
|
||||
**Attributes:**
|
||||
|
||||
name
|
||||
The unique name of the state within the workflow.
|
||||
|
||||
workflow
|
||||
The workflow to which the state belongs.
|
||||
|
||||
transitions
|
||||
The transitions of a workflow state.
|
||||
|
||||
"""
|
||||
name = models.CharField(_(u"Name"), max_length=100)
|
||||
workflow = models.ForeignKey(Workflow, verbose_name=_(u"Workflow"), related_name="states")
|
||||
transitions = models.ManyToManyField("Transition", verbose_name=_(u"Transitions"), blank=True, null=True, related_name="states")
|
||||
|
||||
class Meta:
|
||||
ordering = ("name", )
|
||||
|
||||
def __unicode__(self):
|
||||
return "%s (%s)" % (self.name, self.workflow.name)
|
||||
|
||||
def get_allowed_transitions(self, obj, user):
|
||||
"""Returns all allowed transitions for passed object and user.
|
||||
"""
|
||||
transitions = []
|
||||
for transition in self.transitions.all():
|
||||
permission = transition.permission
|
||||
if permission is None:
|
||||
transitions.append(transition)
|
||||
else:
|
||||
# First we try to get the objects specific has_permission
|
||||
# method (in case the object inherits from the PermissionBase
|
||||
# class).
|
||||
try:
|
||||
if obj.has_permission(user, permission.codename):
|
||||
transitions.append(transition)
|
||||
except AttributeError:
|
||||
if permissions.utils.has_permission(obj, user, permission.codename):
|
||||
transitions.append(transition)
|
||||
return transitions
|
||||
|
||||
class Transition(models.Model):
|
||||
"""A transition from a source to a destination state. The transition can
|
||||
be used from several source states.
|
||||
|
||||
**Attributes:**
|
||||
|
||||
name
|
||||
The unique name of the transition within a workflow.
|
||||
|
||||
workflow
|
||||
The workflow to which the transition belongs. Must be a Workflow
|
||||
instance.
|
||||
|
||||
destination
|
||||
The state after a transition has been processed. Must be a State
|
||||
instance.
|
||||
|
||||
condition
|
||||
The condition when the transition is available. Can be any python
|
||||
expression.
|
||||
|
||||
permission
|
||||
The necessary permission to process the transition. Must be a
|
||||
Permission instance.
|
||||
|
||||
"""
|
||||
name = models.CharField(_(u"Name"), max_length=100)
|
||||
workflow = models.ForeignKey(Workflow, verbose_name=_(u"Workflow"), related_name="transitions")
|
||||
destination = models.ForeignKey(State, verbose_name=_(u"Destination"), null=True, blank=True, related_name="destination_state")
|
||||
condition = models.CharField(_(u"Condition"), blank=True, max_length=100)
|
||||
permission = models.ForeignKey(Permission, verbose_name=_(u"Permission"), blank=True, null=True)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
class StateObjectRelation(models.Model):
|
||||
"""Stores the workflow state of an object.
|
||||
|
||||
Provides a way to give any object a workflow state without changing the
|
||||
object's model.
|
||||
|
||||
**Attributes:**
|
||||
|
||||
content
|
||||
The object for which the state is stored. This can be any instance of
|
||||
a Django model.
|
||||
|
||||
state
|
||||
The state of content. This must be a State instance.
|
||||
"""
|
||||
content_type = models.ForeignKey(ContentType, verbose_name=_(u"Content type"), related_name="state_object", blank=True, null=True)
|
||||
content_id = models.PositiveIntegerField(_(u"Content id"), blank=True, null=True)
|
||||
content = generic.GenericForeignKey(ct_field="content_type", fk_field="content_id")
|
||||
state = models.ForeignKey(State, verbose_name = _(u"State"))
|
||||
|
||||
def __unicode__(self):
|
||||
return "%s %s - %s" % (self.content_type.name, self.content_id, self.state.name)
|
||||
|
||||
class Meta:
|
||||
unique_together = ("content_type", "content_id", "state")
|
||||
|
||||
class WorkflowObjectRelation(models.Model):
|
||||
"""Stores an workflow of an object.
|
||||
|
||||
Provides a way to give any object a workflow without changing the object's
|
||||
model.
|
||||
|
||||
**Attributes:**
|
||||
|
||||
content
|
||||
The object for which the workflow is stored. This can be any instance of
|
||||
a Django model.
|
||||
|
||||
workflow
|
||||
The workflow which is assigned to an object. This needs to be a workflow
|
||||
instance.
|
||||
"""
|
||||
content_type = models.ForeignKey(ContentType, verbose_name=_(u"Content type"), related_name="workflow_object", blank=True, null=True)
|
||||
content_id = models.PositiveIntegerField(_(u"Content id"), blank=True, null=True)
|
||||
content = generic.GenericForeignKey(ct_field="content_type", fk_field="content_id")
|
||||
workflow = models.ForeignKey(Workflow, verbose_name=_(u"Workflow"), related_name="wors")
|
||||
|
||||
class Meta:
|
||||
unique_together = ("content_type", "content_id")
|
||||
|
||||
def __unicode__(self):
|
||||
return "%s %s - %s" % (self.content_type.name, self.content_id, self.workflow.name)
|
||||
|
||||
class WorkflowModelRelation(models.Model):
|
||||
"""Stores an workflow for a model (ContentType).
|
||||
|
||||
Provides a way to give any object a workflow without changing the model.
|
||||
|
||||
**Attributes:**
|
||||
|
||||
Content Type
|
||||
The content type for which the workflow is stored. This can be any
|
||||
instance of a Django model.
|
||||
|
||||
workflow
|
||||
The workflow which is assigned to an object. This needs to be a
|
||||
workflow instance.
|
||||
"""
|
||||
content_type = models.ForeignKey(ContentType, verbose_name=_(u"Content Type"), unique=True)
|
||||
workflow = models.ForeignKey(Workflow, verbose_name=_(u"Workflow"), related_name="wmrs")
|
||||
|
||||
def __unicode__(self):
|
||||
return "%s - %s" % (self.content_type.name, self.workflow.name)
|
||||
|
||||
# Permissions relation #######################################################
|
||||
|
||||
class WorkflowPermissionRelation(models.Model):
|
||||
"""Stores the permissions for which a workflow is responsible.
|
||||
|
||||
**Attributes:**
|
||||
|
||||
workflow
|
||||
The workflow which is responsible for the permissions. Needs to be a
|
||||
Workflow instance.
|
||||
|
||||
permission
|
||||
The permission for which the workflow is responsible. Needs to be a
|
||||
Permission instance.
|
||||
"""
|
||||
workflow = models.ForeignKey(Workflow)
|
||||
permission = models.ForeignKey(Permission, related_name="permissions")
|
||||
|
||||
class Meta:
|
||||
unique_together = ("workflow", "permission")
|
||||
|
||||
def __unicode__(self):
|
||||
return "%s %s" % (self.workflow.name, self.permission.name)
|
||||
|
||||
class StateInheritanceBlock(models.Model):
|
||||
"""Stores inheritance block for state and permission.
|
||||
|
||||
**Attributes:**
|
||||
|
||||
state
|
||||
The state for which the inheritance is blocked. Needs to be a State
|
||||
instance.
|
||||
|
||||
permission
|
||||
The permission for which the instance is blocked. Needs to be a
|
||||
Permission instance.
|
||||
"""
|
||||
state = models.ForeignKey(State, verbose_name=_(u"State"))
|
||||
permission = models.ForeignKey(Permission, verbose_name=_(u"Permission"))
|
||||
|
||||
def __unicode__(self):
|
||||
return "%s %s" % (self.state.name, self.permission.name)
|
||||
|
||||
class StatePermissionRelation(models.Model):
|
||||
"""Stores granted permission for state and role.
|
||||
|
||||
**Attributes:**
|
||||
|
||||
state
|
||||
The state for which the role has the permission. Needs to be a State
|
||||
instance.
|
||||
|
||||
permission
|
||||
The permission for which the workflow is responsible. Needs to be a
|
||||
Permission instance.
|
||||
|
||||
role
|
||||
The role for which the state has the permission. Needs to be a lfc
|
||||
Role instance.
|
||||
"""
|
||||
state = models.ForeignKey(State, verbose_name=_(u"State"))
|
||||
permission = models.ForeignKey(Permission, verbose_name=_(u"Permission"))
|
||||
role = models.ForeignKey(Role, verbose_name=_(u"Role"))
|
||||
|
||||
def __unicode__(self):
|
||||
return "%s %s %s" % (self.state.name, self.role.name, self.permission.name)
|
10
workflows/templates/workflows/transitions.html
Normal file
10
workflows/templates/workflows/transitions.html
Normal file
|
@ -0,0 +1,10 @@
|
|||
{% load i18n %}
|
||||
<label>{{ state.name }}</label>
|
||||
<select name="transition">
|
||||
{% for transition in transitions %}
|
||||
<option {% if transition.selected %}selected="selected"{% endif %}
|
||||
value="{{ transition.id }}">
|
||||
{{ transition.name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
0
workflows/templatetags/__init__.py
Normal file
0
workflows/templatetags/__init__.py
Normal file
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue