virtualcommons-developer Mailing List for Virtual Commons Experiment Software (Page 4)
Status: Beta
Brought to you by:
alllee
You can subscribe to this list here.
| 2011 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(103) |
Jul
(85) |
Aug
(229) |
Sep
(70) |
Oct
(12) |
Nov
(16) |
Dec
(25) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2012 |
Jan
(41) |
Feb
(66) |
Mar
(150) |
Apr
(148) |
May
(109) |
Jun
(8) |
Jul
(20) |
Aug
(20) |
Sep
(16) |
Oct
(13) |
Nov
(58) |
Dec
(22) |
| 2013 |
Jan
(41) |
Feb
(108) |
Mar
(152) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: <com...@bi...> - 2013-03-19 06:55:17
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/7f44c1cbedbc/ changeset: 7f44c1cbedbc user: alllee date: 2013-03-19 07:55:03 summary: fixing invalid ref affected #: 1 file diff -r 896450e32163c30d9a376d56895260db05fd5afa -r 7f44c1cbedbc8a556647b7dbf3ebca272897ff92 vcweb/boundaries/views.py --- a/vcweb/boundaries/views.py +++ b/vcweb/boundaries/views.py @@ -100,7 +100,7 @@ experiment_model_dict['participantNumber'] = participant_group_relationship.participant_number experiment_model_dict['participantGroupId'] = participant_group_relationship.pk experiment_model_dict['dollarsPerToken'] = ec.exchange_rate - experiment_model_dict['chatEnabled'] = round_configuration.chat_enabled + experiment_model_dict['chatEnabled'] = current_round.chat_enabled # FIXME: defaults hard coded in for now experiment_model_dict['maxEarnings'] = 20.00 experiment_model_dict['warningCountdownTime'] = 10 Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
|
From: <com...@bi...> - 2013-03-19 06:43:08
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/896450e32163/ changeset: 896450e32163 user: alllee date: 2013-03-19 07:42:55 summary: fixing Choices generator expression that was causing a ruckus in the django model admin affected #: 1 file diff -r 738047ee9601f80eb44f2d84f14a9a43da1c9b57 -r 896450e32163c30d9a376d56895260db05fd5afa vcweb/core/models.py --- a/vcweb/core/models.py +++ b/vcweb/core/models.py @@ -761,9 +761,6 @@ logger.debug("already created round data: %s", round_data) return round_data - def create_new_groups(self): - pass - def start_round(self, sender=None): logger.debug("%s STARTING ROUND (sender: %s)", self, sender) self.status = Experiment.Status.ROUND_IN_PROGRESS @@ -773,9 +770,9 @@ self.ready_participants = 0 self.save() self.log('Starting round') + current_round_configuration = self.current_round if current_round_configuration.randomize_groups: - self.allocate_groups( - preserve_existing_groups=current_round_configuration.preserve_existing_groups, + self.allocate_groups(preserve_existing_groups=current_round_configuration.preserve_existing_groups, session_id=current_round_configuration.session_id) if sender is None: sender = intern(self.experiment_metadata.namespace.encode('utf8')) @@ -896,7 +893,7 @@ QUIZ=('Quiz round', 'quiz.html')) ROUND_TYPES = (CHAT, DEBRIEFING, INSTRUCTIONS, PRACTICE, QUIZ, REGULAR, WELCOME) = sorted(ROUND_TYPES_DICT.keys()) - ROUND_TYPE_CHOICES = Choices((round_type, ROUND_TYPES_DICT[round_type][0]) for round_type in ROUND_TYPES) + ROUND_TYPE_CHOICES = Choices(*[(round_type, ROUND_TYPES_DICT[round_type][0]) for round_type in ROUND_TYPES]) PLAYABLE_ROUND_CONFIGURATIONS = (PRACTICE, REGULAR) experiment_configuration = models.ForeignKey(ExperimentConfiguration, related_name='round_configuration_set') @@ -930,10 +927,8 @@ survey_url = models.URLField(null=True, blank=True) """ external survey url """ chat_enabled = models.BooleanField(default=False, help_text=_("Is chat enabled in this round?")) - create_group_clusters = models.BooleanField(default=False, help_text=_('''Create relationships (clusters) of groups - that can share group cluster data values''')) - group_cluster_size = models.PositiveIntegerField(default=2, help_text=_('''How many groups should be clustered - together at a time?''')) + create_group_clusters = models.BooleanField(default=False, help_text=_("Create relationships (clusters) of groups that can share group cluster data values")) + group_cluster_size = models.PositiveIntegerField(default=2, help_text=_("How many groups should be clustered together at a time?")) randomize_groups = models.BooleanField(default=False, help_text=_("Shuffle participants into new groups when the round begins?")) """ Should groups be randomized at the start of the round? """ preserve_existing_groups = models.BooleanField(default=True, help_text=_("This option is only useful if randomize_groups is set to true. If we are randomizing groups, should existing groups (if any) be preserved?")) @@ -1840,7 +1835,7 @@ if round_data is None: round_data = experiment.current_round_data for participant_group_relationship in ParticipantGroupRelationship.objects.for_experiment(experiment): - yield ChatMessage.objects.create(participant_group_relationship=participant_group_relationship, + ChatMessage.objects.create(participant_group_relationship=participant_group_relationship, string_value=message, round_data=round_data) Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
|
From: <com...@bi...> - 2013-03-19 06:14:27
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/738047ee9601/ changeset: 738047ee9601 user: alllee date: 2013-03-19 07:14:11 summary: adding group cluster parameters to RoundConfiguration affected #: 2 files diff -r b42f6ed11bfc1a1aaf00a696c18f01ca57216dbe -r 738047ee9601f80eb44f2d84f14a9a43da1c9b57 vcweb/core/migrations/0027_auto__add_field_roundconfiguration_create_group_clusters__add_field_ro.py --- /dev/null +++ b/vcweb/core/migrations/0027_auto__add_field_roundconfiguration_create_group_clusters__add_field_ro.py @@ -0,0 +1,410 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding field 'RoundConfiguration.create_group_clusters' + db.add_column(u'core_roundconfiguration', 'create_group_clusters', + self.gf('django.db.models.fields.BooleanField')(default=False), + keep_default=False) + + # Adding field 'RoundConfiguration.group_cluster_size' + db.add_column(u'core_roundconfiguration', 'group_cluster_size', + self.gf('django.db.models.fields.PositiveIntegerField')(default=2), + keep_default=False) + + + def backwards(self, orm): + # Deleting field 'RoundConfiguration.create_group_clusters' + db.delete_column(u'core_roundconfiguration', 'create_group_clusters') + + # Deleting field 'RoundConfiguration.group_cluster_size' + db.delete_column(u'core_roundconfiguration', 'group_cluster_size') + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'auth.user': { + 'Meta': {'object_name': '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': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + '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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'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'}) + }, + u'core.activitylog': { + 'Meta': {'object_name': 'ActivityLog'}, + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'log_message': ('django.db.models.fields.TextField', [], {}) + }, + u'core.address': { + 'Meta': {'object_name': 'Address'}, + 'city': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'state': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), + 'street1': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'street2': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'zipcode': ('django.db.models.fields.CharField', [], {'max_length': '8', 'blank': 'True'}) + }, + u'core.chatmessage': { + 'Meta': {'ordering': "['date_created']", 'object_name': 'ChatMessage', '_ormbases': [u'core.ParticipantRoundDataValue']}, + u'participantrounddatavalue_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ParticipantRoundDataValue']", 'unique': 'True', 'primary_key': 'True'}), + 'target_participant': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'target_participant_chat_message_set'", 'null': 'True', 'to': u"orm['core.ParticipantGroupRelationship']"}) + }, + u'core.comment': { + 'Meta': {'ordering': "['date_created']", 'object_name': 'Comment', '_ormbases': [u'core.ParticipantRoundDataValue']}, + u'participantrounddatavalue_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ParticipantRoundDataValue']", 'unique': 'True', 'primary_key': 'True'}) + }, + u'core.experiment': { + 'Meta': {'ordering': "['date_created', 'status']", 'object_name': 'Experiment'}, + 'amqp_exchange_name': ('django.db.models.fields.CharField', [], {'default': "'vcweb.default.exchange'", 'max_length': '64'}), + 'authentication_code': ('django.db.models.fields.CharField', [], {'default': "'vcweb.auth.code'", 'max_length': '32'}), + 'current_repeated_round_sequence_number': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'current_round_elapsed_time': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'current_round_sequence_number': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}), + 'current_round_start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'duration': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), + 'experiment_configuration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentConfiguration']"}), + 'experiment_metadata': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentMetadata']"}), + 'experimenter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Experimenter']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'ready_participants': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'start_date_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'INACTIVE'", 'max_length': '32'}), + 'tick_duration': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), + 'total_elapsed_time': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}) + }, + u'core.experimentactivitylog': { + 'Meta': {'object_name': 'ExperimentActivityLog', '_ormbases': [u'core.ActivityLog']}, + u'activitylog_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ActivityLog']", 'unique': 'True', 'primary_key': 'True'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'activity_log_set'", 'to': u"orm['core.Experiment']"}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.experimentconfiguration': { + 'Meta': {'ordering': "['experiment_metadata', 'creator', 'date_created']", 'object_name': 'ExperimentConfiguration'}, + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_configuration_set'", 'to': u"orm['core.Experimenter']"}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'exchange_rate': ('django.db.models.fields.DecimalField', [], {'default': '0.2', 'null': 'True', 'max_digits': '6', 'decimal_places': '2', 'blank': 'True'}), + 'experiment_metadata': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_configuration_set'", 'to': u"orm['core.ExperimentMetadata']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invitation_subject': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'invitation_text': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'is_experimenter_driven': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'max_group_size': ('django.db.models.fields.PositiveIntegerField', [], {'default': '5'}), + 'max_number_of_participants': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'treatment_id': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}) + }, + u'core.experimenter': { + 'Meta': {'ordering': "['user']", 'object_name': 'Experimenter'}, + 'approved': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'authentication_token': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'failed_password_attempts': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'institution': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Institution']", 'null': 'True', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'experimenter'", 'unique': 'True', 'to': u"orm['auth.User']"}) + }, + u'core.experimenterrequest': { + 'Meta': {'object_name': 'ExperimenterRequest'}, + 'approved': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['auth.User']", 'unique': 'True'}) + }, + u'core.experimentmetadata': { + 'Meta': {'ordering': "['namespace', 'date_created']", 'object_name': 'ExperimentMetadata'}, + 'about_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'default_configuration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentConfiguration']", 'null': 'True', 'blank': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'logo_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'namespace': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'short_name': ('django.db.models.fields.SlugField', [], {'max_length': '32', 'unique': 'True', 'null': 'True', 'blank': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + u'core.experimentparametervalue': { + 'Meta': {'object_name': 'ExperimentParameterValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'experiment_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_parameter_value_set'", 'to': u"orm['core.ExperimentConfiguration']"}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + u'core.experimentsession': { + 'Meta': {'object_name': 'ExperimentSession'}, + 'capacity': ('django.db.models.fields.PositiveIntegerField', [], {'default': '20'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_session_set'", 'to': u"orm['auth.User']"}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'experiment_metadata': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_session_set'", 'to': u"orm['core.ExperimentMetadata']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invitation_text': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'scheduled_date': ('django.db.models.fields.DateTimeField', [], {}), + 'scheduled_end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}) + }, + u'core.group': { + 'Meta': {'ordering': "['experiment', 'number']", 'object_name': 'Group'}, + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Experiment']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'max_size': ('django.db.models.fields.PositiveIntegerField', [], {'default': '5'}), + 'number': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'session_id': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}) + }, + u'core.groupactivitylog': { + 'Meta': {'object_name': 'GroupActivityLog', '_ormbases': [u'core.ActivityLog']}, + u'activitylog_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ActivityLog']", 'unique': 'True', 'primary_key': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'activity_log_set'", 'to': u"orm['core.Group']"}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.groupcluster': { + 'Meta': {'ordering': "['date_created']", 'object_name': 'GroupCluster'}, + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Experiment']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'session_id': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}) + }, + u'core.groupclusterdatavalue': { + 'Meta': {'object_name': 'GroupClusterDataValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + 'group_cluster': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.GroupCluster']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'round_data': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'group_cluster_data_value_set'", 'to': u"orm['core.RoundData']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + u'core.grouprelationship': { + 'Meta': {'ordering': "['date_created']", 'object_name': 'GroupRelationship'}, + 'cluster': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'group_set'", 'to': u"orm['core.GroupCluster']"}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + u'core.grouprounddatavalue': { + 'Meta': {'ordering': "['round_data', 'group', 'parameter']", 'object_name': 'GroupRoundDataValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'data_value_set'", 'to': u"orm['core.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'round_data': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'group_data_value_set'", 'to': u"orm['core.RoundData']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + u'core.institution': { + 'Meta': {'object_name': 'Institution'}, + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}) + }, + u'core.invitation': { + 'Meta': {'object_name': 'Invitation'}, + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'experiment_session': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentSession']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'participant': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Participant']"}), + 'sender': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}) + }, + u'core.like': { + 'Meta': {'ordering': "['-date_created', 'round_data', 'participant_group_relationship', 'parameter']", 'object_name': 'Like', '_ormbases': [u'core.ParticipantRoundDataValue']}, + u'participantrounddatavalue_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ParticipantRoundDataValue']", 'unique': 'True', 'primary_key': 'True'}) + }, + u'core.parameter': { + 'Meta': {'ordering': "['name']", 'unique_together': "(('name', 'experiment_metadata', 'scope'),)", 'object_name': 'Parameter'}, + 'class_name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Experimenter']"}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'default_value_string': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'description': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'}), + 'display_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'enum_choices': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'experiment_metadata': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentMetadata']", 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_required': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'scope': ('django.db.models.fields.CharField', [], {'default': "'round'", 'max_length': '32'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '32'}) + }, + u'core.participant': { + 'Meta': {'ordering': "['user']", 'object_name': 'Participant'}, + 'address': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Address']", 'null': 'True', 'blank': 'True'}), + 'authentication_token': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'birthdate': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'can_receive_invitations': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'experiments': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'participant_set'", 'symmetrical': 'False', 'through': u"orm['core.ParticipantExperimentRelationship']", 'to': u"orm['core.Experiment']"}), + 'failed_password_attempts': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'gender': ('django.db.models.fields.CharField', [], {'max_length': '1', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'participant_set'", 'symmetrical': 'False', 'through': u"orm['core.ParticipantGroupRelationship']", 'to': u"orm['core.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'institution': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Institution']", 'null': 'True', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'participant'", 'unique': 'True', 'to': u"orm['auth.User']"}) + }, + u'core.participantexperimentrelationship': { + 'Meta': {'object_name': 'ParticipantExperimentRelationship'}, + 'additional_data': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}), + 'current_location': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'participant_relationship_set'", 'to': u"orm['core.Experiment']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_completed_round_sequence_number': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'participant': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_relationship_set'", 'to': u"orm['core.Participant']"}), + 'participant_identifier': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'sequential_participant_identifier': ('django.db.models.fields.PositiveIntegerField', [], {}) + }, + u'core.participantgrouprelationship': { + 'Meta': {'ordering': "['group', 'participant_number']", 'object_name': 'ParticipantGroupRelationship'}, + 'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'first_visit': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'participant_group_relationship_set'", 'to': u"orm['core.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'notifications_since': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'null': 'True', 'blank': 'True'}), + 'participant': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'participant_group_relationship_set'", 'to': u"orm['core.Participant']"}), + 'participant_number': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'round_joined': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.participantrounddatavalue': { + 'Meta': {'ordering': "['-date_created', 'round_data', 'participant_group_relationship', 'parameter']", 'object_name': 'ParticipantRoundDataValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'participant_group_relationship': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'participant_data_value_set'", 'to': u"orm['core.ParticipantGroupRelationship']"}), + 'round_data': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'participant_data_value_set'", 'to': u"orm['core.RoundData']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'submitted': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'target_data_value': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'target_data_value_set'", 'null': 'True', 'to': u"orm['core.ParticipantRoundDataValue']"}) + }, + u'core.participantsignup': { + 'Meta': {'object_name': 'ParticipantSignup'}, + 'attendance': ('django.db.models.fields.PositiveIntegerField', [], {'max_length': '1', 'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invitation': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'signup_set'", 'to': u"orm['core.Invitation']"}), + 'participant': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'signup_set'", 'to': u"orm['core.Participant']"}) + }, + u'core.quizquestion': { + 'Meta': {'object_name': 'QuizQuestion'}, + 'answer': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'default_quiz_question_set'", 'null': 'True', 'to': u"orm['core.Experiment']"}), + 'explanation': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'input_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'label': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'quiz_question_set'", 'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.roundconfiguration': { + 'Meta': {'ordering': "['experiment_configuration', 'sequence_number', 'date_created']", 'object_name': 'RoundConfiguration'}, + 'chat_enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'create_group_clusters': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'debriefing': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'display_number': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'duration': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'experiment_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'round_configuration_set'", 'to': u"orm['core.ExperimentConfiguration']"}), + 'group_cluster_size': ('django.db.models.fields.PositiveIntegerField', [], {'default': '2'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'instructions': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'preserve_existing_groups': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'randomize_groups': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'repeat': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'round_type': ('django.db.models.fields.CharField', [], {'default': "'REGULAR'", 'max_length': '32'}), + 'sequence_number': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'session_id': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'survey_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'template_name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}) + }, + u'core.rounddata': { + 'Meta': {'ordering': "['round_configuration']", 'unique_together': "(('round_configuration', 'experiment'),)", 'object_name': 'RoundData'}, + 'elapsed_time': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'round_data_set'", 'to': u"orm['core.Experiment']"}), + 'experimenter_notes': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'round_data_set'", 'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.roundparametervalue': { + 'Meta': {'object_name': 'RoundParameterValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'round_parameter_value_set'", 'to': u"orm['core.RoundConfiguration']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + u'core.spoolparticipantstatistics': { + 'Meta': {'object_name': 'SpoolParticipantStatistics'}, + 'absences': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'discharges': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invitations': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'participant': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'spool_statistics_set'", 'to': u"orm['core.Participant']"}), + 'participations': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}) + } + } + + complete_apps = ['core'] \ No newline at end of file diff -r b42f6ed11bfc1a1aaf00a696c18f01ca57216dbe -r 738047ee9601f80eb44f2d84f14a9a43da1c9b57 vcweb/core/models.py --- a/vcweb/core/models.py +++ b/vcweb/core/models.py @@ -930,6 +930,10 @@ survey_url = models.URLField(null=True, blank=True) """ external survey url """ chat_enabled = models.BooleanField(default=False, help_text=_("Is chat enabled in this round?")) + create_group_clusters = models.BooleanField(default=False, help_text=_('''Create relationships (clusters) of groups + that can share group cluster data values''')) + group_cluster_size = models.PositiveIntegerField(default=2, help_text=_('''How many groups should be clustered + together at a time?''')) randomize_groups = models.BooleanField(default=False, help_text=_("Shuffle participants into new groups when the round begins?")) """ Should groups be randomized at the start of the round? """ preserve_existing_groups = models.BooleanField(default=True, help_text=_("This option is only useful if randomize_groups is set to true. If we are randomizing groups, should existing groups (if any) be preserved?")) Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
|
From: <com...@bi...> - 2013-03-19 05:07:00
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/b42f6ed11bfc/ changeset: b42f6ed11bfc user: alllee date: 2013-03-19 06:06:31 summary: adding preserve_existing_groups group creation logic to allocate_groups that creates groups with a session id when it is set. affected #: 1 file diff -r 7c15b41b4b6f3a8b4292d37bba3757625a83a865 -r b42f6ed11bfc1a1aaf00a696c18f01ca57216dbe vcweb/core/models.py --- a/vcweb/core/models.py +++ b/vcweb/core/models.py @@ -689,24 +689,33 @@ current_group = self.group_set.reverse()[0] return current_group.add_participant(participant) - def allocate_groups(self, randomize=True): + def allocate_groups(self, randomize=True, preserve_existing_groups=False, session_id=None): logger.debug("allocating groups for %s (randomize? %s)" % (self, randomize)) # clear out all existing groups # FIXME: record previous mappings in activity log. gs = self.group_set - if gs.count() > 0: - self.log("reallocating groups, deleting old groups") - gqs = gs.all() - for g in gqs: - self.log("reallocating group %s" % g.participant_group_relationship_set.all()) - gqs.delete() - # seed the initial group. max_group_size = self.experiment_configuration.max_group_size - logger.debug("creating group with max size %d", max_group_size) - current_group = self.group_set.create(number=1, max_size=max_group_size) participants = list(self.participant_set.all()) if randomize: random.shuffle(participants) + if gs.count() > 0: + if preserve_existing_groups: + # verify incoming session id is an actual value + if session_id is None: + round_configuration = self.current_round + session_id = round_configuration.session_id + if session_id is None: + logger.error("Trying to create a new set of groups but no session id has been set on %s. Aborting.", round_configuration) + raise ValueError("Cannot allocate new groups and preserve existing groups without an appropriate session id set on this round configuration %s" % round_configuration) + else: + self.log("reallocating groups, deleting old groups") + gqs = gs.all() + for g in gqs: + self.log("reallocating/deleting group %s" % g.participant_group_relationship_set.all()) + gqs.delete() + # seed the initial group. + current_group = self.group_set.create(number=self.group_set.count(), max_size=max_group_size, session_id=session_id) + logger.debug("created initial group %s", current_group) for p in participants: pgr = self.add_participant(p, current_group) current_group = pgr.group @@ -752,6 +761,9 @@ logger.debug("already created round data: %s", round_data) return round_data + def create_new_groups(self): + pass + def start_round(self, sender=None): logger.debug("%s STARTING ROUND (sender: %s)", self, sender) self.status = Experiment.Status.ROUND_IN_PROGRESS @@ -761,13 +773,10 @@ self.ready_participants = 0 self.save() self.log('Starting round') - current_round_configuration = self.current_round if current_round_configuration.randomize_groups: - # check if we need to preserve existing groups - if round_configuration.preserve_existing_groups: - create_new_groups() - else: - allocate_groups() + self.allocate_groups( + preserve_existing_groups=current_round_configuration.preserve_existing_groups, + session_id=current_round_configuration.session_id) if sender is None: sender = intern(self.experiment_metadata.namespace.encode('utf8')) # notify registered game handlers @@ -1081,7 +1090,7 @@ ('string', 'String value'), ('foreignkey', 'Foreign key'), ('float', 'Floating-point number'), - ('boolean', 'True/False'), + ('boolean', 'Boolean value (true/false)'), ('enum', 'Enumeration')) # FIXME: arcane, see if we can encapsulate this better. used to provide sane default values for each parameter type @@ -1466,7 +1475,8 @@ return ParticipantRoundDataValue.objects.filter(**criteria) def create_next_group(self): - return Group.objects.create(number=self.number + 1, max_size=self.max_size, experiment=self.experiment) + return Group.objects.create(number=self.number + 1, max_size=self.max_size, experiment=self.experiment, + session_id=self.session_id) """ Adds the given participant to this group or a new group if this group is is_full. Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
|
From: <com...@bi...> - 2013-03-19 04:26:25
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/7c15b41b4b6f/ changeset: 7c15b41b4b6f user: alllee date: 2013-03-19 05:26:10 summary: adding a repeat field to RoundConfiguration and a tracking repeating round sequence number on Experiment to reduce the number of RoundConfiguration objects needed to setup an Experiment, still need to wire them up into advance_to_next_round etc. affected #: 3 files diff -r 658e0da29ff738092655dd2384d3136d769bcb0b -r 7c15b41b4b6f3a8b4292d37bba3757625a83a865 vcweb/boundaries/models.py --- a/vcweb/boundaries/models.py +++ b/vcweb/boundaries/models.py @@ -45,14 +45,14 @@ @simplecache def get_observe_other_group_parameter(): - return Parameter.objects.for_experiment(name='observe_other_group') + return Parameter.objects.for_round(name='observe_other_group') @simplecache def get_shared_resource_parameter(): - return Parameter.objects.for_experiment(name='shared_resource') + return Parameter.objects.for_round(name='shared_resource') -def can_observe_other_group(experiment_configuration): - return experiment_configuration.get_parameter_value(parameter=get_observe_other_group_parameter(), default=False).boolean_value +def can_observe_other_group(round_configuration): + return round_configuration.get_parameter_value(parameter=get_observe_other_group_parameter(), default=False).boolean_value # players can either be dead or alive def get_player_status_dv(participant_group_relationship_id): diff -r 658e0da29ff738092655dd2384d3136d769bcb0b -r 7c15b41b4b6f3a8b4292d37bba3757625a83a865 vcweb/core/migrations/0026_auto__add_field_roundconfiguration_repeat__add_field_experiment_curren.py --- /dev/null +++ b/vcweb/core/migrations/0026_auto__add_field_roundconfiguration_repeat__add_field_experiment_curren.py @@ -0,0 +1,408 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding field 'RoundConfiguration.repeat' + db.add_column(u'core_roundconfiguration', 'repeat', + self.gf('django.db.models.fields.PositiveIntegerField')(default=0), + keep_default=False) + + # Adding field 'Experiment.current_repeated_round_sequence_number' + db.add_column(u'core_experiment', 'current_repeated_round_sequence_number', + self.gf('django.db.models.fields.PositiveIntegerField')(default=0), + keep_default=False) + + + def backwards(self, orm): + # Deleting field 'RoundConfiguration.repeat' + db.delete_column(u'core_roundconfiguration', 'repeat') + + # Deleting field 'Experiment.current_repeated_round_sequence_number' + db.delete_column(u'core_experiment', 'current_repeated_round_sequence_number') + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'auth.user': { + 'Meta': {'object_name': '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': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + '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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'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'}) + }, + u'core.activitylog': { + 'Meta': {'object_name': 'ActivityLog'}, + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'log_message': ('django.db.models.fields.TextField', [], {}) + }, + u'core.address': { + 'Meta': {'object_name': 'Address'}, + 'city': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'state': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), + 'street1': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'street2': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'zipcode': ('django.db.models.fields.CharField', [], {'max_length': '8', 'blank': 'True'}) + }, + u'core.chatmessage': { + 'Meta': {'ordering': "['date_created']", 'object_name': 'ChatMessage', '_ormbases': [u'core.ParticipantRoundDataValue']}, + u'participantrounddatavalue_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ParticipantRoundDataValue']", 'unique': 'True', 'primary_key': 'True'}), + 'target_participant': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'target_participant_chat_message_set'", 'null': 'True', 'to': u"orm['core.ParticipantGroupRelationship']"}) + }, + u'core.comment': { + 'Meta': {'ordering': "['date_created']", 'object_name': 'Comment', '_ormbases': [u'core.ParticipantRoundDataValue']}, + u'participantrounddatavalue_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ParticipantRoundDataValue']", 'unique': 'True', 'primary_key': 'True'}) + }, + u'core.experiment': { + 'Meta': {'ordering': "['date_created', 'status']", 'object_name': 'Experiment'}, + 'amqp_exchange_name': ('django.db.models.fields.CharField', [], {'default': "'vcweb.default.exchange'", 'max_length': '64'}), + 'authentication_code': ('django.db.models.fields.CharField', [], {'default': "'vcweb.auth.code'", 'max_length': '32'}), + 'current_repeated_round_sequence_number': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'current_round_elapsed_time': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'current_round_sequence_number': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}), + 'current_round_start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'duration': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), + 'experiment_configuration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentConfiguration']"}), + 'experiment_metadata': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentMetadata']"}), + 'experimenter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Experimenter']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'ready_participants': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'start_date_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'INACTIVE'", 'max_length': '32'}), + 'tick_duration': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), + 'total_elapsed_time': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}) + }, + u'core.experimentactivitylog': { + 'Meta': {'object_name': 'ExperimentActivityLog', '_ormbases': [u'core.ActivityLog']}, + u'activitylog_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ActivityLog']", 'unique': 'True', 'primary_key': 'True'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'activity_log_set'", 'to': u"orm['core.Experiment']"}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.experimentconfiguration': { + 'Meta': {'ordering': "['experiment_metadata', 'creator', 'date_created']", 'object_name': 'ExperimentConfiguration'}, + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_configuration_set'", 'to': u"orm['core.Experimenter']"}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'exchange_rate': ('django.db.models.fields.DecimalField', [], {'default': '0.2', 'null': 'True', 'max_digits': '6', 'decimal_places': '2', 'blank': 'True'}), + 'experiment_metadata': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_configuration_set'", 'to': u"orm['core.ExperimentMetadata']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invitation_subject': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'invitation_text': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'is_experimenter_driven': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'max_group_size': ('django.db.models.fields.PositiveIntegerField', [], {'default': '5'}), + 'max_number_of_participants': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'treatment_id': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}) + }, + u'core.experimenter': { + 'Meta': {'ordering': "['user']", 'object_name': 'Experimenter'}, + 'approved': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'authentication_token': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'failed_password_attempts': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'institution': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Institution']", 'null': 'True', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'experimenter'", 'unique': 'True', 'to': u"orm['auth.User']"}) + }, + u'core.experimenterrequest': { + 'Meta': {'object_name': 'ExperimenterRequest'}, + 'approved': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['auth.User']", 'unique': 'True'}) + }, + u'core.experimentmetadata': { + 'Meta': {'ordering': "['namespace', 'date_created']", 'object_name': 'ExperimentMetadata'}, + 'about_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'default_configuration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentConfiguration']", 'null': 'True', 'blank': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'logo_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'namespace': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'short_name': ('django.db.models.fields.SlugField', [], {'max_length': '32', 'unique': 'True', 'null': 'True', 'blank': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + u'core.experimentparametervalue': { + 'Meta': {'object_name': 'ExperimentParameterValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'experiment_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_parameter_value_set'", 'to': u"orm['core.ExperimentConfiguration']"}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + u'core.experimentsession': { + 'Meta': {'object_name': 'ExperimentSession'}, + 'capacity': ('django.db.models.fields.PositiveIntegerField', [], {'default': '20'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_session_set'", 'to': u"orm['auth.User']"}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'experiment_metadata': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_session_set'", 'to': u"orm['core.ExperimentMetadata']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invitation_text': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'scheduled_date': ('django.db.models.fields.DateTimeField', [], {}), + 'scheduled_end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}) + }, + u'core.group': { + 'Meta': {'ordering': "['experiment', 'number']", 'object_name': 'Group'}, + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Experiment']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'max_size': ('django.db.models.fields.PositiveIntegerField', [], {'default': '5'}), + 'number': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'session_id': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}) + }, + u'core.groupactivitylog': { + 'Meta': {'object_name': 'GroupActivityLog', '_ormbases': [u'core.ActivityLog']}, + u'activitylog_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ActivityLog']", 'unique': 'True', 'primary_key': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'activity_log_set'", 'to': u"orm['core.Group']"}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.groupcluster': { + 'Meta': {'ordering': "['date_created']", 'object_name': 'GroupCluster'}, + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Experiment']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'session_id': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}) + }, + u'core.groupclusterdatavalue': { + 'Meta': {'object_name': 'GroupClusterDataValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + 'group_cluster': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.GroupCluster']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'round_data': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'group_cluster_data_value_set'", 'to': u"orm['core.RoundData']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + u'core.grouprelationship': { + 'Meta': {'ordering': "['date_created']", 'object_name': 'GroupRelationship'}, + 'cluster': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'group_set'", 'to': u"orm['core.GroupCluster']"}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + u'core.grouprounddatavalue': { + 'Meta': {'ordering': "['round_data', 'group', 'parameter']", 'object_name': 'GroupRoundDataValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'data_value_set'", 'to': u"orm['core.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'round_data': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'group_data_value_set'", 'to': u"orm['core.RoundData']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + u'core.institution': { + 'Meta': {'object_name': 'Institution'}, + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}) + }, + u'core.invitation': { + 'Meta': {'object_name': 'Invitation'}, + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'experiment_session': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentSession']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'participant': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Participant']"}), + 'sender': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}) + }, + u'core.like': { + 'Meta': {'ordering': "['-date_created', 'round_data', 'participant_group_relationship', 'parameter']", 'object_name': 'Like', '_ormbases': [u'core.ParticipantRoundDataValue']}, + u'participantrounddatavalue_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ParticipantRoundDataValue']", 'unique': 'True', 'primary_key': 'True'}) + }, + u'core.parameter': { + 'Meta': {'ordering': "['name']", 'unique_together': "(('name', 'experiment_metadata', 'scope'),)", 'object_name': 'Parameter'}, + 'class_name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Experimenter']"}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'default_value_string': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'description': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'}), + 'display_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'enum_choices': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'experiment_metadata': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentMetadata']", 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_required': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'scope': ('django.db.models.fields.CharField', [], {'default': "'round'", 'max_length': '32'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '32'}) + }, + u'core.participant': { + 'Meta': {'ordering': "['user']", 'object_name': 'Participant'}, + 'address': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Address']", 'null': 'True', 'blank': 'True'}), + 'authentication_token': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'birthdate': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'can_receive_invitations': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'experiments': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'participant_set'", 'symmetrical': 'False', 'through': u"orm['core.ParticipantExperimentRelationship']", 'to': u"orm['core.Experiment']"}), + 'failed_password_attempts': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'gender': ('django.db.models.fields.CharField', [], {'max_length': '1', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'participant_set'", 'symmetrical': 'False', 'through': u"orm['core.ParticipantGroupRelationship']", 'to': u"orm['core.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'institution': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Institution']", 'null': 'True', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'participant'", 'unique': 'True', 'to': u"orm['auth.User']"}) + }, + u'core.participantexperimentrelationship': { + 'Meta': {'object_name': 'ParticipantExperimentRelationship'}, + 'additional_data': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}), + 'current_location': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'participant_relationship_set'", 'to': u"orm['core.Experiment']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_completed_round_sequence_number': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'participant': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_relationship_set'", 'to': u"orm['core.Participant']"}), + 'participant_identifier': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'sequential_participant_identifier': ('django.db.models.fields.PositiveIntegerField', [], {}) + }, + u'core.participantgrouprelationship': { + 'Meta': {'ordering': "['group', 'participant_number']", 'object_name': 'ParticipantGroupRelationship'}, + 'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'first_visit': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'participant_group_relationship_set'", 'to': u"orm['core.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'notifications_since': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'null': 'True', 'blank': 'True'}), + 'participant': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'participant_group_relationship_set'", 'to': u"orm['core.Participant']"}), + 'participant_number': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'round_joined': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.participantrounddatavalue': { + 'Meta': {'ordering': "['-date_created', 'round_data', 'participant_group_relationship', 'parameter']", 'object_name': 'ParticipantRoundDataValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'participant_group_relationship': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'participant_data_value_set'", 'to': u"orm['core.ParticipantGroupRelationship']"}), + 'round_data': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'participant_data_value_set'", 'to': u"orm['core.RoundData']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'submitted': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'target_data_value': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'target_data_value_set'", 'null': 'True', 'to': u"orm['core.ParticipantRoundDataValue']"}) + }, + u'core.participantsignup': { + 'Meta': {'object_name': 'ParticipantSignup'}, + 'attendance': ('django.db.models.fields.PositiveIntegerField', [], {'max_length': '1', 'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invitation': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'signup_set'", 'to': u"orm['core.Invitation']"}), + 'participant': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'signup_set'", 'to': u"orm['core.Participant']"}) + }, + u'core.quizquestion': { + 'Meta': {'object_name': 'QuizQuestion'}, + 'answer': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'default_quiz_question_set'", 'null': 'True', 'to': u"orm['core.Experiment']"}), + 'explanation': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'input_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'label': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'quiz_question_set'", 'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.roundconfiguration': { + 'Meta': {'ordering': "['experiment_configuration', 'sequence_number', 'date_created']", 'object_name': 'RoundConfiguration'}, + 'chat_enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'debriefing': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'display_number': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'duration': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'experiment_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'round_configuration_set'", 'to': u"orm['core.ExperimentConfiguration']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'instructions': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'preserve_existing_groups': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'randomize_groups': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'repeat': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'round_type': ('django.db.models.fields.CharField', [], {'default': "'REGULAR'", 'max_length': '32'}), + 'sequence_number': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'session_id': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'survey_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'template_name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}) + }, + u'core.rounddata': { + 'Meta': {'ordering': "['round_configuration']", 'unique_together': "(('round_configuration', 'experiment'),)", 'object_name': 'RoundData'}, + 'elapsed_time': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'round_data_set'", 'to': u"orm['core.Experiment']"}), + 'experimenter_notes': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'round_data_set'", 'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.roundparametervalue': { + 'Meta': {'object_name': 'RoundParameterValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'round_parameter_value_set'", 'to': u"orm['core.RoundConfiguration']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + u'core.spoolparticipantstatistics': { + 'Meta': {'object_name': 'SpoolParticipantStatistics'}, + 'absences': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'discharges': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invitations': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'participant': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'spool_statistics_set'", 'to': u"orm['core.Participant']"}), + 'participations': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}) + } + } + + complete_apps = ['core'] \ No newline at end of file diff -r 658e0da29ff738092655dd2384d3136d769bcb0b -r 7c15b41b4b6f3a8b4292d37bba3757625a83a865 vcweb/core/models.py --- a/vcweb/core/models.py +++ b/vcweb/core/models.py @@ -277,9 +277,12 @@ currently unused, but kept here in the event that we want to allow participants to authenticate with this authentication_code either in lieu or in addition to their own user password. """ - current_round_sequence_number = models.PositiveIntegerField(default=1) + current_round_sequence_number = models.PositiveIntegerField(default=1, help_text=_('''Used to identify which round the + experiment is currently running, should be a sequential number ranging from 1 to N''')) """ Each round is assigned a sequential sequence number, ranging from 1 to N. Used to identify which round the experiment is currently running. """ + current_repeated_round_sequence_number = models.PositiveIntegerField(default=0, help_text=_('''For repeating rounds, + the number of times the round has been repeated, used to keep track of when to move on from a repeating round.''')) experimenter = models.ForeignKey(Experimenter) """ the user running this experiment """ experiment_metadata = models.ForeignKey(ExperimentMetadata) @@ -930,6 +933,7 @@ Group/ParticipantGroupRelationship models that can live in conjunction with the existing Group/ParticipantGroupRelationship models. ''')) + repeat = models.PositiveIntegerField(default=0, help_text=_('If set to a positive integer n, this round will repeat itself n times with the same configuration and parameter values.')) @property def custom_template_name(self): Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
|
From: <com...@bi...> - 2013-03-19 04:14:40
|
2 new commits in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/b57b81a30fd8/ changeset: b57b81a30fd8 user: alllee date: 2013-03-19 05:12:16 summary: fixing ref errors, setting observe_other_group as an ExperimentConfiguration parameter that applies to the entire experiment as opposed to a per-round configuration parameter as it is treatment-specific: treatment A, C = observe other group treatment B, D = cannot observe other group affected #: 4 files diff -r 803f0f093db84c87d3605dd6c59e5ec2e895b8a9 -r b57b81a30fd882c0566c6fbd2472c8b8f4622525 vcweb/boundaries/models.py --- a/vcweb/boundaries/models.py +++ b/vcweb/boundaries/models.py @@ -47,8 +47,8 @@ def get_observe_other_group_parameter(): return Parameter.objects.for_round(name='observe_other_group') -def can_observe_other_group(round_configuration): - return round_configuration.get_parameter_value(parameter=get_observe_other_group_parameter(), default=False).boolean_value +def can_observe_other_group(experiment_configuration): + return experiment_configuration.get_parameter_value(parameter=get_observe_other_group_parameter(), default=False).boolean_value # players can either be dead or alive def get_player_status_dv(participant_group_relationship_id): diff -r 803f0f093db84c87d3605dd6c59e5ec2e895b8a9 -r b57b81a30fd882c0566c6fbd2472c8b8f4622525 vcweb/boundaries/tests.py --- a/vcweb/boundaries/tests.py +++ b/vcweb/boundaries/tests.py @@ -17,5 +17,3 @@ expected_parameter_names = ('survival_cost', 'storage', 'player_status') for p in ps: self.assertTrue(p.name in expected_parameter_names) - - diff -r 803f0f093db84c87d3605dd6c59e5ec2e895b8a9 -r b57b81a30fd882c0566c6fbd2472c8b8f4622525 vcweb/boundaries/views.py --- a/vcweb/boundaries/views.py +++ b/vcweb/boundaries/views.py @@ -9,7 +9,7 @@ from vcweb.boundaries.forms import HarvestDecisionForm from vcweb.boundaries.models import (get_experiment_metadata, get_regrowth_rate, get_harvest_decision_parameter, get_cost_of_living, get_resource_level, get_initial_resource_level, get_total_storage, get_storage, - get_last_harvest_decision) + get_last_harvest_decision, can_observe_other_group) import logging import random @@ -65,7 +65,7 @@ cost_of_living = get_cost_of_living(current_round) own_group = participant_group_relationship.group own_resource_level = 0 - last_harvest_decision = get_last_harvest_decision(pgr, round_data=previous_round_data) + last_harvest_decision = get_last_harvest_decision(participant_group_relationship, round_data=previous_round_data) experiment_model_dict['playerData'] = [{ 'id': pgr.participant_number, 'lastHarvestDecision': last_harvest_decision, @@ -97,8 +97,8 @@ experiment_model_dict['roundType'] = current_round.round_type experiment_model_dict['regrowthRate'] = regrowth_rate experiment_model_dict['costOfLiving'] = cost_of_living - experiment_model_dict['participantNumber'] = pgr.participant_number - experiment_model_dict['participantGroupId'] = pgr.pk + experiment_model_dict['participantNumber'] = participant_group_relationship.participant_number + experiment_model_dict['participantGroupId'] = participant_group_relationship.pk experiment_model_dict['dollarsPerToken'] = ec.exchange_rate experiment_model_dict['chatEnabled'] = round_configuration.chat_enabled # FIXME: defaults hard coded in for now @@ -106,7 +106,7 @@ experiment_model_dict['warningCountdownTime'] = 10 experiment_model_dict['lastHarvestDecision'] = last_harvest_decision - experiment_model_dict['storage'] = get_storage(pgr, current_round_data) + experiment_model_dict['storage'] = get_storage(participant_group_relationship, current_round_data) experiment_model_dict['resourceLevel'] = own_resource_level # FIXME: these need to be looked up experiment_model_dict['maxHarvestDecision'] = 10 diff -r 803f0f093db84c87d3605dd6c59e5ec2e895b8a9 -r b57b81a30fd882c0566c6fbd2472c8b8f4622525 vcweb/core/models.py --- a/vcweb/core/models.py +++ b/vcweb/core/models.py @@ -215,13 +215,13 @@ def get_parameter_value(self, parameter=None, name=None, default=None): if parameter is None and name is None: logger.error("Can't find a parameter value with no name or parameter, returning default") - return default + return DefaultValue(default) try: if parameter: return self.experiment_parameter_value_set.get(parameter=parameter) elif name: return self.experiment_parameter_value_set.get(parameter__name=name) - except ExperimentParameterValue.DoesNotExist: + except ExperimentParameterValue.DoesNotExist as e: logger.debug("no experiment configuration parameter value found: (%s, %s) returning default %s", parameter, name, default) return DefaultValue(default) https://bitbucket.org/virtualcommons/vcweb/commits/658e0da29ff7/ changeset: 658e0da29ff7 user: alllee date: 2013-03-19 05:14:24 summary: adding group shared resource experiment configuration parameter affected #: 1 file diff -r b57b81a30fd882c0566c6fbd2472c8b8f4622525 -r 658e0da29ff738092655dd2384d3136d769bcb0b vcweb/boundaries/models.py --- a/vcweb/boundaries/models.py +++ b/vcweb/boundaries/models.py @@ -45,7 +45,11 @@ @simplecache def get_observe_other_group_parameter(): - return Parameter.objects.for_round(name='observe_other_group') + return Parameter.objects.for_experiment(name='observe_other_group') + +@simplecache +def get_shared_resource_parameter(): + return Parameter.objects.for_experiment(name='shared_resource') def can_observe_other_group(experiment_configuration): return experiment_configuration.get_parameter_value(parameter=get_observe_other_group_parameter(), default=False).boolean_value Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
|
From: <com...@bi...> - 2013-03-19 01:17:48
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/803f0f093db8/ changeset: 803f0f093db8 user: alllee date: 2013-03-19 02:14:06 summary: fixing list comprehension syntax affected #: 1 file diff -r 24eb0b1507a8f308d8464cda38631c264bc2fde5 -r 803f0f093db84c87d3605dd6c59e5ec2e895b8a9 vcweb/boundaries/views.py --- a/vcweb/boundaries/views.py +++ b/vcweb/boundaries/views.py @@ -66,21 +66,17 @@ own_group = participant_group_relationship.group own_resource_level = 0 last_harvest_decision = get_last_harvest_decision(pgr, round_data=previous_round_data) - experiment_model_dict['playerData'] = { - 'id': pgr.participant_number, - 'lastHarvestDecision': last_harvest_decision, - 'storage': get_storage(pgr, current_round_data), - } for pgr in own_group.participant_group_relationship_set.all() - - - experiment_model_dict['chatMessages'] = [ - { 'pk': cm.pk, - 'participant_number': cm.participant_group_relationship.participant_number, - 'message': cm.string_value, - 'date_created': cm.date_created.strftime("%I:%M:%S") - } - for cm in ChatMessage.objects.for_group(own_group) - ] + experiment_model_dict['playerData'] = [{ + 'id': pgr.participant_number, + 'lastHarvestDecision': last_harvest_decision, + 'storage': get_storage(pgr, current_round_data), + } for pgr in own_group.participant_group_relationship_set.all()] + experiment_model_dict['chatMessages'] = [{ + 'pk': cm.pk, + 'participant_number': cm.participant_group_relationship.participant_number, + 'message': cm.string_value, + 'date_created': cm.date_created.strftime("%I:%M:%S") + } for cm in ChatMessage.objects.for_group(own_group)] experiment_model_dict['initialResourceLevel'] = get_initial_resource_level(current_round) if not current_round.is_practice_round and can_observe_other_group(current_round): gr = GroupRelationship.objects.select_related('cluster').get(group=own_group) Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
|
From: <com...@bi...> - 2013-03-19 01:13:02
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/24eb0b1507a8/ changeset: 24eb0b1507a8 user: alllee date: 2013-03-19 02:12:44 summary: wiring up observe_other_group parameter and group cluster lookups. removing experimenter test controls, almost ready to enable experimenter driven round progression affected #: 6 files diff -r 46fc340bca8d0f2f3bd6fe8618de5f916f85272f -r 24eb0b1507a8f308d8464cda38631c264bc2fde5 vcweb/boundaries/models.py --- a/vcweb/boundaries/models.py +++ b/vcweb/boundaries/models.py @@ -16,6 +16,9 @@ EXPERIMENT_METADATA_NAME = intern('bound') MAX_RESOURCE_LEVEL = 240 +''' +Experiment Parameters and Metadata Accessors +''' @simplecache def get_experiment_metadata(): return ExperimentMetadata.objects.get(namespace=EXPERIMENT_METADATA_NAME) @@ -41,8 +44,11 @@ return Parameter.objects.for_round(name='cost_of_living') @simplecache -def get_exchange_rate_parameter(): - return Parameter.objects.for_experiment(name='exchange_rate') +def get_observe_other_group_parameter(): + return Parameter.objects.for_round(name='observe_other_group') + +def can_observe_other_group(round_configuration): + return round_configuration.get_parameter_value(parameter=get_observe_other_group_parameter(), default=False).boolean_value # players can either be dead or alive def get_player_status_dv(participant_group_relationship_id): diff -r 46fc340bca8d0f2f3bd6fe8618de5f916f85272f -r 24eb0b1507a8f308d8464cda38631c264bc2fde5 vcweb/boundaries/templates/boundaries/participate.html --- a/vcweb/boundaries/templates/boundaries/participate.html +++ b/vcweb/boundaries/templates/boundaries/participate.html @@ -5,56 +5,6 @@ <link rel='stylesheet' href='{% static "css/boundaries/style.css" %}'/> {% endblock %} {% block content %} -<form class='form-inline'> - <h2>Experimenter Panel</h2> - <!-- - <div class='control-group'> - <label class='control-label' for='set-resource-level'>Resource level</label> - <div class='controls'> - 0 <input type='range' id='set-resource-level' data-bind='value: resourceLevel' min='0' max='100' /> 100 - </div> - </div> - <div class='control-group'> - <label class='control-label' for='set-survival-cost'>Survival cost</label> - <div class='controls'> - <input class='input-small' type='number' id='set-survival-cost' data-bind='value:costOfLiving' /> - </div> - </div> - <div class='control-group'> - <label class='control-label' for='set-storage'>Storage</label> - <div class='controls'> - <input class='input-small' type='number' id='set-storage' data-bind='value:storage' /> - </div> - </div> - <div class='control-group'> - <label class='control-label' for='set-regrowth-rate'>Regrowth rate</label> - <div class='controls'> - <input class='input-small' step='0.1' type='number' id='set-regrowth-rate' data-bind='value:regrowthRate' /> - </div> - </div> - --> - <div class='control-group'> - <div class='controls'> - <label class='control-label' for='pick-template'>Round template</label> - <select id='pick-template' data-bind='value: templateName()'> - <option value='WELCOME'>Welcome</option> - <option value='GENERAL_INSTRUCTIONS'>Instructions</option> - <option value='GENERAL_INSTRUCTIONS2'>Instructions page 2</option> - <option value='GENERAL_INSTRUCTIONS3'>Instructions page 3</option> - <option value='PRACTICE_ROUND_INSTRUCTIONS'>Practice Round Instructions</option> - <option value='PRACTICE'>Practice round</option> - <option value='REGULAR'>Actual round</option> - </select> - </div> - </div> - <h3>Timers</h3> - <div class='control-group'> - <div class='controls'> - <button data-bind='click: startHarvestDecisionTimer' type='button' class='btn btn-primary'>Start harvest decision timer</button> - <button data-bind='click: startChatTimer' type='button' class='btn btn-primary'>Start chat timer</button> - </div> - </div> -</form><div data-bind='template: { name: templateName() }'></div> {% endblock content %} @@ -302,10 +252,10 @@ </div><h3>Forest</h3><div data-bind='if: practiceRound'> -<div class='alert alert-error alert-block'> -<h4>PRACTICE ROUND</h4> -This is a practice round. The decisions you make in this round will <b>NOT</b> contribute to your earnings. -</div> + <div class='alert alert-error alert-block'> + <h4>PRACTICE ROUND</h4> + This is a practice round. The decisions you make in this round will <b>NOT</b> contribute to your earnings. + </div></div><div data-bind="ifnot: isResourceEmpty" id='resourceDisplay'> @@ -321,53 +271,51 @@ <div class='alert alert-error'>There are no more resources to harvest. Please wait until the next round begins.</div></div><div data-bind='if: hasSubmit'> -<div class='alert alert-error'> - You have submitted a decision to harvest <span class='badge badge-important' data-bind='text: harvestDecision'></span> resources. -</div> + <div class='alert alert-error'> + You have submitted a decision to harvest <span class='badge badge-important' data-bind='text: harvestDecision'></span> resources. + </div></div> -<h3>Observe Other Group</h3> -<div class='row'> -<div class='span4'> -<table> -<tr> -<td> -<button class='btn' data-bind='click: showOtherGroup'><i class='icon-eye-open'></i> Observe</a> -</td> -<td> -<img src='{{STATIC_URL}}/images/boundaries/observe.png' alt='observe'> -</td> -</tr> -</table> -</div> -<div class='span5'> -<div data-bind='if: shouldShowOtherGroup'> -<table class='table table-bordered table-condensed'> -<caption>Observation Results</caption> -<thead> -<tr><th></th><th>Other Group</th></tr> -</thead> -<tbody> -<tr><td>trees in forest</td><td data-bind='text:otherGroupResourceLevel()'></td></tr> -<tr><td>average harvest</td><td data-bind='text:otherGroupAverageHarvest().toFixed(1)'></td></tr> -<tr><td>average storage</td><td data-bind='text:otherGroupAverageStorage().toFixed(1)'></td></tr> -</tbody> -</table> -</div> -</div> +<div data-bind='if: canObserveOtherGroup'> + <h3>Observe Other Group</h3> + <div class='row'> + <div class='span4'> + <table> + <tr> + <td><button class='btn' data-bind='click: showOtherGroup'><i class='icon-eye-open'></i> Observe</a></td> + <td><img src='{{STATIC_URL}}/images/boundaries/observe.png' alt='observe'></td> + </tr> + </table> + </div> + <div class='span5'> + <div data-bind='if: shouldShowOtherGroup'> + <table class='table table-bordered table-condensed'> + <caption>Observation Results</caption> + <thead> + <tr><th></th><th>Other Group</th></tr> + </thead> + <tbody> + <tr><td>trees in forest</td><td data-bind='text:otherGroupResourceLevel()'></td></tr> + <tr><td>average harvest</td><td data-bind='text:otherGroupAverageHarvest().toFixed(1)'></td></tr> + <tr><td>average storage</td><td data-bind='text:otherGroupAverageStorage().toFixed(1)'></td></tr> + </tbody> + </table> + </div> + </div> + </div></div><h3>Harvest</h3><div data-bind='ifnot: isResourceEmpty'> -<form id='vcweb-form' action='' method='post' class='form-inline'> - {% csrf_token %} - <div class='control-group'> - <div class='controls'> - <input id='participantGroupId' type='hidden' name='participant_group_id' data-bind='value: participantGroupId'/> - <input id='harvestDecision' type="number" size="1" maxlength="1" name='harvest_decision' class='required' min="0" data-bind="value: harvestDecision, attr: { max: maxHarvestDecision }" /> - <button id='submitDecision' data-bind='click: submitDecision' type='submit' class='btn'>Harvest</button> + <form id='vcweb-form' action='' method='post' class='form-inline'> + {% csrf_token %} + <div class='control-group'> + <div class='controls'> + <input id='participantGroupId' type='hidden' name='participant_group_id' data-bind='value: participantGroupId'/> + <input id='harvestDecision' type="number" size="1" maxlength="1" name='harvest_decision' class='required' min="0" data-bind="value: harvestDecision, attr: { max: maxHarvestDecision }" /> + <button id='submitDecision' data-bind='click: submitDecision' type='submit' class='btn'>Harvest</button> + </div></div> - </div> -</form> + </form></div></script><script type="text/javascript"> @@ -421,7 +369,6 @@ model.showOtherGroup = function() { model.shouldShowOtherGroup(true); } - model.chatEnabled = ko.observable(false); model.shouldShowOtherGroup = ko.observable(false); model.harvestDecision = ko.observable(0); model.numberOfTreesPerRow = ko.observable(10); diff -r 46fc340bca8d0f2f3bd6fe8618de5f916f85272f -r 24eb0b1507a8f308d8464cda38631c264bc2fde5 vcweb/boundaries/views.py --- a/vcweb/boundaries/views.py +++ b/vcweb/boundaries/views.py @@ -61,20 +61,17 @@ previous_round_data = experiment.get_round_data(round_configuration=previous_round) experiment_model_dict = experiment.as_dict(include_round_data=False, attrs={}) - group_data = [] - player_data = [] regrowth_rate = get_regrowth_rate(current_round) cost_of_living = get_cost_of_living(current_round) own_group = participant_group_relationship.group own_resource_level = 0 - for pgr in own_group.participant_group_relationship_set.all(): - player_data.append({ + last_harvest_decision = get_last_harvest_decision(pgr, round_data=previous_round_data) + experiment_model_dict['playerData'] = { 'id': pgr.participant_number, - # FIXME: replace with lookup of last harvest decision, if it exists - 'lastHarvestDecision': get_last_harvest_decision(pgr, round_data=previous_round_data), + 'lastHarvestDecision': last_harvest_decision, 'storage': get_storage(pgr, current_round_data), - }) - experiment_model_dict['playerData'] = player_data + } for pgr in own_group.participant_group_relationship_set.all() + experiment_model_dict['chatMessages'] = [ { 'pk': cm.pk, @@ -85,22 +82,19 @@ for cm in ChatMessage.objects.for_group(own_group) ] experiment_model_dict['initialResourceLevel'] = get_initial_resource_level(current_round) - experiment_model_dict['groupData'] = group_data -# FIXME: replace with group cluster lookups - for group in experiment.group_set.all(): - resource_level = get_resource_level(group) - if group == own_group: - own_resource_level = resource_level - group_data.append({ - 'groupId': unicode(group), - 'resourceLevel': resource_level, - 'totalStorage': get_total_storage(group), - 'regrowthRate': regrowth_rate, - 'costOfLiving': cost_of_living, - }) - experiment_model_dict['otherGroupResourceLevel'] = random.randint(50, 100) - experiment_model_dict['otherGroupAverageHarvest'] = random.uniform(0, 10) - experiment_model_dict['otherGroupAverageStorage'] = random.uniform(10, 30) + if not current_round.is_practice_round and can_observe_other_group(current_round): + gr = GroupRelationship.objects.select_related('cluster').get(group=own_group) + group_data = [] + for group in gr.cluster.group_set.all(): + if group != own_group: + group_data.append({ + 'groupId': unicode(group), + 'resourceLevel': resource_level, + 'totalStorage': get_total_storage(group), + 'regrowthRate': regrowth_rate, + 'costOfLiving': cost_of_living, + }) + experiment_model_dict['groupData'] = group_data # round / experiment configuration data experiment_model_dict['participantsPerGroup'] = ec.max_group_size @@ -109,18 +103,19 @@ experiment_model_dict['costOfLiving'] = cost_of_living experiment_model_dict['participantNumber'] = pgr.participant_number experiment_model_dict['participantGroupId'] = pgr.pk + experiment_model_dict['dollarsPerToken'] = ec.exchange_rate + experiment_model_dict['chatEnabled'] = round_configuration.chat_enabled # FIXME: defaults hard coded in for now - experiment_model_dict['dollarsPerToken'] = 0.20 experiment_model_dict['maxEarnings'] = 20.00 experiment_model_dict['warningCountdownTime'] = 10 + experiment_model_dict['lastHarvestDecision'] = last_harvest_decision + experiment_model_dict['storage'] = get_storage(pgr, current_round_data) + experiment_model_dict['resourceLevel'] = own_resource_level # FIXME: these need to be looked up - experiment_model_dict['lastHarvestDecision'] = 5 experiment_model_dict['maxHarvestDecision'] = 10 - experiment_model_dict['storage'] = 20 - experiment_model_dict['resourceLevel'] = own_resource_level experiment_model_dict['hasSubmit'] = False - experiment_model_dict['practiceRound'] = False + experiment_model_dict['practiceRound'] = round_configuration.is_practice_round experiment_model_dict['instructions'] = current_round.get_custom_instructions(session_number=get_session_number(current_round)) experiment_model_dict.update(**kwargs) return dumps(experiment_model_dict) diff -r 46fc340bca8d0f2f3bd6fe8618de5f916f85272f -r 24eb0b1507a8f308d8464cda38631c264bc2fde5 vcweb/core/models.py --- a/vcweb/core/models.py +++ b/vcweb/core/models.py @@ -631,9 +631,9 @@ def initialize_data_values(self, group_parameters=None, participant_parameters=None, round_data=None): logger.debug("initializing [participant params: %s] [group parameters: %s] ", participant_parameters, group_parameters) if group_parameters is None: - group_parameters = self.parameters(scope=Parameter.GROUP_SCOPE) + group_parameters = self.parameters(scope=Parameter.Scope.GROUP) if participant_parameters is None: - participant_parameters = self.parameters(scope=Parameter.PARTICIPANT_SCOPE) + participant_parameters = self.parameters(scope=Parameter.Scope.PARTICIPANT) if round_data is None: round_data = self.current_round_data for group in self.group_set.select_related('parameter').all(): @@ -884,7 +884,7 @@ QUIZ=('Quiz round', 'quiz.html')) ROUND_TYPES = (CHAT, DEBRIEFING, INSTRUCTIONS, PRACTICE, QUIZ, REGULAR, WELCOME) = sorted(ROUND_TYPES_DICT.keys()) - ROUND_TYPE_CHOICES = [(round_type, ROUND_TYPES_DICT[round_type][0]) for round_type in ROUND_TYPES] + ROUND_TYPE_CHOICES = Choices((round_type, ROUND_TYPES_DICT[round_type][0]) for round_type in ROUND_TYPES) PLAYABLE_ROUND_CONFIGURATIONS = (PRACTICE, REGULAR) experiment_configuration = models.ForeignKey(ExperimentConfiguration, related_name='round_configuration_set') @@ -903,7 +903,6 @@ """ instructions, if any, to display before the round begins """ debriefing = models.TextField(null=True, blank=True) """ debriefing, if any, to display after the round ends """ -# FIXME: replace with model_utils Choices round_type = models.CharField(max_length=32, choices=ROUND_TYPE_CHOICES, default=REGULAR) @@ -1055,36 +1054,35 @@ class ParameterQuerySet(models.query.QuerySet): def for_participant(self, **kwargs): - return self.get(scope=Parameter.PARTICIPANT_SCOPE, **kwargs) + return self.get(scope=Parameter.Scope.PARTICIPANT, **kwargs) def for_group(self, **kwargs): - return self.get(scope=Parameter.GROUP_SCOPE, **kwargs) + return self.get(scope=Parameter.Scope.GROUP, **kwargs) def for_group_round(self, **kwargs): - return self.get(scope=Parameter.GROUP_ROUND_SCOPE, **kwargs) + return self.get(scope=Parameter.Scope.GROUP_ROUND, **kwargs) def for_round(self, **kwargs): - return self.get(scope=Parameter.ROUND_SCOPE, **kwargs) + return self.get(scope=Parameter.Scope.ROUND, **kwargs) def for_experiment(self, **kwargs): - return self.get(scope=Parameter.EXPERIMENT_SCOPE, **kwargs) + return self.get(scope=Parameter.Scope.EXPERIMENT, **kwargs) class ParameterPassThroughManager(PassThroughManager): def get_by_natural_key(self, name): return self.get(name=name) class Parameter(models.Model): - PARAMETER_TYPES = (('int', 'Integer'), - ('string', 'String'), - ('foreignkey', 'Foreign key'), - ('float', 'Floating-point number'), - ('boolean', (('True', True), ('False', False))), - ('enum', 'Enumeration')) + ParameterType = Choices(('int', 'Integer value'), + ('string', 'String value'), + ('foreignkey', 'Foreign key'), + ('float', 'Floating-point number'), + ('boolean', 'True/False'), + ('enum', 'Enumeration')) # FIXME: arcane, see if we can encapsulate this better. used to provide sane default values for each parameter type # when the parameter is null - NONE_VALUES_DICT = dict(map(lambda x,y: (x[0], y), PARAMETER_TYPES, [0, '', -1, 0.0, False, None])) - #dict(zip([parameter_type[0] for parameter_type in PARAMETER_TYPES], [0, '', 0.0, False, None])) + NONE_VALUES_DICT = dict(map(lambda x,y: (x[0], y), ParameterType, [0, '', -1, 0.0, False, None])) CONVERTERS = { 'int': int, @@ -1100,23 +1098,18 @@ NOTE: they expect already validated string data and will throw ValueErrors on invalid input. ''' - GROUP_SCOPE = 'group' - GROUP_ROUND_SCOPE = 'group_round' - PARTICIPANT_SCOPE = 'participant' - ROUND_SCOPE = 'round' - EXPERIMENT_SCOPE = 'experiment' - SCOPE_CHOICES = ((ROUND_SCOPE, 'Parameter applies just for this round'), - (EXPERIMENT_SCOPE, 'Parameter applies to this entire experiment'), - (GROUP_SCOPE, 'Parameter applies to the entire group for the duration of the experiment'), - (GROUP_ROUND_SCOPE, 'Parameter applies to the entire group for a given round'), - (PARTICIPANT_SCOPE, 'Parameter is for a single participant')) + Scope = Choices(('round', 'ROUND', 'Parameter applies to the entire round across all groups'), + ('experiment', 'EXPERIMENT', 'Parameter applies to the entire experiment across all groups and rounds'), + ('group', 'GROUP', 'Parameter applies to a group for the duration of the experiment'), + ('group_round', 'GROUP_ROUND', 'Parameter applies to a group for a given round'), + ('participant', 'PARTICIPANT', 'Parameter applies for a single participant')) - scope = models.CharField(max_length=32, choices=SCOPE_CHOICES, default=ROUND_SCOPE) + scope = models.CharField(max_length=32, choices=Scope, default=Scope.ROUND) name = models.CharField(max_length=255, unique=True) display_name = models.CharField(max_length=255, null=True, blank=True) description = models.CharField(max_length=512, null=True, blank=True) - type = models.CharField(max_length=32, choices=PARAMETER_TYPES) + type = models.CharField(max_length=32, choices=ParameterType) class_name = models.CharField(max_length=64, null=True, blank=True, help_text='Model classname in the form of appname.modelname, e.g., "core.Experiment". Only applicable for foreign key parameters.') default_value_string = models.CharField(max_length=255, null=True, blank=True) date_created = models.DateTimeField(default=datetime.now) @@ -1322,7 +1315,7 @@ @property def data_parameters(self): - return Parameter.objects.filter(experiment_metadata=self.experiment.experiment_metadata, scope=Parameter.GROUP_SCOPE) + return Parameter.objects.filter(experiment_metadata=self.experiment.experiment_metadata, scope=Parameter.Scope.GROUP) @property def current_round_data(self): @@ -1717,11 +1710,14 @@ def get_data_value(self, parameter=None, round_data=None, default=None): if round_data is None: round_data = self.current_round_data - if parameter is not None: - return ParticipantRoundDataValue.objects.get(round_data=round_data, parameter=parameter, - participant_group_relationship=self) - logger.warning("unable to retrieve data value with parameter %s, returning default value %s", parameter, default) - return DefaultValue(default) + try: + return ParticipantRoundDataValue.objects.get(round_data=round_data, parameter=parameter, participant_group_relationship=self) + except ParticipantRoundDataValue.DoesNotExist as e: + if default is None: + raise e + else: + logger.warning("unable to retrieve ParticipantRoundDataValue with parameter %s, returning default value %s", parameter, default) + return DefaultValue(default) def set_data_value(self, parameter=None, value=None, round_data=None): if round_data is None: @@ -1812,10 +1808,6 @@ # unique_together = (('parameter', 'participant_group_relationship'),) -@simplecache -def get_chat_message_parameter(): - return Parameter.objects.get(name='chat_message', scope=Parameter.PARTICIPANT_SCOPE) - class ChatMessageQuerySet(models.query.QuerySet): def for_group(self, group=None, **kwargs): @@ -1875,18 +1867,6 @@ class Meta: ordering = ['date_created'] -@simplecache -def get_comment_parameter(): - return Parameter.objects.get(name='comment', scope=Parameter.PARTICIPANT_SCOPE) - -@simplecache -def get_like_parameter(): - return Parameter.objects.get(name='like', scope=Parameter.PARTICIPANT_SCOPE) - -@simplecache -def get_participant_ready_parameter(): - return Parameter.objects.get(name='participant_ready', scope=Parameter.PARTICIPANT_SCOPE) - class Comment(ParticipantRoundDataValue): def __init__(self, *args, **kwargs): kwargs['parameter'] = get_comment_parameter() @@ -1960,6 +1940,25 @@ participations = models.PositiveIntegerField(default=0) invitations = models.PositiveIntegerField(default=0) +''' parameter accessors ''' +@simplecache +def get_chat_message_parameter(): + return Parameter.objects.get(name='chat_message', scope=Parameter.Scope.PARTICIPANT) + +@simplecache +def get_comment_parameter(): + return Parameter.objects.get(name='comment', scope=Parameter.Scope.PARTICIPANT) + +@simplecache +def get_like_parameter(): + return Parameter.objects.get(name='like', scope=Parameter.Scope.PARTICIPANT) + +@simplecache +def get_participant_ready_parameter(): + return Parameter.objects.get(name='participant_ready', scope=Parameter.Scope.PARTICIPANT) + + + def is_experimenter(user, experimenter=None): """ returns true if user.experimenter exists and is an Experimenter instance. If an experimenter is passed in as a diff -r 46fc340bca8d0f2f3bd6fe8618de5f916f85272f -r 24eb0b1507a8f308d8464cda38631c264bc2fde5 vcweb/core/tests.py --- a/vcweb/core/tests.py +++ b/vcweb/core/tests.py @@ -93,7 +93,7 @@ template_name=template_name ) - def create_new_parameter(self, name='vcweb.test.parameter', scope='EXPERIMENT_SCOPE', parameter_type='string'): + def create_new_parameter(self, name='vcweb.test.parameter', scope=Parameter.Scope.EXPERIMENT, parameter_type='string'): return Parameter.objects.create(experiment_metadata=self.experiment_metadata, creator=self.experimenter, name=name, scope=scope, type=parameter_type) def create_new_group(self, max_size=10, experiment=None): @@ -245,7 +245,7 @@ parameter=parameter) self.assertFalse(created) for pgr in group.participant_group_relationship_set.all(): - for parameter in e.parameters(scope=Parameter.PARTICIPANT_SCOPE): + for parameter in e.parameters(scope=Parameter.Scope.PARTICIPANT): participant_data_value, created = ParticipantRoundDataValue.objects.get_or_create(round_data=current_round_data, participant_group_relationship=pgr, parameter=parameter) self.assertFalse(created) @@ -264,7 +264,7 @@ self.assertEqual(g.get_scalar_data_value(parameter=data_value.parameter), test_data_value) def test_transfer_to_next_round(self): - parameter = self.create_new_parameter(scope=Parameter.GROUP_SCOPE, name='test_group_parameter', parameter_type='int') + parameter = self.create_new_parameter(scope=Parameter.Scope.GROUP, name='test_group_parameter', parameter_type='int') test_data_value = 37 e = self.experiment first_pass = True @@ -328,17 +328,6 @@ class RoundConfigurationTest(BaseVcwebTest): - def test_round_configuration_enums(self): - self.assertEqual(len(RoundConfiguration.ROUND_TYPES), len(RoundConfiguration.ROUND_TYPES_DICT)) - self.assertEqual(RoundConfiguration.PRACTICE, 'PRACTICE') - self.assertEqual(RoundConfiguration.REGULAR, 'REGULAR') - choices = RoundConfiguration.ROUND_TYPE_CHOICES - self.assertEqual(len(choices), len(RoundConfiguration.ROUND_TYPES_DICT)) - for pair in choices: - self.assertTrue(pair[0] in RoundConfiguration.ROUND_TYPES_DICT.keys()) - self.assertTrue(pair[0] in RoundConfiguration.ROUND_TYPES) - self.assertFalse(pair[1].isupper()) - def test_parameterized_value(self): e = self.experiment p = Parameter.objects.create(scope='round', name='test_round_parameter', type='int', creator=e.experimenter, experiment_metadata=e.experiment_metadata) diff -r 46fc340bca8d0f2f3bd6fe8618de5f916f85272f -r 24eb0b1507a8f308d8464cda38631c264bc2fde5 vcweb/forestry/tests.py --- a/vcweb/forestry/tests.py +++ b/vcweb/forestry/tests.py @@ -206,14 +206,14 @@ data_value.save() self.assertEqual(100, data_value.value) self.assertEqual(e.get_round_data().group_data_value_set.count(), GroupRoundDataValue.objects.filter(group__experiment=e, round_data=round_data).count()) - self.assertEqual(e.parameters(scope=Parameter.GROUP_SCOPE).count(), 3) + self.assertEqual(e.parameters(scope=Parameter.Scope.GROUP).count(), 3) data_round_number += 1 def test_data_parameters(self): e = self.experiment # FIXME: horrible tests, improve self.assertEqual(6, e.parameters().count()) - for data_param in e.parameters(scope=Parameter.GROUP_SCOPE).all(): + for data_param in e.parameters(scope=Parameter.Scope.GROUP).all(): logger.debug("inspecting data param %s" % data_param) self.assertEqual(data_param.type, 'int', 'Currently all group data parameters for the forestry experiment are ints.') @@ -223,7 +223,7 @@ e.activate() e.start_round() round_data = e.get_round_data() - for data_param in e.parameters(scope=Parameter.PARTICIPANT_SCOPE).all(): + for data_param in e.parameters(scope=Parameter.Scope.PARTICIPANT).all(): for p in self.participants: per = ParticipantExperimentRelationship.objects.get(participant=p, experiment=e) pgr = ParticipantGroupRelationship.objects.get(group__experiment=e, participant=p) @@ -235,7 +235,7 @@ def test_data_values(self): e = self.create_participant_data_values() - num_participant_parameters = e.parameters(scope=Parameter.PARTICIPANT_SCOPE).count() + num_participant_parameters = e.parameters(scope=Parameter.Scope.PARTICIPANT).count() self.assertEqual(e.participant_set.count() * num_participant_parameters, ParticipantRoundDataValue.objects.filter(round_data__experiment=e, parameter__type='int').count(), 'There should be %s participants * %s total data parameters = %s' % (e.participant_set.count(), num_participant_parameters, e.participant_set.count() * num_participant_parameters)) Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
|
From: <com...@bi...> - 2013-03-19 00:07:15
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/46fc340bca8d/ changeset: 46fc340bca8d user: alllee date: 2013-03-19 01:06:54 summary: adding chat_enabled column and migration affected #: 2 files diff -r d21848f9d4a0fbd735dd8cda3d0ce317c76e2a6b -r 46fc340bca8d0f2f3bd6fe8618de5f916f85272f vcweb/core/migrations/0025_auto__add_field_roundconfiguration_chat_enabled.py --- /dev/null +++ b/vcweb/core/migrations/0025_auto__add_field_roundconfiguration_chat_enabled.py @@ -0,0 +1,398 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding field 'RoundConfiguration.chat_enabled' + db.add_column(u'core_roundconfiguration', 'chat_enabled', + self.gf('django.db.models.fields.BooleanField')(default=False), + keep_default=False) + + + def backwards(self, orm): + # Deleting field 'RoundConfiguration.chat_enabled' + db.delete_column(u'core_roundconfiguration', 'chat_enabled') + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'auth.user': { + 'Meta': {'object_name': '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': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + '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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'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'}) + }, + u'core.activitylog': { + 'Meta': {'object_name': 'ActivityLog'}, + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'log_message': ('django.db.models.fields.TextField', [], {}) + }, + u'core.address': { + 'Meta': {'object_name': 'Address'}, + 'city': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'state': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), + 'street1': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'street2': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'zipcode': ('django.db.models.fields.CharField', [], {'max_length': '8', 'blank': 'True'}) + }, + u'core.chatmessage': { + 'Meta': {'ordering': "['date_created']", 'object_name': 'ChatMessage', '_ormbases': [u'core.ParticipantRoundDataValue']}, + u'participantrounddatavalue_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ParticipantRoundDataValue']", 'unique': 'True', 'primary_key': 'True'}), + 'target_participant': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'target_participant_chat_message_set'", 'null': 'True', 'to': u"orm['core.ParticipantGroupRelationship']"}) + }, + u'core.comment': { + 'Meta': {'ordering': "['date_created']", 'object_name': 'Comment', '_ormbases': [u'core.ParticipantRoundDataValue']}, + u'participantrounddatavalue_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ParticipantRoundDataValue']", 'unique': 'True', 'primary_key': 'True'}) + }, + u'core.experiment': { + 'Meta': {'ordering': "['date_created', 'status']", 'object_name': 'Experiment'}, + 'amqp_exchange_name': ('django.db.models.fields.CharField', [], {'default': "'vcweb.default.exchange'", 'max_length': '64'}), + 'authentication_code': ('django.db.models.fields.CharField', [], {'default': "'vcweb.auth.code'", 'max_length': '32'}), + 'current_round_elapsed_time': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'current_round_sequence_number': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}), + 'current_round_start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'duration': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), + 'experiment_configuration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentConfiguration']"}), + 'experiment_metadata': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentMetadata']"}), + 'experimenter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Experimenter']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'ready_participants': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'start_date_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'INACTIVE'", 'max_length': '32'}), + 'tick_duration': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), + 'total_elapsed_time': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}) + }, + u'core.experimentactivitylog': { + 'Meta': {'object_name': 'ExperimentActivityLog', '_ormbases': [u'core.ActivityLog']}, + u'activitylog_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ActivityLog']", 'unique': 'True', 'primary_key': 'True'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'activity_log_set'", 'to': u"orm['core.Experiment']"}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.experimentconfiguration': { + 'Meta': {'ordering': "['experiment_metadata', 'creator', 'date_created']", 'object_name': 'ExperimentConfiguration'}, + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_configuration_set'", 'to': u"orm['core.Experimenter']"}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'exchange_rate': ('django.db.models.fields.DecimalField', [], {'default': '0.2', 'null': 'True', 'max_digits': '6', 'decimal_places': '2', 'blank': 'True'}), + 'experiment_metadata': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_configuration_set'", 'to': u"orm['core.ExperimentMetadata']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invitation_subject': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'invitation_text': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'is_experimenter_driven': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'max_group_size': ('django.db.models.fields.PositiveIntegerField', [], {'default': '5'}), + 'max_number_of_participants': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'treatment_id': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}) + }, + u'core.experimenter': { + 'Meta': {'ordering': "['user']", 'object_name': 'Experimenter'}, + 'approved': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'authentication_token': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'failed_password_attempts': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'institution': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Institution']", 'null': 'True', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'experimenter'", 'unique': 'True', 'to': u"orm['auth.User']"}) + }, + u'core.experimenterrequest': { + 'Meta': {'object_name': 'ExperimenterRequest'}, + 'approved': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['auth.User']", 'unique': 'True'}) + }, + u'core.experimentmetadata': { + 'Meta': {'ordering': "['namespace', 'date_created']", 'object_name': 'ExperimentMetadata'}, + 'about_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'default_configuration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentConfiguration']", 'null': 'True', 'blank': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'logo_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'namespace': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'short_name': ('django.db.models.fields.SlugField', [], {'max_length': '32', 'unique': 'True', 'null': 'True', 'blank': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + u'core.experimentparametervalue': { + 'Meta': {'object_name': 'ExperimentParameterValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'experiment_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_parameter_value_set'", 'to': u"orm['core.ExperimentConfiguration']"}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + u'core.experimentsession': { + 'Meta': {'object_name': 'ExperimentSession'}, + 'capacity': ('django.db.models.fields.PositiveIntegerField', [], {'default': '20'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_session_set'", 'to': u"orm['auth.User']"}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'experiment_metadata': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_session_set'", 'to': u"orm['core.ExperimentMetadata']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invitation_text': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'scheduled_date': ('django.db.models.fields.DateTimeField', [], {}), + 'scheduled_end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}) + }, + u'core.group': { + 'Meta': {'ordering': "['experiment', 'number']", 'object_name': 'Group'}, + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Experiment']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'max_size': ('django.db.models.fields.PositiveIntegerField', [], {'default': '5'}), + 'number': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'session_id': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}) + }, + u'core.groupactivitylog': { + 'Meta': {'object_name': 'GroupActivityLog', '_ormbases': [u'core.ActivityLog']}, + u'activitylog_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ActivityLog']", 'unique': 'True', 'primary_key': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'activity_log_set'", 'to': u"orm['core.Group']"}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.groupcluster': { + 'Meta': {'ordering': "['date_created']", 'object_name': 'GroupCluster'}, + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Experiment']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'session_id': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}) + }, + u'core.groupclusterdatavalue': { + 'Meta': {'object_name': 'GroupClusterDataValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + 'group_cluster': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.GroupCluster']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'round_data': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'group_cluster_data_value_set'", 'to': u"orm['core.RoundData']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + u'core.grouprelationship': { + 'Meta': {'ordering': "['date_created']", 'object_name': 'GroupRelationship'}, + 'cluster': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'group_set'", 'to': u"orm['core.GroupCluster']"}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + u'core.grouprounddatavalue': { + 'Meta': {'ordering': "['round_data', 'group', 'parameter']", 'object_name': 'GroupRoundDataValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'data_value_set'", 'to': u"orm['core.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'round_data': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'group_data_value_set'", 'to': u"orm['core.RoundData']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + u'core.institution': { + 'Meta': {'object_name': 'Institution'}, + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}) + }, + u'core.invitation': { + 'Meta': {'object_name': 'Invitation'}, + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'experiment_session': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentSession']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'participant': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Participant']"}), + 'sender': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}) + }, + u'core.like': { + 'Meta': {'ordering': "['-date_created', 'round_data', 'participant_group_relationship', 'parameter']", 'object_name': 'Like', '_ormbases': [u'core.ParticipantRoundDataValue']}, + u'participantrounddatavalue_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ParticipantRoundDataValue']", 'unique': 'True', 'primary_key': 'True'}) + }, + u'core.parameter': { + 'Meta': {'ordering': "['name']", 'unique_together': "(('name', 'experiment_metadata', 'scope'),)", 'object_name': 'Parameter'}, + 'class_name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Experimenter']"}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'default_value_string': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'description': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'}), + 'display_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'enum_choices': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'experiment_metadata': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentMetadata']", 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_required': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'scope': ('django.db.models.fields.CharField', [], {'default': "'round'", 'max_length': '32'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '32'}) + }, + u'core.participant': { + 'Meta': {'ordering': "['user']", 'object_name': 'Participant'}, + 'address': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Address']", 'null': 'True', 'blank': 'True'}), + 'authentication_token': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'birthdate': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'can_receive_invitations': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'experiments': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'participant_set'", 'symmetrical': 'False', 'through': u"orm['core.ParticipantExperimentRelationship']", 'to': u"orm['core.Experiment']"}), + 'failed_password_attempts': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'gender': ('django.db.models.fields.CharField', [], {'max_length': '1', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'participant_set'", 'symmetrical': 'False', 'through': u"orm['core.ParticipantGroupRelationship']", 'to': u"orm['core.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'institution': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Institution']", 'null': 'True', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'participant'", 'unique': 'True', 'to': u"orm['auth.User']"}) + }, + u'core.participantexperimentrelationship': { + 'Meta': {'object_name': 'ParticipantExperimentRelationship'}, + 'additional_data': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}), + 'current_location': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'participant_relationship_set'", 'to': u"orm['core.Experiment']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_completed_round_sequence_number': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'participant': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_relationship_set'", 'to': u"orm['core.Participant']"}), + 'participant_identifier': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'sequential_participant_identifier': ('django.db.models.fields.PositiveIntegerField', [], {}) + }, + u'core.participantgrouprelationship': { + 'Meta': {'ordering': "['group', 'participant_number']", 'object_name': 'ParticipantGroupRelationship'}, + 'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'first_visit': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'participant_group_relationship_set'", 'to': u"orm['core.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'notifications_since': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'null': 'True', 'blank': 'True'}), + 'participant': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'participant_group_relationship_set'", 'to': u"orm['core.Participant']"}), + 'participant_number': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'round_joined': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.participantrounddatavalue': { + 'Meta': {'ordering': "['-date_created', 'round_data', 'participant_group_relationship', 'parameter']", 'object_name': 'ParticipantRoundDataValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'participant_group_relationship': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'participant_data_value_set'", 'to': u"orm['core.ParticipantGroupRelationship']"}), + 'round_data': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'participant_data_value_set'", 'to': u"orm['core.RoundData']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'submitted': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'target_data_value': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'target_data_value_set'", 'null': 'True', 'to': u"orm['core.ParticipantRoundDataValue']"}) + }, + u'core.participantsignup': { + 'Meta': {'object_name': 'ParticipantSignup'}, + 'attendance': ('django.db.models.fields.PositiveIntegerField', [], {'max_length': '1', 'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invitation': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'signup_set'", 'to': u"orm['core.Invitation']"}), + 'participant': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'signup_set'", 'to': u"orm['core.Participant']"}) + }, + u'core.quizquestion': { + 'Meta': {'object_name': 'QuizQuestion'}, + 'answer': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'default_quiz_question_set'", 'null': 'True', 'to': u"orm['core.Experiment']"}), + 'explanation': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'input_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'label': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'quiz_question_set'", 'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.roundconfiguration': { + 'Meta': {'ordering': "['experiment_configuration', 'sequence_number', 'date_created']", 'object_name': 'RoundConfiguration'}, + 'chat_enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'debriefing': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'display_number': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'duration': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'experiment_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'round_configuration_set'", 'to': u"orm['core.ExperimentConfiguration']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'instructions': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'preserve_existing_groups': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'randomize_groups': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'round_type': ('django.db.models.fields.CharField', [], {'default': "'REGULAR'", 'max_length': '32'}), + 'sequence_number': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'session_id': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'survey_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'template_name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}) + }, + u'core.rounddata': { + 'Meta': {'ordering': "['round_configuration']", 'unique_together': "(('round_configuration', 'experiment'),)", 'object_name': 'RoundData'}, + 'elapsed_time': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'round_data_set'", 'to': u"orm['core.Experiment']"}), + 'experimenter_notes': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'round_data_set'", 'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.roundparametervalue': { + 'Meta': {'object_name': 'RoundParameterValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'round_parameter_value_set'", 'to': u"orm['core.RoundConfiguration']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + u'core.spoolparticipantstatistics': { + 'Meta': {'object_name': 'SpoolParticipantStatistics'}, + 'absences': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'discharges': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invitations': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'participant': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'spool_statistics_set'", 'to': u"orm['core.Participant']"}), + 'participations': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}) + } + } + + complete_apps = ['core'] \ No newline at end of file diff -r d21848f9d4a0fbd735dd8cda3d0ce317c76e2a6b -r 46fc340bca8d0f2f3bd6fe8618de5f916f85272f vcweb/core/models.py --- a/vcweb/core/models.py +++ b/vcweb/core/models.py @@ -918,6 +918,7 @@ e.g., if set to foo.html, vcweb will look for templates/forestry/foo.html''')) survey_url = models.URLField(null=True, blank=True) """ external survey url """ + chat_enabled = models.BooleanField(default=False, help_text=_("Is chat enabled in this round?")) randomize_groups = models.BooleanField(default=False, help_text=_("Shuffle participants into new groups when the round begins?")) """ Should groups be randomized at the start of the round? """ preserve_existing_groups = models.BooleanField(default=True, help_text=_("This option is only useful if randomize_groups is set to true. If we are randomizing groups, should existing groups (if any) be preserved?")) Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
|
From: <com...@bi...> - 2013-03-18 23:34:05
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/d21848f9d4a0/ changeset: d21848f9d4a0 user: alllee date: 2013-03-19 00:33:50 summary: adding 500 handler back to properly render 500.html template when an unexpected server error occurs affected #: 4 files diff -r 05f5bf92e7fe379e5fb921aa67f7c1c8d8903bd8 -r d21848f9d4a0fbd735dd8cda3d0ce317c76e2a6b vcweb/core/templates/500.html --- a/vcweb/core/templates/500.html +++ b/vcweb/core/templates/500.html @@ -5,15 +5,13 @@ {% endblock %} {% block page %} - <div id='post'> - <h2 class='title'>Unhandled server error</h2> - <div class='entry'> - We just encountered an unforeseen error that has been logged and emailed to - our development team. If you'd like to report this error to us manually - as well, please feel free to <a href='/contact'>contact us</a> and let - us know what you were doing at the time of the error and any other - salient details (e.g., browser version, OS). - </div> + <h2>Unhandled server error</h2> + <div class='entry'> + We just encountered an unforeseen error that has been logged and emailed to + our development team. If you'd like to report this error to us manually + as well, please feel free to <a href='/contact'>contact us</a> and let + us know what you were doing at the time of the error and any other + salient details (e.g., browser version, OS). </div> {% endblock page %} diff -r 05f5bf92e7fe379e5fb921aa67f7c1c8d8903bd8 -r d21848f9d4a0fbd735dd8cda3d0ce317c76e2a6b vcweb/core/templates/base.html --- a/vcweb/core/templates/base.html +++ b/vcweb/core/templates/base.html @@ -1,6 +1,6 @@ {% load tags %} {% load url from future %} -{% load static %} +{% load static from staticfiles %} {% url 'home' as home %} {% url 'about' as about %} diff -r 05f5bf92e7fe379e5fb921aa67f7c1c8d8903bd8 -r d21848f9d4a0fbd735dd8cda3d0ce317c76e2a6b vcweb/core/views.py --- a/vcweb/core/views.py +++ b/vcweb/core/views.py @@ -532,5 +532,6 @@ return JsonResponse(dumps({'success': valid_form})) def handler500(request): + logger.debug("handling 500 request") return render_to_response('500.html', context_instance=RequestContext(request)) diff -r 05f5bf92e7fe379e5fb921aa67f7c1c8d8903bd8 -r d21848f9d4a0fbd735dd8cda3d0ce317c76e2a6b vcweb/urls.py --- a/vcweb/urls.py +++ b/vcweb/urls.py @@ -24,6 +24,7 @@ url(r'^accounts/password_reset/done/$', 'django.contrib.auth.views.password_reset_done', { 'template_name': 'account/password_reset_done.html' }), url(r'^accounts/reset/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$', 'django.contrib.auth.views.password_reset_confirm'), url(r'^accounts/reset/done/$', 'django.contrib.auth.views.password_reset_complete'), + url(dajaxice_config.dajaxice_url, include('dajaxice.urls')), # FIXME: ideally this should be set up dynamically by iterating through each @@ -44,5 +45,11 @@ # (r'^admin/doc/', include('django.contrib.admindocs.urls')), ) +handler500 = 'vcweb.core.views.handler500' + if settings.DEBUG: + urlpatterns += patterns('', + (r'^500/$', TemplateView.as_view(template_name='500.html'),), + ) urlpatterns += staticfiles_urlpatterns() + Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
|
From: <com...@bi...> - 2013-03-18 16:15:27
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/05f5bf92e7fe/ changeset: 05f5bf92e7fe user: alllee date: 2013-03-18 17:15:10 summary: fixing get_or_create call, returns a tuple affected #: 1 file diff -r f1545b8e19ce47e6e995cd029e7a0949a8a5c52b -r 05f5bf92e7fe379e5fb921aa67f7c1c8d8903bd8 vcweb/core/views.py --- a/vcweb/core/views.py +++ b/vcweb/core/views.py @@ -522,7 +522,7 @@ if valid_form: pgr = get_object_or_404(ParticipantGroupRelationship.objects.select_related('group__experiment'), pk=form.cleaned_data['participant_group_id']) experiment = pgr.group.experiment - prdv = ParticipantRoundDataValue.objects.get_or_create(participant_group_relationship=pgr, + prdv, created = ParticipantRoundDataValue.objects.get_or_create(participant_group_relationship=pgr, round_data=experiment.get_round_data(), parameter=get_participant_ready_parameter()) prdv.submitted = True prdv.boolean_value = True Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
|
From: <com...@bi...> - 2013-03-17 10:20:03
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/f1545b8e19ce/ changeset: f1545b8e19ce user: alllee date: 2013-03-17 11:19:50 summary: deploy config snippets affected #: 3 files diff -r fc527022929efdbf504f3c921b5a9dff5238622f -r f1545b8e19ce47e6e995cd029e7a0949a8a5c52b deploy/supervisord.conf --- /dev/null +++ b/deploy/supervisord.conf @@ -0,0 +1,5 @@ +[program:vcweb-sockjs] +directory=/opt/vcweb/ +command=/opt/virtualenvs/vcweb/bin/python /opt/vcweb/vcweb/vcweb-sockjs.py 8882 +autostart=true +redirect_stderr=true diff -r fc527022929efdbf504f3c921b5a9dff5238622f -r f1545b8e19ce47e6e995cd029e7a0949a8a5c52b deploy/vcweb.apache.vhost --- /dev/null +++ b/deploy/vcweb.apache.vhost @@ -0,0 +1,28 @@ +WSGISocketPrefix run/wsgi +WSGIPythonHome /opt/virtualenvs/vcweb +<VirtualHost *:80> + ServerAdmin all...@as... + DocumentRoot /var/www/vcweb + ServerName vcweb.asu.edu + + Alias /static /var/www/vcweb/static + <FilesMatch "\.(html|js|png|jpg|gif|css)"> + ExpiresDefault "access plus 1 days" + ExpiresActive On + </FilesMatch> + + Alias /favicon.ico /var/www/vcweb/static/favicon.ico + Alias /robots.txt /var/www/vcweb/static/robots.txt + + WSGIDaemonProcess vcweb-production user=apache group=commons threads=25 python-path=/opt/virtualenvs/vcweb/lib/python2.6/site-packages + WSGIProcessGroup vcweb-production + WSGIScriptAlias / /opt/webapps/virtualcommons/vcweb/vcweb.wsgi + <Directory /opt/webapps/virtualcommons/vcweb/vcweb/> + Order deny,allow + Allow from all + </Directory> + ErrorLog /var/log/apache2/vcweb/error.log + LogLevel warn + CustomLog /var/log/apache2/vcweb/access.log combined +</VirtualHost> + diff -r fc527022929efdbf504f3c921b5a9dff5238622f -r f1545b8e19ce47e6e995cd029e7a0949a8a5c52b vcweb/vcweb.apache.vhost --- a/vcweb/vcweb.apache.vhost +++ /dev/null @@ -1,28 +0,0 @@ -WSGISocketPrefix run/wsgi -WSGIPythonHome /opt/virtualenvs/vcweb -<VirtualHost *:80> - ServerAdmin all...@as... - DocumentRoot /var/www/vcweb - ServerName vcweb.asu.edu - - Alias /static /var/www/vcweb/static - <FilesMatch "\.(html|js|png|jpg|gif|css)"> - ExpiresDefault "access plus 1 days" - ExpiresActive On - </FilesMatch> - - Alias /favicon.ico /var/www/vcweb/static/favicon.ico - Alias /robots.txt /var/www/vcweb/static/robots.txt - - WSGIDaemonProcess vcweb-production user=apache group=commons threads=25 python-path=/opt/virtualenvs/vcweb/lib/python2.6/site-packages - WSGIProcessGroup vcweb-production - WSGIScriptAlias / /opt/webapps/virtualcommons/vcweb/vcweb.wsgi - <Directory /opt/webapps/virtualcommons/vcweb/vcweb/> - Order deny,allow - Allow from all - </Directory> - ErrorLog /var/log/apache2/vcweb/error.log - LogLevel warn - CustomLog /var/log/apache2/vcweb/access.log combined -</VirtualHost> - Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
|
From: <com...@bi...> - 2013-03-17 10:11:51
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/fc527022929e/ changeset: fc527022929e user: alllee date: 2013-03-17 11:11:38 summary: restarting sockjs tornado server along with httpd on deploy affected #: 1 file diff -r 8506625ba6d4a4cdd8f8c99e28b55bab0f48e6a6 -r fc527022929efdbf504f3c921b5a9dff5238622f fabfile.py --- a/fabfile.py +++ b/fabfile.py @@ -150,7 +150,7 @@ pip() def _restart_command(): - return 'service %(apache)s restart' % env + return 'service %(apache)s restart && supervisorctl restart vcweb-sockjs' % env def clean(): with cd(env.project_path): Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
|
From: <com...@bi...> - 2013-03-17 10:06:27
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/8506625ba6d4/ changeset: 8506625ba6d4 user: alllee date: 2013-03-17 11:06:12 summary: adding fix to sockjs script to allow for supervisord execution affected #: 1 file diff -r 02c48aeec9ec58b0d1e5c8193133494f163c0959 -r 8506625ba6d4a4cdd8f8c99e28b55bab0f48e6a6 vcweb/vcweb-sockjs.py --- a/vcweb/vcweb-sockjs.py +++ b/vcweb/vcweb-sockjs.py @@ -11,7 +11,7 @@ from tornado.escape import xhtml_escape import tornadoredis -sys.path.append(os.path.abspath('.')) +sys.path.append( path.abspath(path.join(path.dirname(path.abspath(__file__)), '..')) ) os.environ['DJANGO_SETTINGS_MODULE'] = 'vcweb.settings' from vcweb.core.models import (Experiment, ParticipantGroupRelationship, ParticipantExperimentRelationship, Participant, Experimenter, ChatMessage) Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
|
From: <com...@bi...> - 2013-03-17 08:24:02
|
2 new commits in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/2d310d561726/ changeset: 2d310d561726 user: alllee date: 2013-03-17 09:16:23 summary: adding default to exchange rate refactoring Experiment.Status field and replacing deprecated jquery live usage with .on affected #: 3 files diff -r 8ed7ca8671b66f2ab7aa9426be2e0100cf348102 -r 2d310d561726e6543c5dd29e5d2c4f0d621cf75f vcweb/core/models.py --- a/vcweb/core/models.py +++ b/vcweb/core/models.py @@ -180,7 +180,7 @@ last_modified = AutoDateTimeField(default=datetime.now) is_public = models.BooleanField(default=False) max_group_size = models.PositiveIntegerField(default=5) - exchange_rate = models.DecimalField(null=True, blank=True, max_digits=6, decimal_places=2, help_text=_('The exchange rate of currency per in-game token, e.g., dollars per token')) + exchange_rate = models.DecimalField(null=True, blank=True, default=0.2, max_digits=6, decimal_places=2, help_text=_('The exchange rate of currency per in-game token, e.g., dollars per token')) treatment_id = models.CharField(null=True, blank=True, max_length=32, help_text=_('An alphanumeric ID that should be unique to the set of ExperimentConfigurations for a given ExperimentMetadata')) is_experimenter_driven = models.BooleanField(default=True) """ @@ -266,13 +266,12 @@ Experiment instances are a concrete parameterization of an ExperimentMetadata record, with associated ExperimentConfiguration, Experimenter, etc. In other words, they represent an actual experiment run. """ - STATUS = Choices( + Status = Choices( ('INACTIVE', _('Not active')), ('ACTIVE', _('Active, no round in progress')), ('PAUSED', _('Paused')), ('ROUND_IN_PROGRESS', _('Round in progress')), ('COMPLETED', _('Completed'))) - (INACTIVE, ACTIVE, PAUSED, ROUND_IN_PROGRESS, COMPLETED) = [ choice[0] for choice in STATUS ] authentication_code = models.CharField(max_length=32, default="vcweb.auth.code") """ currently unused, but kept here in the event that we want to allow participants to authenticate with this @@ -289,7 +288,7 @@ """ the configuration parameters in use for this experiment run. """ # FIXME: consider using django-model-utils but need to verify that it works with South # status = StatusField() - status = models.CharField(max_length=32, choices=STATUS, default=STATUS.INACTIVE) + status = models.CharField(max_length=32, choices=Status, default=Status.INACTIVE) """ the status of an experiment can be either INACTIVE, ACTIVE, PAUSED, ROUND_IN_PROGRESS, or COMPLETED """ @@ -327,7 +326,7 @@ @property def is_round_in_progress(self): - return self.status == 'ROUND_IN_PROGRESS' + return self.status == Experiment.Status.ROUND_IN_PROGRESS @property def is_data_round_in_progress(self): @@ -495,11 +494,17 @@ @property def is_active(self): - return self.status != 'INACTIVE' + return self.status not in (Experiment.Status.COMPLETED, Experiment.Status.INACTIVE,) + + @property + def is_archived(self): + # FIXME: add a unique status for this if needed + return self.status == Experiment.Status.COMPLETED @property def is_completed(self): - return self.status == 'COMPLETED' + return self.status == Experiment.Status.COMPLETED + @property def is_public(self): return self.experiment_configuration.is_public @@ -746,7 +751,7 @@ def start_round(self, sender=None): logger.debug("%s STARTING ROUND (sender: %s)", self, sender) - self.status = 'ROUND_IN_PROGRESS' + self.status = Experiment.Status.ROUND_IN_PROGRESS self.create_round_data() self.current_round_elapsed_time = 0 self.current_round_start_time = datetime.now() @@ -767,7 +772,7 @@ return signals.round_started.send_robust(sender, experiment=self, time=datetime.now(), round_configuration=current_round_configuration) def end_round(self, sender=None): - self.status = 'ACTIVE' + self.status = Experiment.Status.ACTIVE self.current_round_elapsed_time = max(self.current_round_elapsed_time, self.current_round.duration) self.save() self.log('Ending round with elapsed time %s' % self.current_round_elapsed_time) @@ -779,19 +784,19 @@ def activate(self): if not self.is_active: self.allocate_groups() - self.status = 'ACTIVE' + self.status = Experiment.Status.ACTIVE self.start_date_time = datetime.now() self.save() return self def complete(self): self.log("Marking as COMPLETED") - self.status = 'COMPLETED' + self.status = Experiment.Status.COMPLETED self.save() def deactivate(self): self.log("Deactivating experiment and flagging as inactive.") - self.status = 'INACTIVE' + self.status = Experiment.Status.INACTIVE self.save() def check_elapsed_time(self): @@ -837,7 +842,7 @@ return self.to_dict(*args, **kwargs) def to_json(self, include_round_data=True, *args, **kwargs): - return dumps(self.as_dict(include_round_data, *args, **kwargs)) + return dumps(self.to_dict(include_round_data, *args, **kwargs)) """ returns a fresh copy of this experiment with configuration / metadata intact """ def clone(self, experimenter=None): @@ -849,7 +854,7 @@ experiment_configuration=self.experiment_configuration, duration=self.duration, tick_duration=self.tick_duration, - status=Experiment.INACTIVE + status=Experiment.Status.INACTIVE ) def transfer_participants(self, experiment): @@ -1581,15 +1586,15 @@ @property def active_experiments(self): - return self.experiment_relationship_set.filter(experiment__status=Experiment.ACTIVE) + return self.experiment_relationship_set.filter(experiment__status=Experiment.Status.ACTIVE) @property def inactive_experiments(self): - return self.experiment_relationship_set.exclude(experiment__status=Experiment.ACTIVE) + return self.experiment_relationship_set.exclude(experiment__status=Experiment.Status.ACTIVE) @property def completed_experiments(self): - return self.experiments_with_status(Experiment.COMPLETED) + return self.experiments_with_status(Experiment.Status.COMPLETED) def get_participant_experiment_relationship(self, experiment): return ParticipantExperimentRelationship.objects.select_related(depth=1).get(participant=self, experiment=experiment) @@ -1597,7 +1602,7 @@ def get_participant_group_relationship(self, experiment): return ParticipantGroupRelationship.objects.get_relationship(self, experiment) - def experiments_with_status(self, status=Experiment.ACTIVE): + def experiments_with_status(self, status=Experiment.Status.ACTIVE): return self.experiment_relationship_set.filter(experiment__status=status) class Meta: diff -r 8ed7ca8671b66f2ab7aa9426be2e0100cf348102 -r 2d310d561726e6543c5dd29e5d2c4f0d621cf75f vcweb/core/templates/experimenter/dashboard.html --- a/vcweb/core/templates/experimenter/dashboard.html +++ b/vcweb/core/templates/experimenter/dashboard.html @@ -12,6 +12,7 @@ <a class='btn' href='{{e.monitor_url}}'><i class='icon-zoom-in'></i> monitor</a></li><a class='btn confirm-experiment-action' data-content='Creates a new copy of this experiment with the same configuration and no participants.' href='{{e.clone_url}}'><i class='icon-copy'></i> clone</a> + {% if not e.is_archived %} {% if e.participant_set.count == 0 %} <a class='btn' data-content='Register participants for this experiment with actual email addresses' href='{{e.controller_url}}/register-email-list'><img src='{{STATIC_URL}}images/famfamfam/group_add.png' alt='register'/> register participants</a> @@ -26,7 +27,8 @@ <a data-content='Mark this experiment as completed' href='{{e.complete_url}}' class='btn confirm-experiment-action'><i class='icon-save'></i> archive</a><a data-content='deactivate this experiment' href='{{e.deactivate_url}}' class='btn confirm-experiment-action'><i class='icon-off'></i> deactivate</a> {% else %} - <a class='btn' data-content='Configure this experiment (sanitation)' href='{{e.configure_url}}'><i class='icon-wrench'></i>configure</a> + <a class='btn' data-content='Configure this experiment' href='{{e.configure_url}}'><i class='icon-wrench'></i> configure</a> + {% endif %} {% endif %} </div></div> diff -r 8ed7ca8671b66f2ab7aa9426be2e0100cf348102 -r 2d310d561726e6543c5dd29e5d2c4f0d621cf75f vcweb/core/templates/experimenter/monitor.html --- a/vcweb/core/templates/experimenter/monitor.html +++ b/vcweb/core/templates/experimenter/monitor.html @@ -17,14 +17,14 @@ </ul> {% comment %} should offer different actions (start + reset) to experiments that has already been activated / started {% endcomment %} <div data-bind="ifnot: isActive"> - <div data-bind="ifnot: hasParticipants()"> + <div data-bind="ifnot: hasParticipants"><div class='alert alert-error alert-block'><h4>No participants</h4><i class='icon-warning-sign'></i><a href='{{experiment.controller_url}}/register-email-list'>Register bulk email addresses</a> or <a href='{{experiment.controller_url}}/register-simple'>add test participants</a>? </div></div> - <div data-bind="if: hasParticipants()"> + <div data-bind="if: hasParticipants"><div class='alert alert-info alert-block'><h3>Inactive Experiment</h3><p> @@ -143,9 +143,9 @@ model.addMessage = function (evt) { model.messages.unshift(evt.message); } - model.hasParticipants = function() { + model.hasParticipants = ko.computed(function() { return model.participantCount() > 0; - } + }); return model; } function update(experimentModel) { @@ -163,7 +163,7 @@ console.log("Received event: " + evt); experimentModel.addMessage(jQuery.parseJSON(evt.data)); }; - $('a.confirm-experiment-action').live("click", function(evt) { + $('a.confirm-experiment-action').on("click", function(evt) { evt.preventDefault(); var self = $(this); var description = self.attr("data-content"); https://bitbucket.org/virtualcommons/vcweb/commits/02c48aeec9ec/ changeset: 02c48aeec9ec user: alllee date: 2013-03-17 09:23:45 summary: adding archive functionality to experimenter affected #: 4 files diff -r 2d310d561726e6543c5dd29e5d2c4f0d621cf75f -r 02c48aeec9ec58b0d1e5c8193133494f163c0959 vcweb/core/models.py --- a/vcweb/core/models.py +++ b/vcweb/core/models.py @@ -830,6 +830,7 @@ 'participantCount': self.participant_set.count(), 'isRoundInProgress': self.is_round_in_progress, 'isActive': self.is_active, + 'isArchived': self.is_archived, 'dollarsPerToken': float(ec.exchange_rate), } if include_round_data: diff -r 2d310d561726e6543c5dd29e5d2c4f0d621cf75f -r 02c48aeec9ec58b0d1e5c8193133494f163c0959 vcweb/core/templates/experimenter/monitor.html --- a/vcweb/core/templates/experimenter/monitor.html +++ b/vcweb/core/templates/experimenter/monitor.html @@ -16,7 +16,12 @@ <li class='divider'></li></ul> {% comment %} should offer different actions (start + reset) to experiments that has already been activated / started {% endcomment %} - <div data-bind="ifnot: isActive"> + <div data-bind='if: isArchived()'> + <div class='alert alert-success'> + <i class='icon-save'></i> This experiment has been archived. + </div> + </div> + <div data-bind="ifnot: isActive() || isArchived()"><div data-bind="ifnot: hasParticipants"><div class='alert alert-error alert-block'><h4>No participants</h4> diff -r 2d310d561726e6543c5dd29e5d2c4f0d621cf75f -r 02c48aeec9ec58b0d1e5c8193133494f163c0959 vcweb/static/css/lighterprints/style.css --- a/vcweb/static/css/lighterprints/style.css +++ b/vcweb/static/css/lighterprints/style.css @@ -190,10 +190,7 @@ border-left: 1px solid #ddd; border-right: 1px solid #ddd; } -.text-gold { - color: #DFB03D; -} -.expired-challenge { +..expired-challenge { color: red; } a.upcoming-challenge, a.expired-challenge, a.perform-challenge, a.completed-challenge { diff -r 2d310d561726e6543c5dd29e5d2c4f0d621cf75f -r 02c48aeec9ec58b0d1e5c8193133494f163c0959 vcweb/static/css/style.css --- a/vcweb/static/css/style.css +++ b/vcweb/static/css/style.css @@ -107,6 +107,9 @@ width: inherit; z-index: -1; } +.text-gold { + color: #DFB03D; +} /* @font-face { font-family: Entypo; Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
|
From: <com...@bi...> - 2013-03-17 06:18:47
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/8ed7ca8671b6/ changeset: 8ed7ca8671b6 user: alllee date: 2013-03-17 07:18:29 summary: setting up complete/archive endpoints and pushing group formation logic into Experiment.start_round affected #: 3 files diff -r 5349b371047890e2740fe6e1a0e186aec3f29173 -r 8ed7ca8671b66f2ab7aa9426be2e0100cf348102 vcweb/boundaries/models.py --- a/vcweb/boundaries/models.py +++ b/vcweb/boundaries/models.py @@ -97,13 +97,6 @@ during a practice or regular round, set up resource levels and participant harvest decision parameters ''' - if round_configuration.randomize_groups: -# check if we need to preserve existing groups - if round_configuration.preserve_existing_groups: - experiment.create_new_groups() - else: - experiment.allocate_groups() - if should_reset_resource_level(round_configuration): initial_resource_level = get_initial_resource_level(round_configuration) @@ -125,7 +118,6 @@ # FIXME: max resource level might need to be read from the experiment / round configuration instead max_resource_level = MAX_RESOURCE_LEVEL for group in experiment.group_set.all(): - # FIXME: simplify logic logger.debug("group %s has resource level", group) if has_resource_level(group): current_resource_level_dv = get_resource_level_dv(group) diff -r 5349b371047890e2740fe6e1a0e186aec3f29173 -r 8ed7ca8671b66f2ab7aa9426be2e0100cf348102 vcweb/core/models.py --- a/vcweb/core/models.py +++ b/vcweb/core/models.py @@ -245,6 +245,8 @@ class ExperimentQuerySet(models.query.QuerySet): def public(self, **kwargs): return self.filter(experiment_configuration__is_public=True, **kwargs) + def completed(self, **kwargs): + return self.filter(status='COMPLETED', **kwargs) def active(self, **kwargs): return self.filter(status__in=('ACTIVE', 'ROUND_IN_PROGRESS'), **kwargs) def increment_elapsed_time(self, status='ROUND_IN_PROGRESS', amount=60): @@ -391,13 +393,18 @@ return "/%s/configure" % self.get_absolute_url() @property - def stop_url(self): - return "%s/stop" % self.controller_url + def complete_url(self): + return "%s/complete" % self.controller_url + + @property + def deactivate_url(self): + return "%s/deactivate" % self.controller_url @property def monitor_url(self): return "%s/monitor" % self.controller_url +# FIXME: deprecate and remove this, should be a POST not a GET @property def clone_url(self): return "%s/clone" % self.controller_url @@ -491,6 +498,9 @@ return self.status != 'INACTIVE' @property + def is_completed(self): + return self.status == 'COMPLETED' + @property def is_public(self): return self.experiment_configuration.is_public @@ -743,13 +753,18 @@ self.ready_participants = 0 self.save() self.log('Starting round') - # FIXME: would prefer using self.namespace as a default but django's - # managed unicode strings don't work as senders - sender = intern(self.experiment_metadata.namespace.encode('utf8')) if sender is None else sender - #sender = self.namespace.encode('utf-8') + current_round_configuration = self.current_round + if current_round_configuration.randomize_groups: + # check if we need to preserve existing groups + if round_configuration.preserve_existing_groups: + create_new_groups() + else: + allocate_groups() + if sender is None: + sender = intern(self.experiment_metadata.namespace.encode('utf8')) # notify registered game handlers logger.debug("About to send round started signal with sender %s", sender) - return signals.round_started.send_robust(sender, experiment=self, time=datetime.now(), round_configuration=self.current_round) + return signals.round_started.send_robust(sender, experiment=self, time=datetime.now(), round_configuration=current_round_configuration) def end_round(self, sender=None): self.status = 'ACTIVE' @@ -770,12 +785,12 @@ return self def complete(self): - self.log("Marking as COMPLETED") + self.log("Marking as COMPLETED") self.status = 'COMPLETED' self.save() - def stop(self): - self.log("Stopping experiment and flagging as inactive.") + def deactivate(self): + self.log("Deactivating experiment and flagging as inactive.") self.status = 'INACTIVE' self.save() diff -r 5349b371047890e2740fe6e1a0e186aec3f29173 -r 8ed7ca8671b66f2ab7aa9426be2e0100cf348102 vcweb/core/templates/experimenter/dashboard.html --- a/vcweb/core/templates/experimenter/dashboard.html +++ b/vcweb/core/templates/experimenter/dashboard.html @@ -9,9 +9,9 @@ <div class='alert alert-message'><h4>{{e.status_line}} <span class='pull-right'><span class='badge badge-important'>{{e.participant_set.count}}</span> participants</span></h4><div class='btn-group'> - <a class='btn' href='{{e.monitor_url}}'><img src='{{STATIC_URL}}images/famfamfam/zoom.png' alt='General experiment monitoring interface'/> monitor</a></li> + <a class='btn' href='{{e.monitor_url}}'><i class='icon-zoom-in'></i> monitor</a></li><a class='btn confirm-experiment-action' data-content='Creates a new copy of this experiment with the same configuration and no participants.' - href='{{e.clone_url}}'><img src='{{STATIC_URL}}images/famfamfam/page_copy.png' alt='Clone experiment'/> clone</a> + href='{{e.clone_url}}'><i class='icon-copy'></i> clone</a> {% if e.participant_set.count == 0 %} <a class='btn' data-content='Register participants for this experiment with actual email addresses' href='{{e.controller_url}}/register-email-list'><img src='{{STATIC_URL}}images/famfamfam/group_add.png' alt='register'/> register participants</a> @@ -20,10 +20,11 @@ <img src='{{STATIC_URL}}images/famfamfam/group_add.png' alt='register'/> test participants</a> {% else %} <a data-content='Remove all participants from the experiment, including any data they may have generated.' href='{{e.controller_url}}/clear-participants' class='btn confirm-experiment-action'> - <i class='icon-trash'></i>clear all participants</a></li> + <i class='icon-trash'></i> clear all participants</a></li> {% endif %} {% if e.is_active %} - <a data-content='stop this experiment' href='{{e.stop_url}}' class='btn confirm-experiment-action'><i class='icon-stop'></i>stop</a> + <a data-content='Mark this experiment as completed' href='{{e.complete_url}}' class='btn confirm-experiment-action'><i class='icon-save'></i> archive</a> + <a data-content='deactivate this experiment' href='{{e.deactivate_url}}' class='btn confirm-experiment-action'><i class='icon-off'></i> deactivate</a> {% else %} <a class='btn' data-content='Configure this experiment (sanitation)' href='{{e.configure_url}}'><i class='icon-wrench'></i>configure</a> {% endif %} Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
|
From: <com...@bi...> - 2013-03-16 09:11:02
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/5349b3710478/ changeset: 5349b3710478 user: alllee date: 2013-03-16 10:10:48 summary: filtering by ints affected #: 1 file diff -r 72ef61414b0e063ab7624a969d41de44fa4f90cc -r 5349b371047890e2740fe6e1a0e186aec3f29173 vcweb/forestry/tests.py --- a/vcweb/forestry/tests.py +++ b/vcweb/forestry/tests.py @@ -258,4 +258,4 @@ self.assertFalse(dv.float_value) e.advance_to_next_round() round_data = e.get_round_data() - self.assertEqual(10, ParticipantRoundDataValue.objects.filter(round_data=round_data).count()) + self.assertEqual(10, ParticipantRoundDataValue.objects.filter(round_data=round_data, parameter__type='int').count()) Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
|
From: <com...@bi...> - 2013-03-16 09:10:18
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/72ef61414b0e/ changeset: 72ef61414b0e user: alllee date: 2013-03-16 10:09:59 summary: fixing tests to take into account the auto-generated participant_ready parameter affected #: 3 files diff -r 6d4652654efd721d54070cf74612668b9a2dc6fc -r 72ef61414b0e063ab7624a969d41de44fa4f90cc vcweb/core/fixtures/initial_data.json --- a/vcweb/core/fixtures/initial_data.json +++ b/vcweb/core/fixtures/initial_data.json @@ -75,6 +75,24 @@ } }, { + "pk": 22, + "model": "core.parameter", + "fields": { + "experiment_metadata": null, + "display_name": "Participant is ready", + "name": "participant_ready", + "creator": 1, + "default_value_string": "", + "last_modified": "2011-12-22 13:50:08", + "date_created": "2011-12-22 13:50:08", + "scope": "participant", + "enum_choices": "", + "is_required": false, + "type": "boolean", + "description": "A chat message either broadcast to the group or targeted to a single participant" + } + }, + { "pk": 12, "model": "core.parameter", "fields": { diff -r 6d4652654efd721d54070cf74612668b9a2dc6fc -r 72ef61414b0e063ab7624a969d41de44fa4f90cc vcweb/core/tests.py --- a/vcweb/core/tests.py +++ b/vcweb/core/tests.py @@ -230,7 +230,10 @@ # instructions round current_round_data = e.current_round_data self.assertEqual(current_round_data.group_data_value_set.count(), 0) - self.assertEqual(current_round_data.participant_data_value_set.count(), 0) + if e.experiment_configuration.is_experimenter_driven: + self.assertEqual(current_round_data.participant_data_value_set.count(), e.participant_set.count()) + else: + self.assertEqual(current_round_data.participant_data_value_set.count(), 0) def test_playable_round(self): # advance_to_next_round automatically starts it diff -r 6d4652654efd721d54070cf74612668b9a2dc6fc -r 72ef61414b0e063ab7624a969d41de44fa4f90cc vcweb/forestry/tests.py --- a/vcweb/forestry/tests.py +++ b/vcweb/forestry/tests.py @@ -236,7 +236,7 @@ def test_data_values(self): e = self.create_participant_data_values() num_participant_parameters = e.parameters(scope=Parameter.PARTICIPANT_SCOPE).count() - self.assertEqual(e.participant_set.count() * num_participant_parameters, ParticipantRoundDataValue.objects.filter(round_data__experiment=e).count(), + self.assertEqual(e.participant_set.count() * num_participant_parameters, ParticipantRoundDataValue.objects.filter(round_data__experiment=e, parameter__type='int').count(), 'There should be %s participants * %s total data parameters = %s' % (e.participant_set.count(), num_participant_parameters, e.participant_set.count() * num_participant_parameters)) def test_data_value_conversion(self): @@ -245,10 +245,10 @@ for p in self.participants: participant_data_values = round_data.participant_data_value_set.filter(participant_group_relationship__participant=p) logger.debug("XXX: participant data values: %s", participant_data_values) - self.assertEqual(participant_data_values.count(), 1) + self.assertEqual(participant_data_values.count(), 2) pexpr = p.get_participant_experiment_relationship(e) logger.debug("relationship %s" % pexpr) - for dv in participant_data_values.all(): + for dv in participant_data_values.filter(parameter__type='int'): logger.debug("verifying data value %s" % dv) self.assertEqual(pexpr.sequential_participant_identifier * 2, dv.value) self.assertTrue(dv.value) Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
|
From: <com...@bi...> - 2013-03-16 08:59:57
|
2 new commits in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/f6139fd0ab7f/ changeset: f6139fd0ab7f user: alllee date: 2013-03-16 09:57:45 summary: moving is_experimenter_driven from Experiment to ExperimentConfiguration in fixtures affected #: 2 files diff -r 1fd3cdb607affad22f7b2c9cbcf69fe86ee871ca -r f6139fd0ab7f232b451432c0986f53ce30a71cc0 vcweb/broker/fixtures/broker_experiment_metadata.json --- a/vcweb/broker/fixtures/broker_experiment_metadata.json +++ b/vcweb/broker/fixtures/broker_experiment_metadata.json @@ -57,6 +57,7 @@ "last_modified": "2013-02-13T15:52:27.520", "is_public": false, "date_created": "2013-02-13T15:50:59", + "is_experimenter_driven": true, "max_group_size": 4 } }, @@ -79,7 +80,6 @@ "duration": "", "date_created": "2013-02-13T15:52:55", "experiment_configuration": 8, - "is_experimenter_driven": true, "amqp_exchange_name": "vcweb.default.exchange" } }, diff -r 1fd3cdb607affad22f7b2c9cbcf69fe86ee871ca -r f6139fd0ab7f232b451432c0986f53ce30a71cc0 vcweb/lighterprints/fixtures/lighterprints_experiment_metadata.json --- a/vcweb/lighterprints/fixtures/lighterprints_experiment_metadata.json +++ b/vcweb/lighterprints/fixtures/lighterprints_experiment_metadata.json @@ -75,7 +75,6 @@ "lighterprints" ], "experimenter": 1, - "is_experimenter_driven": false, "start_date_time": null, "status": "INACTIVE", "date_created": "2011-07-07 15:12:07", @@ -96,6 +95,7 @@ "last_modified": "2011-07-07 15:13:03", "is_public": false, "max_group_size": 20, + "is_experimenter_driven": false, "name": "Lighter Footprints Default Configuration" }, "model": "core.experimentconfiguration", https://bitbucket.org/virtualcommons/vcweb/commits/6d4652654efd/ changeset: 6d4652654efd user: alllee date: 2013-03-16 09:59:42 summary: fixing Experiment.clone affected #: 1 file diff -r f6139fd0ab7f232b451432c0986f53ce30a71cc0 -r 6d4652654efd721d54070cf74612668b9a2dc6fc vcweb/core/models.py --- a/vcweb/core/models.py +++ b/vcweb/core/models.py @@ -834,7 +834,6 @@ experiment_configuration=self.experiment_configuration, duration=self.duration, tick_duration=self.tick_duration, - is_experimenter_driven=self.is_experimenter_driven, status=Experiment.INACTIVE ) Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
|
From: <com...@bi...> - 2013-03-16 08:55:25
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/1fd3cdb607af/ changeset: 1fd3cdb607af user: alllee date: 2013-03-16 09:54:56 summary: fixing bug in get_total_storage and starting to set up boundaries round started handler next up is to work out the group formation logic and pairing of groups into GroupClusters based on the treatment type affected #: 2 files diff -r a2af4a98bf84608d3d0faae0dc3c80ff53f53169 -r 1fd3cdb607affad22f7b2c9cbcf69fe86ee871ca vcweb/boundaries/models.py --- a/vcweb/boundaries/models.py +++ b/vcweb/boundaries/models.py @@ -65,8 +65,9 @@ # returns the sum of all stored resources for each member in the group def get_total_storage(group): - # FIXME: use django queryset aggregation for this? - return sum([pdv.int_value for pdv in group.get_participant_data_values(parameter=get_storage_parameter())]) + # FIXME: int_value would be more performant but storage isn't being initialized properly yet and value returns an + # appropriate default value + return sum([pdv.value for pdv in group.get_participant_data_values(parameter=get_storage_parameter())]) def set_storage(participant_group_relationship, value=0): storage_dv = participant_group_relationship.set_data_value(parameter=get_storage_parameter(), value=value) @@ -74,15 +75,17 @@ return storage_dv def should_reset_resource_level(round_configuration): - # FIXME: stub - return True + return round_configuration.get_parameter_value(parameter=get_reset_resource_level_parameter(), default=False).boolean_value def get_last_harvest_decision(participant_group_relationship, round_data=None): return participant_group_relationship.get_data_value(parameter=get_harvest_decision_parameter(), round_data=round_data, default=0).int_value -# signal handlers -def round_setup(experiment, **kwargs): +@receiver(signals.round_started, sender=EXPERIMENT_METADATA_NAME) +def round_started_handler(sender, experiment=None, **kwargs): + if experiment is None: + logger.error("Received round started signal with no experiment: %s", sender) + raise ValueError("Received round started signal with no experiment") round_configuration = experiment.current_round logger.debug("setting up round %s", round_configuration) # initialize group and participant data values @@ -94,6 +97,14 @@ during a practice or regular round, set up resource levels and participant harvest decision parameters ''' + if round_configuration.randomize_groups: +# check if we need to preserve existing groups + if round_configuration.preserve_existing_groups: + experiment.create_new_groups() + else: + experiment.allocate_groups() + + if should_reset_resource_level(round_configuration): initial_resource_level = get_initial_resource_level(round_configuration) logger.debug("Resetting resource level for %s to %d", round_configuration, initial_resource_level) @@ -103,13 +114,14 @@ group.log("Setting resource level to initial value [%s]" % initial_resource_level) set_resource_level(group, initial_resource_level, round_data=round_data) -def round_teardown(experiment, **kwargs): +@receiver(signals.round_ended, sender=EXPERIMENT_METADATA_NAME) +def round_ended_handler(sender, experiment=None, **kwargs): ''' calculates new resource levels for practice or regular rounds based on the group harvest and resultant regrowth. also responsible for transferring those parameters to the next round as needed. ''' current_round_configuration = experiment.current_round - logger.debug("ending round: %s", current_round_configuration) + logger.debug("ending boundaries round: %s", current_round_configuration) # FIXME: max resource level might need to be read from the experiment / round configuration instead max_resource_level = MAX_RESOURCE_LEVEL for group in experiment.group_set.all(): @@ -137,12 +149,3 @@ ''' set group round data resource_level for each group + regrowth ''' group.log("Transferring resource level %s to next round" % current_resource_level_dv.int_value) group.copy_to_next_round(current_resource_level_dv) - -@receiver(signals.round_started, sender=EXPERIMENT_METADATA_NAME) -def round_started_handler(sender, experiment=None, **kwargs): - round_setup(experiment, **kwargs) - -@receiver(signals.round_ended, sender=EXPERIMENT_METADATA_NAME) -def round_ended_handler(sender, experiment=None, **kwargs): - logger.debug("ending boundaries round for %s", experiment) - round_teardown(experiment, **kwargs) diff -r a2af4a98bf84608d3d0faae0dc3c80ff53f53169 -r 1fd3cdb607affad22f7b2c9cbcf69fe86ee871ca vcweb/core/models.py --- a/vcweb/core/models.py +++ b/vcweb/core/models.py @@ -236,7 +236,7 @@ return serializers.serialize(output_format, all_objects, **kwargs) def __unicode__(self): - return u"%s configuration for the %s" % (self.name, self.experiment_metadata) + return self.name class Meta: ordering = ['experiment_metadata', 'creator', 'date_created'] @@ -675,7 +675,13 @@ logger.debug("allocating groups for %s (randomize? %s)" % (self, randomize)) # clear out all existing groups # FIXME: record previous mappings in activity log. - self.group_set.all().delete() + gs = self.group_set + if gs.count() > 0: + self.log("reallocating groups, deleting old groups") + gqs = gs.all() + for g in gqs: + self.log("reallocating group %s" % g.participant_group_relationship_set.all()) + gqs.delete() # seed the initial group. max_group_size = self.experiment_configuration.max_group_size logger.debug("creating group with max size %d", max_group_size) @@ -683,15 +689,10 @@ participants = list(self.participant_set.all()) if randomize: random.shuffle(participants) - for p in participants: pgr = self.add_participant(p, current_group) current_group = pgr.group - # XXX: if there a performance hit here, should probably do a void return instead - # or collect the groups as they are added - return self.group_set - def get_round_configuration(self, sequence_number): return RoundConfiguration.objects.get(experiment_configuration__experiment=self, sequence_number=sequence_number) @@ -994,7 +995,7 @@ return Template(template_string).substitute(kwargs, round_number=self.display_number, participant_id=participant_id) def __unicode__(self): - return u"%s (%s)" % (self.experiment_configuration, self.sequence_label) + return u"%s %s (%s)" % (self.get_round_type_display(), self.sequence_label, self.experiment_configuration) @property def display_label(self): Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
|
From: <com...@bi...> - 2013-03-16 07:52:32
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/a2af4a98bf84/ changeset: a2af4a98bf84 user: alllee date: 2013-03-16 08:52:27 summary: refactoring affected #: 6 files diff -r 79d250c1c17d2ee5ee4ff769fcca1c7a0db41d14 -r a2af4a98bf84608d3d0faae0dc3c80ff53f53169 vcweb/boundaries/views.py --- a/vcweb/boundaries/views.py +++ b/vcweb/boundaries/views.py @@ -43,7 +43,7 @@ pgr = get_object_or_404(ParticipantGroupRelationship, pk=participant_group_id) harvest_decision = form.cleaned_data['harvest_decision'] ParticipantRoundDataValue.objects.create(participant_group_relationship=pgr, int_value=harvest_decision, - round_data=experiment.get_round_data(), parameter=get_harvest_decision_parameter()) + round_data=experiment.current_round_data, parameter=get_harvest_decision_parameter()) # set harvest decision for participant # FIXME: inconsistency, GET returns HTML and POST return JSON.. return JsonResponse(dumps({ 'success': True, 'experimentModelJson': get_view_model_json(experiment, pgr)})) @@ -56,7 +56,7 @@ def get_view_model_json(experiment, participant_group_relationship, **kwargs): ec = experiment.experiment_configuration current_round = experiment.current_round - current_round_data = experiment.current_round_data(round_configuration=current_round) + current_round_data = experiment.current_round_data previous_round = experiment.previous_round previous_round_data = experiment.get_round_data(round_configuration=previous_round) diff -r 79d250c1c17d2ee5ee4ff769fcca1c7a0db41d14 -r a2af4a98bf84608d3d0faae0dc3c80ff53f53169 vcweb/broker/views.py --- a/vcweb/broker/views.py +++ b/vcweb/broker/views.py @@ -62,7 +62,7 @@ group = participant_group_relationship.group experiment_configuration = experiment.experiment_configuration round_configuration = experiment.current_round - round_data = experiment.current_round_data(round_configuration=round_configuration) + round_data = experiment.current_round_data # experiment configuration data experiment_model_dict['maxHarvestDecision'] = 10 diff -r 79d250c1c17d2ee5ee4ff769fcca1c7a0db41d14 -r a2af4a98bf84608d3d0faae0dc3c80ff53f53169 vcweb/core/models.py --- a/vcweb/core/models.py +++ b/vcweb/core/models.py @@ -429,6 +429,10 @@ self.cached_round = self.get_round_configuration(self.current_round_sequence_number) return self.cached_round + @property + def current_round_data(self): + return self.get_round_data(round_configuration=self.current_round) + # FIXME: cache this as well to avoid a query per invocation def get_round_data(self, round_configuration=None): if round_configuration is None: @@ -510,7 +514,7 @@ group__session_id=session_id) def all_participants_have_submitted(self): - return ParticipantRoundDataValue.objects.filter(submitted=False, round_data=self.get_round_data()).count() == 0 + return ParticipantRoundDataValue.objects.filter(submitted=False, round_data=self.current_round_data).count() == 0 def register_participants(self, users=None, emails=None, institution=None, password=None): if self.participant_set.count() > 0: @@ -616,7 +620,7 @@ if participant_parameters is None: participant_parameters = self.parameters(scope=Parameter.PARTICIPANT_SCOPE) if round_data is None: - round_data = self.get_round_data() + round_data = self.current_round_data for group in self.group_set.select_related('parameter').all(): for parameter in group_parameters: group_data_value, created = GroupRoundDataValue.objects.get_or_create(round_data=round_data, group=group, parameter=parameter) @@ -1298,6 +1302,10 @@ def data_parameters(self): return Parameter.objects.filter(experiment_metadata=self.experiment.experiment_metadata, scope=Parameter.GROUP_SCOPE) + @property + def current_round_data(self): + return self.experiment.get_round_data(round_configuration=self.current_round) + def get_round_data(self, round_configuration=None): return self.experiment.get_round_data(round_configuration) @@ -1325,7 +1333,7 @@ # could be a float or an int.. update_dict = { parameter.value_field_name : models.F(parameter.value_field_name) + amount } self.log("adding %s to this group's %s parameter" % (amount, parameter)) - updated_rows = self.data_value_set.filter(round_data=self.get_round_data(), parameter=parameter).update(**update_dict) + updated_rows = self.data_value_set.filter(round_data=self.current_round_data, parameter=parameter).update(**update_dict) if updated_rows != 1: logger.error("Updated %s rows, should have been only one.", updated_rows) @@ -1357,7 +1365,7 @@ def get_data_value(self, parameter=None, parameter_name=None, round_data=None, default=None): ''' returns a tuple of (scalar data value, entity DataValue). if no entity data value exists, returns (default value, None) ''' if round_data is None: - round_data = self.get_round_data() + round_data = self.current_round_data criteria = self._data_parameter_criteria(parameter=parameter, parameter_name=parameter_name, round_data=round_data) try: return self.data_value_set.select_related('parameter', 'group', 'round_data').get(**criteria) @@ -1373,7 +1381,7 @@ conversion / processing to put the value into the appropriate field. ''' if round_data is None: - round_data = self.get_round_data() + round_data = self.current_round_data self.log("setting group param %s => %s" % (parameter, value)) grdv = GroupRoundDataValue.objects.get(parameter=parameter, round_data=round_data, group=self) grdv.value = value @@ -1383,14 +1391,13 @@ def _data_parameter_criteria(self, parameter=None, parameter_name=None, round_data=None, **kwargs): criteria = dict([ ('parameter__pk', parameter.pk) if parameter else ('parameter__name', parameter_name), - ('round_data__pk', self.get_round_data().pk if round_data is None else round_data.pk) + ('round_data__pk', self.current_round_data.pk if round_data is None else round_data.pk) ]) criteria.update(kwargs) return criteria - def get_group_data_values(self, name=None, *names): - round_data = self.get_round_data() + round_data = self.current_round_data if names: if name: names.append(name) return self.data_value_set.filter(round_data=round_data, parameter__name__in=names) @@ -1656,6 +1663,10 @@ objects = PassThroughManager.for_queryset_class(ParticipantGroupRelationshipQuerySet)() + @property + def current_round_data(self): + return self.group.current_round_data + def get_round_data(self, round_configuration=None): return self.group.get_round_data(round_configuration) @@ -1683,7 +1694,7 @@ def get_data_value(self, parameter=None, round_data=None, default=None): if round_data is None: - round_data = self.get_round_data() + round_data = self.current_round_data if parameter is not None: return ParticipantRoundDataValue.objects.get(round_data=round_data, parameter=parameter, participant_group_relationship=self) @@ -1692,7 +1703,7 @@ def set_data_value(self, parameter=None, value=None, round_data=None): if round_data is None: - round_data = self.get_round_data() + round_data = self.current_round_data if parameter is not None and value is not None: pdv = ParticipantRoundDataValue.objects.get(round_data=round_data, parameter=parameter, participant_group_relationship=self) pdv.submitted = True @@ -1721,7 +1732,7 @@ class ParticipantRoundDataValue(ParameterizedValue): def __init__(self, *args, **kwargs): if 'round_data' not in kwargs and 'participant_group_relationship' in kwargs: - kwargs['round_data'] = kwargs['participant_group_relationship'].get_round_data() + kwargs['round_data'] = kwargs['participant_group_relationship'].current_round_data super(ParticipantRoundDataValue, self).__init__(*args, **kwargs) """ Represents one data point collected for a given Participant in a given Round. @@ -1795,7 +1806,7 @@ def message_all(self, experiment, message, round_data=None, **kwargs): if round_data is None: - round_data = experiment.get_round_data() + round_data = experiment.current_round_data for participant_group_relationship in ParticipantGroupRelationship.objects.for_experiment(experiment): yield ChatMessage.objects.create(participant_group_relationship=participant_group_relationship, string_value=message, diff -r 79d250c1c17d2ee5ee4ff769fcca1c7a0db41d14 -r a2af4a98bf84608d3d0faae0dc3c80ff53f53169 vcweb/core/tests.py --- a/vcweb/core/tests.py +++ b/vcweb/core/tests.py @@ -228,14 +228,14 @@ e.activate() e.start_round() # instructions round - current_round_data = e.get_round_data() + current_round_data = e.current_round_data self.assertEqual(current_round_data.group_data_value_set.count(), 0) self.assertEqual(current_round_data.participant_data_value_set.count(), 0) def test_playable_round(self): # advance_to_next_round automatically starts it e = self.advance_to_data_round() - current_round_data = e.get_round_data() + current_round_data = e.current_round_data for group in e.group_set.all(): for parameter in group.data_parameters.all(): group_data_value, created = current_round_data.group_data_value_set.get_or_create(group=group, diff -r 79d250c1c17d2ee5ee4ff769fcca1c7a0db41d14 -r a2af4a98bf84608d3d0faae0dc3c80ff53f53169 vcweb/vcweb-sockjs.py --- a/vcweb/vcweb-sockjs.py +++ b/vcweb/vcweb-sockjs.py @@ -296,7 +296,7 @@ (per, valid) = self.verify_auth_token(event) if valid: pgr = connection_manager.get_participant_group_relationship(self) - current_round_data = experiment.get_round_data() + current_round_data = experiment.current_round_data # FIXME: should chat message be created via post to Django form instead? chat_message = ChatMessage.objects.create(participant_group_relationship=pgr, string_value=event.message, diff -r 79d250c1c17d2ee5ee4ff769fcca1c7a0db41d14 -r a2af4a98bf84608d3d0faae0dc3c80ff53f53169 vcweb/vcwebio.py --- a/vcweb/vcwebio.py +++ b/vcweb/vcwebio.py @@ -236,7 +236,7 @@ event.participant_pk = participant_pk pgr_pk = event.participant_group_relationship_id participant_group_relationship = ParticipantGroupRelationship.objects.get(pk=pgr_pk) - prdv = experiment.get_round_data().participant_data_value_set.get(participant_group_relationship__pk=pgr_pk) + prdv = experiment.current_round_data.participant_data_value_set.get(participant_group_relationship__pk=pgr_pk) event.participant_data_value_pk = prdv.pk event.participant_number = participant_group_relationship.participant_number event.participant_group = participant_group_relationship.group_number @@ -253,7 +253,7 @@ elif message_type == 'chat': try: participant_group_relationship = connection_manager.get_participant_group_relationship(self) - current_round_data = participant_group_relationship.group.experiment.get_round_data() + current_round_data = participant_group_relationship.group.experiment.current_round_data chat_message = ChatMessage.objects.create(participant_group_relationship=participant_group_relationship, value=xhtml_escape(event.message), round_data=current_round_data Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
|
From: <com...@bi...> - 2013-03-15 23:08:58
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/79d250c1c17d/ changeset: 79d250c1c17d user: di...@gm... date: 2013-03-16 00:08:01 summary: updated participant and views trying to get bootstrap tour to work affected #: 2 files diff -r 2ac61e67bd736b3f0902bf390d66e17996131156 -r 79d250c1c17d2ee5ee4ff769fcca1c7a0db41d14 vcweb/broker/templates/broker/participate.html --- a/vcweb/broker/templates/broker/participate.html +++ b/vcweb/broker/templates/broker/participate.html @@ -135,6 +135,7 @@ </script> + <script type='text/html' id='GENERAL_INSTRUCTIONS'><div id='instructions1'><h4>Harvesting and Profit</h4> @@ -267,11 +268,8 @@ </ul></script> + <script type='text/html' id='PRACTICE'> - - <script type='text/html' id='INSTRUCTIONS'> - <div data-bind='html: instructions'> - </div></script> @@ -291,21 +289,10 @@ </div></div></div> - - <p> - You will have a maximum of <i class='icon-clock'></i>seconds - to make a - harvest decision each round. A countdown will alert you when there are - <span data-bind='text: warningCountdownTime'></span> seconds remaining to make a harvest choice. When the - countdown - reaches zero, any value you have selected will be submitted. <strong>The default harvest is zero.</strong> - </p> - - - + </div><!-- only show when chatOption enabled --> - <div clas="span6" data-bind="if: chatOptionEnabled"> + <div class="span6" data-bind="if: chatOptionEnabled"><div data-bind='if: isTimerRunning'><div class='alert alert-error'><b><i class='icon-time'></i> Time left:</b> @@ -313,159 +300,177 @@ </div></div><div class="span1"> - <a href="#" class="btn btn-primary" data-bind="submitChatOptionLocal"> + <a href="#" class="btn btn-primary" data-bind="submitChatOptionLocal()"><i class="icon-home icon-white"></i><span><strong>Talk within group FREE</strong></span></a></div><div class="span1"> - <a href="#" class="btn btn-primary" data-bind="submitChatOptionGlobal"> + <a href="#" class="btn btn-primary" data-bind="submitChatOptionGlobal()"><i class="icon-globe icon-white"></i><span><strong>Talk with other group $$ 2h</strong></span></a></div></div> - - <!-- The table for decision and showing payments from last round --> - <div class='span6'> - <table class="table table-hover"> - <thead> - <tr> - <th colspan="3">Round Decisions</th> - </tr> - </thead> - <tbody> - <tr> - <td class="td-1">Harvesting</td> - <td><input class="textinput" type="text" id="harvestID" name="harvest" placeholder="Placeholder"></td> - <td class="td-1"> - </table> - <p> - <table class="table" data-bind="with: chosenFolderData"> - <thead> - <tr> - <th colspan="3">Your decisions last round</th> - </tr> - </thead> - <tbody> - <tr> - <td class="td-1">Harvesting</td> - <td><strong class='text-success'><span data-bind='text:lastRoundHarvestDecision'></span><i - class='icon-leaf'></i></strong></td> - <td class="td-1"></td> - </tr> - <tr> - <td class="td-1">Conservation</td> - <td span="2"><strong class='text-success'><span id="lastRoundMyGroupConservation" data-bind='text:lastRoundMyGroupConservation'></span><i class='icon-leaf'></i></strong> - </td> - </tr> - <tr> - <td class="td-1">Global Conservation</td> - <td span="2"><strong class='text-success'><span data-bind='text:lastRoundGlobalConservation'></span><i class='icon-leaf'></i></strong> - </td> - </tr> - </table> - <p> - <table class="table" > - <thead> - <tr> - <th colspan="3">Payments from last round</th> - </tr> - </thead> - <tbody> - <tr> - <td class="td-1">from your harvesting</td> - <td><span id="lastRoundHarvestPayOff" data-bind="lastRoundHarvestPayOff"></span></td> - <td class="td-1"></td> - </tr> - <tr> - <td class="td-1">from within group bonus</td> - <td span="2"><span id="lastRoundGroupLocalBonus" data-bind="lastRoundGroupLocalBonus"></span></td> - </tr> - <tr> - <td class="td-1">from between group bonus</td> - <td span="2"><span id="lastRoundGroupGlobalBonus" data-bind="lastRoundGroupGlobalBonus"></span></td> - </tr> - </table> - - </div> - - - </div> - - <div data-bind='if: practiceRound'> - <div class='alert alert-error alert-block'> - <h4>PRACTICE ROUND</h4> - This is a practice round. The decisions you make in this round will <b>NOT</b> contribute to your - earnings. + <div data-bind='if: practiceRound'> + <div class='alert alert-error alert-block'> + <h4>PRACTICE ROUND</h4> + This is a practice round. The decisions you make in this round will <b>NOT</b> contribute to your + earnings. <span data-bind="if: isFirstPracticeRound"> - <a href="#" data-bind="">Show me 1st Instructions again</input> + <a href="#" data-bind="">Show me 1st Instructions again</a></span> - </div> - <div data-bind='style: { width: networkStructureImageWidth, height: systemImageHeight, background: networkStructureImageBackgroundUrl }'> - - </div> + </div> + <div> + Insert system image here + </div> - <div data-bind="ifnot: isTimeOut" id='resourceDisplay'> - <div class='alert alert-info'>You have <strong class='badge badge-success' - data-bind='text:hoursLeft'></strong> hours left to use today. - </div> + <div data-bind="ifnot: isTimeOut" id='resourceDisplay'> + <div class='alert alert-info'>You have <strong class='badge badge-success' + data-bind='text:maxHarvestDecision'></strong> hours + left to use + today. + </div> - </div> - <div data-bind="if: isTimeOut"> - <div style='padding: 8px; margin: auto; border: solid 1px; background: url("{{ STATIC_URL }}images/forestry/deforestation.jpg") no-repeat center; height: 282px; width:425px;'> - - </div> - <div class='alert alert-error'>You have no time left today. Please wait until the next round begins.</div> - </div> - <div data-bind='if: hasSubmit'> - <div class='alert alert-error'> - You have invested <span class='badge badge-important' data-bind='text: harvestDecision'></span> hours in - harvesting today. - You have invested <span class='badge badge-important' data-bind='text: conservationDecision'></span> - hours in conservation today. - </div> - </div> - - - <h3>Harvest</h3> - - <div data-bind='ifnot: isResourceEmpty'> - <form id='vcweb-form' action='' method='post' class='form-inline'> - {% csrf_token %} - <div class='control-group'> - <div class='controls'> - <input id='participantGroupId' type='hidden' name='participant_group_id' - data-bind='value: participantGroupId'/> - <input id='harvestDecision' type="number" size="1" maxlength="1" name='harvest_decision' - class='required' min="0" - data-bind="value: harvestDecision, attr: { max: maxHarvestDecision }"/> - <input id='conservationDecision' type="number" size="1" maxlength="1" - name='conservation_decision' class='disabled' min="0" - data-bind="value: conservationDecision, attr: { max: maxConservationDecision }"/> - - <button id='submitDecision' data-bind='click: submitDecision' type='submit' class='btn'> - Harvest - </button> + </div> + <div data-bind="if: isTimeOut"> + <div style='padding: 8px; margin: auto; border: solid 1px; background: url("{{ STATIC_URL }}images/broker/SES.jpg") no-repeat center; height: 282px; width:425px;'> + + </div> + <div class='alert alert-error'>You have no time left today. Please wait until the next round begins. </div></div> - </form> - </div> + <div data-bind='if: hasSubmit'> + <div class='alert alert-error'> + You have invested <span class='badge badge-important' data-bind='text: harvestDecision'></span> + hours in + harvesting today. + You have invested <span class='badge badge-important' + data-bind='text: conservationDecision'></span> + hours in conservation today. + </div> + </div> + + <!-- The table for decision and showing payments from last round --> + <div class='span6'> + <form id='vcweb-form' action='' method='post' class='form-inline'> + {% csrf_token %} + <table class="table table-hover"> + <thead> + <tr> + <th colspan="3">Round Decisions</th> + </tr> + </thead> + <tbody> + <tr> + <td class="td-1">Harvesting</td> + <td> + <div> + <div class='control-group'> + <div class='controls'> + <input id='participantGroupId' type='hidden' name='participant_group_id'/> + <input id='harvestDecisionId' type="number" size="1" maxlength="1" + name='harvest_decision' + class='required' min="0" + data-bind="value: harvestDecision, attr: { max: maxHarvestDecision }"/> + + <button id='submitDecision' data-bind='click: submitDecision' + type='submit' class='btn'> + Harvest + </button> + </div> + </div> + + </div> + </tr> + <tr> + <td class="td-1">Conservation</td> + <td> + <div> + + <div class='controls'> + <input id='conservationDecision' type="number" size="1" maxlength="1" + name='conservation_decision' class='disabled' min="0" + data-bind="value: conservationDecision"/> + </div> + + + </div> + </tr> + </table> + </form> + <p></p> + <table class="table"> + <thead> + <tr> + <th colspan="3">Your decisions last round</th> + </tr> + </thead> + <tbody> + <tr> + <td class="td-1">Harvesting</td> + <td><strong class='text-success'><span data-bind='text:lastRoundHarvestDecision'></span><i + class='icon-leaf'></i></strong></td> + <td class="td-1"></td> + </tr> + <tr> + <td class="td-1">Conservation</td> + <td span="2"><strong class='text-success'><span id="lastRoundMyGroupConservation" + data-bind='text:lastRoundMyGroupConservation'></span> + <i class='icon-leaf'></i></strong> + </td> + </tr> + <tr> + <td class="td-1">Global Conservation</td> + <td span="2"><strong class='text-success'><span + data-bind='text:lastRoundGlobalConservation'></span><i + class='icon-leaf'></i></strong> + </td> + </tr> + </table> + <p> + <table class="table"> + <thead> + <tr> + <th colspan="3">Payments from last round</th> + </tr> + </thead> + <tbody> + <tr> + <td class="td-1">from your harvesting</td> + <td><span id="lastRoundHarvestPayOff" data-bind="text: lastRoundHarvestPayOff"></span></td> + <td class="td-1"></td> + </tr> + <tr> + <td class="td-1">from within group bonus</td> + <td span="2"><span id="lastRoundGroupLocalBonus" + data-bind="text: lastRoundGroupLocalBonus"></span> + </td> + </tr> + <tr> + <td class="td-1">from between group bonus</td> + <td span="2"><span id="lastRoundGroupGlobalBonus" + data-bind="text: lastRoundGroupGlobalBonus"></span> + </td> + </tr> + </table> + + + </div> + + </script> - - - - - <script type="text/javascript"> + var tour; $(function () { function ExperimentModel(experimentModelJson) { var self = this; var model = ko.mapping.fromJS(experimentModelJson); - + model.isTimeOut = ko.observable(0) + model.hasSubmit = ko.observable(0) model.secondsLeft = ko.observable(0); model.currentInterval = ko.observable(); model.setCurrentInterval = function (intervalId) { @@ -496,17 +501,17 @@ }; model.update = function () { $.get('view-model', { participant_group_id: {{ participant_group_relationship.pk }}, }, - function (response) { - console.debug("updating with response: "); - console.debug(response); - ko.mapping.fromJS(response, model); - if (model.isFirstPracticeRound()) { - model.setupFirstPracticeRoundTour(); - } - else if (model.isSecondPracticeRound()) { - model.setupSecondPracticeRoundTour(); - } - }); + function (response) { + console.debug("updating with response: "); + console.debug(response); + ko.mapping.fromJS(response, model); + if (model.isFirstPracticeRound()) { + model.setupFirstPracticeRoundTour(); + } + else if (model.isSecondPracticeRound()) { + model.setupSecondPracticeRoundTour(); + } + }); }; model.templateName = ko.observable("WELCOME"); // activate instructions click bindings @@ -536,17 +541,18 @@ model.networkStructureImageWidth = ko.observable("600px"); model.networkStructureImageHeight = ko.observable("80px"); model.finishedInstructions = function () { - console.debug("instructions were finished, notifying experimenter"); - $.post('/experiment/participant-ready', { participant_group_id: {{ participant_group_relationship.pk }} }, function(response) { + {% comment %}console.debug("instructions were finished, notifying experimenter"); + $.post('/experiment/participant-ready', { participant_group_id: {{ participant_group_relationship.pk }} }, function (response) { console.debug("successfully posted to server, notifying sockjs: " + response); - getWebSocket().send(createMessageEvent("Instructions completed", "client_ready")); - }); + getWebSocket().send(createMessageEvent("Instructions completed", "client_ready"));{% endcomment %} + model.templateName("PRACTICE"); + } model.chatEnabled = ko.observable(false); // round configurations model.chatOptionEnabled = ko.observable(false); // round configurations model.harvestDecision = ko.observable(0); model.conservationDecision = ko.computed(function () { - return model.maxHarvestDecision - model.harvestDecision + return model.conservationDecision == model.maxHarvestDecision() - model.harvestDecision(); }); // model.numberOfTreesPerRow = ko.observable(10); // model.isResourceEmpty = ko.computed(function() { @@ -565,37 +571,37 @@ model.secondsLeft(60); model.setCurrentInterval( setInterval(function () { - model.tick(); - if (!model.isTimerRunning()) { - model.disableChat(); - model.clearCurrentInterval(); - } - }, - 1000)); + model.tick(); + if (!model.isTimerRunning()) { + model.disableChat(); + model.clearCurrentInterval(); + } + }, + 1000)); }; model.startHarvestDecisionTimer = function () { model.secondsLeft(10); model.setCurrentInterval(setInterval(function () { - model.tick(); - if (!model.isTimerRunning()) { - model.submitDecision(); - model.clearCurrentInterval(); - } - }, - 1000)); + model.tick(); + if (!model.isTimerRunning()) { + model.submitDecision(); + model.clearCurrentInterval(); + } + }, + 1000)); }; model.startChatOptionTimer = function () { model.enableChatOption(); model.secondsLeft(10); model.setCurrentInterval( setInterval(function () { - model.tick(); - if (!model.isTimerRunning()) { - model.disableChatOption(); - model.clearCurrentInterval(); - } - }, - 1000)); + model.tick(); + if (!model.isTimerRunning()) { + model.disableChatOption(); + model.clearCurrentInterval(); + } + }, + 1000)); }; // model.submitDecision = function(data, evt) { // if (evt) { @@ -676,90 +682,91 @@ if (templateName === "PRACTICE") { templateName = "REGULAR"; experimentModel.practiceRound(true); - if (isFirstPracticeRound){ + if (experimentModel.isFirstPracticeRound) { + console.debug("starting first practice round tour"); + var tourFirst = new Tour({ - onEnd: function (tourFirst) { - // send player to next practice round where isSecondPracticeRound = TRUE and EnabledChatOption=TRUE + useLocalStorage: true + }); + tourFirst.addStep({ + element: "harvestDecisionId", + title: "Here's where you insert your harvesting decision", + content: "For this practice round, go ahead and put 6 hours into harvesting. Each round you will have a maximum of 6 minute to make a harvest decision.", /* content of the popover */ + placement: "right" + }); + tourFirst.addStep({ + element: "conservationDecision", + title: "Your conservation decision", + content: "Note that the rest of your available hours will be put into conservation.", + placement: "right" + }); + tourFirst.addStep({ + element: "submitDecision", + title: "Submit your decision", + content: "Now click here to submit your harvest choice. Your choice will be submitted automatically when time is up. A countdown will alert you when there are 10 seconds remaining to make a harvest. The default harvest is zero.", /* content of the popover */ + placement: "right" + }); + tourFirst.start(true); + tour = tourFirst; + console.debug("tour started"); - }, - }); - tourFirst.addStep({ - element: "harvestDecision", - title: "Here's where you insert your harvesting decision", - content: "For this practice round, go ahead and put 6 hours into harvesting. Each round you will have a maximum of <span data-bind='text: roundDuration'></span> minute to make a harvest decision." /* content of the popover */ - placement:"right" - }); - tourFirst.addStep({ - element: "conservationDecision", - title: "Your conservation decision", - content: "Note that the rest of your available hours will be put into conservation." - placement:"right" - }); - tourFirst.addStep({ - element: "submitDecision", - title: "Submit your decision", - content: "Now click here to submit your harvest choice. Your choice will be submitted automatically when time is up. A countdown will alert you when there are 10 seconds remaining to make a harvest. The default harvest is zero." /* content of the popover */ - placement:"right" - }); - tourFirst.addStep({ - element: "lastRoundHarvestPayOff", - title: "Your round earnings", - content: "Here you will see how much you earned in each round. You receive 0.6 from harvesting. Because everyone contributed 4 hours to conservation, resulting in 8 hours for group A and 8 hours for group B." - placement:"right" - }); - tourFirst.addStep({ - element: "lastRoundGroupLocalBonus", - title: "Bonus", - content: "So the standard revenue of $0.10/hour has been increased by 50% you receive an extra $0.30 and your total is $0.90. If the sum within your group was less than 5 hours you would not receive benefits. " - placement:"right" - }); - tourFirst.addStep({ - element: "lastRoundMyGroupConservation", - title: "Bonus", - content: "If the sum of conservation time of all players were more than 22 hours you would get a further increase of 50% in the revenues." - placement:"right" - }); - tourFirst.addStep({ - element: "totalEarning", - title: "Total Earning", - content: "Here you can your total earning throughout the game" - placement:"right" - }); - tourFirst.start(); - } else if (isSecondPracticeRound) { + } else if (experimentModel.isSecondPracticeRound) { var tourSecond = new Tour(); + alert("second tour"); tourSecond.addStep({ - element: "", - title: "Communication", - content: "At some point during the game you will have the option of communicating to other players. Communication to the other player within your group is FREE. Communication with the other group costs 2 hours." - }); + element: "lastRoundHarvestPayOff", + title: "Your round earnings", + content: "Here you will see how much you earned in each round. You receive 0.6 from harvesting. Because everyone contributed 4 hours to conservation, resulting in 8 hours for group A and 8 hours for group B.", + placement: "right" + }); tourSecond.addStep({ - element: "", - title: "", - content: "For this practice, go ahead and choose 'Communication within Group' and 'Communication with other Group'" - }); + element: "lastRoundGroupLocalBonus", + title: "Bonus", + content: "So the standard revenue of $0.10/hour has been increased by 50% you receive an extra $0.30 and your total is $0.90. If the sum within your group was less than 5 hours you would not receive benefits. ", + placement: "right" + }); tourSecond.addStep({ - element: "", - title: "Chat rooms", - content: "Communication will happen through these chat windows. Communications is time bound. Each message you send will be targeted a single player. Go ahead and send a message. It will not be seen by others for this practice." - onHide: function (tourSecond) { - // post a dummy message to the chat... "Here's an example of a reply message" - } + element: "lastRoundMyGroupConservation", + title: "Bonus", + content: "If the sum of conservation time of all players were more than 22 hours you would get a further increase of 50% in the revenues.", + placement: "right" + }); + tourSecond.addStep({ + element: "totalEarning", + title: "Total Earning", + content: "Here you can your total earning throughout the game", + placement: "right" + }); - }); tourSecond.addStep({ - element: "", - title: "Chat rooms", - content: "Remember that all your choices are independent and none will see what your decisions are." - }); + element: "totalEarning", + title: "Communication", + content: "At some point during the game you will have the option of communicating to other players. Communication to the other player within your group is FREE. Communication with the other group costs 2 hours.", + }); + tourSecond.addStep({ + element: "totalEarning", + title: "", + content: "For this practice, go ahead and choose 'Communication within Group' and 'Communication with other Group'", + + }); + tourSecond.addStep({ + element: "totalEarning", + title: "Chat rooms", + content: "Communication will happen through these chat windows. Communications is time bound. Each message you send will be targeted a single player. Go ahead and send a message. It will not be seen by others for this practice.", + onHide: function (tourSecond) { + // post a dummy message to the chat... "Here's an example of a reply message" + } + + }); + tourSecond.addStep({ + element: "totalEarning", + title: "Chat rooms", + content: "Remember that all your choices are independent and none will see what your decisions are.", + }); tourSecond.start(); - - - - } } else if (templateName === "REGULAR") { diff -r 2ac61e67bd736b3f0902bf390d66e17996131156 -r 79d250c1c17d2ee5ee4ff769fcca1c7a0db41d14 vcweb/broker/views.py --- a/vcweb/broker/views.py +++ b/vcweb/broker/views.py @@ -69,18 +69,25 @@ experiment_model_dict['maxEarnings'] = 20.00 experiment_model_dict['localBonus'] = experiment_configuration.get_parameter_value(name='local_bonus', default=50).int_value experiment_model_dict['globalBonus'] = experiment_configuration.get_parameter_value(name='global_bonus', default=50).int_value + # round configuration data experiment_model_dict['chatEnabled'] = True experiment_model_dict['roundDuration'] = 10 experiment_model_dict['networkStructure'] = 10 practice_round = round_configuration.is_practice_round experiment_model_dict['practiceRound'] = practice_round - if practice_round and round_configuration.sequence_number == 2: + + if practice_round and round_configuration.sequence_number == 3: experiment_model_dict['isFirstPracticeRound'] = True experiment_model_dict['isSecondPracticeRound'] = False - elif practice_round and round_configuration.sequence_number == 3: + elif practice_round and round_configuration.sequence_number == 4: experiment_model_dict['isFirstPracticeRound'] = False experiment_model_dict['isSecondPracticeRound'] = True + else: + experiment_model_dict['isFirstPracticeRound'] = False + experiment_model_dict['isSecondPracticeRound'] = False + + experiment_model_dict['networkStructureImageBackgroundUrl'] = "{{ STATIC_URL }}images/broker/SES.jpg" # round data @@ -92,12 +99,11 @@ # data from the last round experiment_model_dict['lastRoundHarvestDecision'] = 5 - experiment_model_dict['lastRoundGroupAConservation'] = 10 - experiment_model_dict['lastRoundGroupBConservation'] = 10 + experiment_model_dict['lastRoundMyGroupConservation'] = 10 + experiment_model_dict['lastRoundGlobalConservation'] = 10 experiment_model_dict['lastRoundGroupLocalBonus'] = 10 experiment_model_dict['lastRoundGroupGlobalBonus'] = 10 experiment_model_dict['lastRoundHarvestPayOff'] = 5 - experiment_model_dict['totalEarning'] = 100 number_of_connected_groups = round_configuration.get_parameter_value(name='number_of_connected_groups', default=2).int_value experiment_model_dict['participantsPerSubGroup'] = group.max_size Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
|
From: <com...@bi...> - 2013-03-15 22:30:48
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/2ac61e67bd73/ changeset: 2ac61e67bd73 user: alllee date: 2013-03-15 23:30:35 summary: schema refactoring, moving is_experimenter_driven to ExperimentConfiguration from Experiment is_experimenter_driven now determines whether or not we auto-add participant_ready participant group relationship data values to each RoundData object at RoundData creation time (when the round is started) renaming Experiment.current_round_data to get_round_data adding last harvest decision lookup to boundaries affected #: 19 files diff -r 0050f5045e29e1c8502ddf2baa99ca7a1608fc02 -r 2ac61e67bd736b3f0902bf390d66e17996131156 vcweb/boundaries/models.py --- a/vcweb/boundaries/models.py +++ b/vcweb/boundaries/models.py @@ -66,8 +66,7 @@ # returns the sum of all stored resources for each member in the group def get_total_storage(group): # FIXME: use django queryset aggregation for this? - return sum([pdv.value for pdv in group.get_participant_data_values(parameter=get_storage_parameter())]) - + return sum([pdv.int_value for pdv in group.get_participant_data_values(parameter=get_storage_parameter())]) def set_storage(participant_group_relationship, value=0): storage_dv = participant_group_relationship.set_data_value(parameter=get_storage_parameter(), value=value) @@ -75,8 +74,13 @@ return storage_dv def should_reset_resource_level(round_configuration): + # FIXME: stub return True +def get_last_harvest_decision(participant_group_relationship, round_data=None): + return participant_group_relationship.get_data_value(parameter=get_harvest_decision_parameter(), + round_data=round_data, default=0).int_value + # signal handlers def round_setup(experiment, **kwargs): round_configuration = experiment.current_round @@ -93,7 +97,7 @@ if should_reset_resource_level(round_configuration): initial_resource_level = get_initial_resource_level(round_configuration) logger.debug("Resetting resource level for %s to %d", round_configuration, initial_resource_level) - round_data = experiment.current_round_data(round_configuration) + round_data = experiment.get_round_data(round_configuration) for group in experiment.group_set.all(): ''' set resource level to initial default ''' group.log("Setting resource level to initial value [%s]" % initial_resource_level) @@ -142,7 +146,3 @@ def round_ended_handler(sender, experiment=None, **kwargs): logger.debug("ending boundaries round for %s", experiment) round_teardown(experiment, **kwargs) - - - - diff -r 0050f5045e29e1c8502ddf2baa99ca7a1608fc02 -r 2ac61e67bd736b3f0902bf390d66e17996131156 vcweb/boundaries/templates/boundaries/participate.html --- a/vcweb/boundaries/templates/boundaries/participate.html +++ b/vcweb/boundaries/templates/boundaries/participate.html @@ -430,7 +430,7 @@ }) model.resourcesToDisplay = ko.computed(function() { if (model.resourceLevel() > 0) { - return Math.min(model.resourceLevel(), 20); + return Math.min(model.resourceLevel(), model.maximumResourcesToDisplay()); } return 0; }); diff -r 0050f5045e29e1c8502ddf2baa99ca7a1608fc02 -r 2ac61e67bd736b3f0902bf390d66e17996131156 vcweb/boundaries/views.py --- a/vcweb/boundaries/views.py +++ b/vcweb/boundaries/views.py @@ -8,7 +8,8 @@ ParticipantExperimentRelationship, ChatMessage, ParticipantRoundDataValue) from vcweb.boundaries.forms import HarvestDecisionForm from vcweb.boundaries.models import (get_experiment_metadata, get_regrowth_rate, get_harvest_decision_parameter, - get_cost_of_living, get_resource_level, get_initial_resource_level, get_total_storage, get_storage) + get_cost_of_living, get_resource_level, get_initial_resource_level, get_total_storage, get_storage, + get_last_harvest_decision) import logging import random @@ -19,11 +20,7 @@ participant = request.user.participant logger.debug("handling participate request for %s and experiment %s", participant, experiment_id) experiment = get_object_or_404(Experiment.objects.select_related('experiment_metadata', 'experiment_configuration').prefetch_related('group_set', 'experiment_configuration__round_configuration_set'), pk=experiment_id) - per = get_object_or_404(ParticipantExperimentRelationship.objects.select_related('participant'), - experiment=experiment, participant=participant) - pgr = get_object_or_404(ParticipantGroupRelationship.objects.select_related('group', 'participant__user').prefetch_related('group__participant_group_relationship_set'), - group__experiment=experiment, - participant=participant) + pgr = experiment.get_participant_group_relationship(participant) if experiment.experiment_metadata != get_experiment_metadata() or pgr.participant != request.user.participant: raise Http404 @@ -32,7 +29,6 @@ 'auth_token': participant.authentication_token, 'experiment': experiment, 'participant_group_relationship': pgr, - 'participant_experiment_relationship': per, 'experimentModelJson': get_view_model_json(experiment, pgr), }, context_instance=RequestContext(request)) @@ -47,7 +43,7 @@ pgr = get_object_or_404(ParticipantGroupRelationship, pk=participant_group_id) harvest_decision = form.cleaned_data['harvest_decision'] ParticipantRoundDataValue.objects.create(participant_group_relationship=pgr, int_value=harvest_decision, - round_data=experiment.current_round_data(), parameter=get_harvest_decision_parameter()) + round_data=experiment.get_round_data(), parameter=get_harvest_decision_parameter()) # set harvest decision for participant # FIXME: inconsistency, GET returns HTML and POST return JSON.. return JsonResponse(dumps({ 'success': True, 'experimentModelJson': get_view_model_json(experiment, pgr)})) @@ -60,7 +56,10 @@ def get_view_model_json(experiment, participant_group_relationship, **kwargs): ec = experiment.experiment_configuration current_round = experiment.current_round - current_round_data = experiment.current_round_data + current_round_data = experiment.current_round_data(round_configuration=current_round) + previous_round = experiment.previous_round + previous_round_data = experiment.get_round_data(round_configuration=previous_round) + experiment_model_dict = experiment.as_dict(include_round_data=False, attrs={}) group_data = [] player_data = [] @@ -68,6 +67,26 @@ cost_of_living = get_cost_of_living(current_round) own_group = participant_group_relationship.group own_resource_level = 0 + for pgr in own_group.participant_group_relationship_set.all(): + player_data.append({ + 'id': pgr.participant_number, + # FIXME: replace with lookup of last harvest decision, if it exists + 'lastHarvestDecision': get_last_harvest_decision(pgr, round_data=previous_round_data), + 'storage': get_storage(pgr, current_round_data), + }) + experiment_model_dict['playerData'] = player_data + + experiment_model_dict['chatMessages'] = [ + { 'pk': cm.pk, + 'participant_number': cm.participant_group_relationship.participant_number, + 'message': cm.string_value, + 'date_created': cm.date_created.strftime("%I:%M:%S") + } + for cm in ChatMessage.objects.for_group(own_group) + ] + experiment_model_dict['initialResourceLevel'] = get_initial_resource_level(current_round) + experiment_model_dict['groupData'] = group_data +# FIXME: replace with group cluster lookups for group in experiment.group_set.all(): resource_level = get_resource_level(group) if group == own_group: @@ -79,31 +98,12 @@ 'regrowthRate': regrowth_rate, 'costOfLiving': cost_of_living, }) - - for pgr in own_group.participant_group_relationship_set.all(): - player_data.append({ - 'id': pgr.participant_number, - 'lastHarvestDecision': random.randint(0, 10), - 'storage': get_storage(pgr, current_round_data), - }) - - experiment_model_dict['chatMessages'] = [ - { 'pk': cm.pk, - 'participant_number': cm.participant_group_relationship.participant_number, - 'message': cm.string_value, - 'date_created': cm.date_created.strftime("%I:%M:%S") - } - for cm in ChatMessage.objects.for_group(own_group) - ] - experiment_model_dict['initialResourceLevel'] = get_initial_resource_level(current_round) - experiment_model_dict['groupData'] = group_data experiment_model_dict['otherGroupResourceLevel'] = random.randint(50, 100) experiment_model_dict['otherGroupAverageHarvest'] = random.uniform(0, 10) experiment_model_dict['otherGroupAverageStorage'] = random.uniform(10, 30) - experiment_model_dict['playerData'] = player_data +# round / experiment configuration data experiment_model_dict['participantsPerGroup'] = ec.max_group_size - experiment_model_dict['numberOfRounds'] = ec.final_sequence_number experiment_model_dict['roundType'] = current_round.round_type experiment_model_dict['regrowthRate'] = regrowth_rate experiment_model_dict['costOfLiving'] = cost_of_living diff -r 0050f5045e29e1c8502ddf2baa99ca7a1608fc02 -r 2ac61e67bd736b3f0902bf390d66e17996131156 vcweb/broker/views.py --- a/vcweb/broker/views.py +++ b/vcweb/broker/views.py @@ -25,7 +25,7 @@ pgr = get_object_or_404(ParticipantGroupRelationship, pk=participant_group_id) harvest_hours = form.cleaned_data['integer_decision'] conservation_hours = get_max_harvest_hours(experiment) - harvest_hours - round_data = experiment.current_round_data() + round_data = experiment.get_round_data() ParticipantRoundDataValue.objects.create(participant_group_relationship=pgr, int_value=harvest_hours, round_data=round_data, parameter=get_harvest_decision_parameter()) pgr.participant_data_value_set.create(int_value=conservation_hours, round_data=round_data, diff -r 0050f5045e29e1c8502ddf2baa99ca7a1608fc02 -r 2ac61e67bd736b3f0902bf390d66e17996131156 vcweb/core/migrations/0023_auto__del_field_experiment_is_experimenter_driven__add_field_experimen.py --- /dev/null +++ b/vcweb/core/migrations/0023_auto__del_field_experiment_is_experimenter_driven__add_field_experimen.py @@ -0,0 +1,405 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Deleting field 'Experiment.is_experimenter_driven' + db.delete_column(u'core_experiment', 'is_experimenter_driven') + + # Adding field 'ExperimentConfiguration.is_experimenter_driven' + db.add_column(u'core_experimentconfiguration', 'is_experimenter_driven', + self.gf('django.db.models.fields.BooleanField')(default=True), + keep_default=False) + + + def backwards(self, orm): + # Adding field 'Experiment.is_experimenter_driven' + db.add_column(u'core_experiment', 'is_experimenter_driven', + self.gf('django.db.models.fields.BooleanField')(default=True), + keep_default=False) + + # Deleting field 'ExperimentConfiguration.is_experimenter_driven' + db.delete_column(u'core_experimentconfiguration', 'is_experimenter_driven') + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'auth.user': { + 'Meta': {'object_name': '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': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + '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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'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'}) + }, + u'core.activitylog': { + 'Meta': {'object_name': 'ActivityLog'}, + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'log_message': ('django.db.models.fields.TextField', [], {}) + }, + u'core.address': { + 'Meta': {'object_name': 'Address'}, + 'city': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'state': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), + 'street1': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'street2': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'zipcode': ('django.db.models.fields.CharField', [], {'max_length': '8', 'blank': 'True'}) + }, + u'core.chatmessage': { + 'Meta': {'ordering': "['date_created']", 'object_name': 'ChatMessage', '_ormbases': [u'core.ParticipantRoundDataValue']}, + u'participantrounddatavalue_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ParticipantRoundDataValue']", 'unique': 'True', 'primary_key': 'True'}), + 'target_participant': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'target_participant_chat_message_set'", 'null': 'True', 'to': u"orm['core.ParticipantGroupRelationship']"}) + }, + u'core.comment': { + 'Meta': {'ordering': "['date_created']", 'object_name': 'Comment', '_ormbases': [u'core.ParticipantRoundDataValue']}, + u'participantrounddatavalue_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ParticipantRoundDataValue']", 'unique': 'True', 'primary_key': 'True'}) + }, + u'core.experiment': { + 'Meta': {'ordering': "['date_created', 'status']", 'object_name': 'Experiment'}, + 'amqp_exchange_name': ('django.db.models.fields.CharField', [], {'default': "'vcweb.default.exchange'", 'max_length': '64'}), + 'authentication_code': ('django.db.models.fields.CharField', [], {'default': "'vcweb.auth.code'", 'max_length': '32'}), + 'current_round_elapsed_time': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'current_round_sequence_number': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}), + 'current_round_start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'duration': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), + 'experiment_configuration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentConfiguration']"}), + 'experiment_metadata': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentMetadata']"}), + 'experimenter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Experimenter']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'ready_participants': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'start_date_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'INACTIVE'", 'max_length': '32'}), + 'tick_duration': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), + 'total_elapsed_time': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}) + }, + u'core.experimentactivitylog': { + 'Meta': {'object_name': 'ExperimentActivityLog', '_ormbases': [u'core.ActivityLog']}, + u'activitylog_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ActivityLog']", 'unique': 'True', 'primary_key': 'True'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'activity_log_set'", 'to': u"orm['core.Experiment']"}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.experimentconfiguration': { + 'Meta': {'ordering': "['experiment_metadata', 'creator', 'date_created']", 'object_name': 'ExperimentConfiguration'}, + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_configuration_set'", 'to': u"orm['core.Experimenter']"}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'exchange_rate': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '6', 'decimal_places': '2', 'blank': 'True'}), + 'experiment_metadata': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_configuration_set'", 'to': u"orm['core.ExperimentMetadata']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invitation_subject': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'invitation_text': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'is_experimenter_driven': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'max_group_size': ('django.db.models.fields.PositiveIntegerField', [], {'default': '5'}), + 'max_number_of_participants': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'treatment_id': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}) + }, + u'core.experimenter': { + 'Meta': {'ordering': "['user']", 'object_name': 'Experimenter'}, + 'approved': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'authentication_token': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'failed_password_attempts': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'institution': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Institution']", 'null': 'True', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'experimenter'", 'unique': 'True', 'to': u"orm['auth.User']"}) + }, + u'core.experimenterrequest': { + 'Meta': {'object_name': 'ExperimenterRequest'}, + 'approved': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['auth.User']", 'unique': 'True'}) + }, + u'core.experimentmetadata': { + 'Meta': {'ordering': "['namespace', 'date_created']", 'object_name': 'ExperimentMetadata'}, + 'about_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'default_configuration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentConfiguration']", 'null': 'True', 'blank': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'logo_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'namespace': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'short_name': ('django.db.models.fields.SlugField', [], {'max_length': '32', 'unique': 'True', 'null': 'True', 'blank': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + u'core.experimentparametervalue': { + 'Meta': {'object_name': 'ExperimentParameterValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'experiment_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_parameter_value_set'", 'to': u"orm['core.ExperimentConfiguration']"}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + u'core.experimentsession': { + 'Meta': {'object_name': 'ExperimentSession'}, + 'capacity': ('django.db.models.fields.PositiveIntegerField', [], {'default': '20'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_session_set'", 'to': u"orm['auth.User']"}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'experiment_metadata': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_session_set'", 'to': u"orm['core.ExperimentMetadata']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invitation_text': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'scheduled_date': ('django.db.models.fields.DateTimeField', [], {}), + 'scheduled_end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}) + }, + u'core.group': { + 'Meta': {'ordering': "['experiment', 'number']", 'object_name': 'Group'}, + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Experiment']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'max_size': ('django.db.models.fields.PositiveIntegerField', [], {'default': '5'}), + 'number': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'session_id': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}) + }, + u'core.groupactivitylog': { + 'Meta': {'object_name': 'GroupActivityLog', '_ormbases': [u'core.ActivityLog']}, + u'activitylog_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ActivityLog']", 'unique': 'True', 'primary_key': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'activity_log_set'", 'to': u"orm['core.Group']"}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.groupcluster': { + 'Meta': {'ordering': "['date_created']", 'object_name': 'GroupCluster'}, + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Experiment']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'session_id': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}) + }, + u'core.groupclusterdatavalue': { + 'Meta': {'object_name': 'GroupClusterDataValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + 'group_cluster': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.GroupCluster']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'round_data': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'group_cluster_data_value_set'", 'to': u"orm['core.RoundData']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + u'core.grouprelationship': { + 'Meta': {'ordering': "['date_created']", 'object_name': 'GroupRelationship'}, + 'cluster': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'group_set'", 'to': u"orm['core.GroupCluster']"}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + u'core.grouprounddatavalue': { + 'Meta': {'ordering': "['round_data', 'group', 'parameter']", 'object_name': 'GroupRoundDataValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'data_value_set'", 'to': u"orm['core.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'round_data': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'group_data_value_set'", 'to': u"orm['core.RoundData']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + u'core.institution': { + 'Meta': {'object_name': 'Institution'}, + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}) + }, + u'core.invitation': { + 'Meta': {'object_name': 'Invitation'}, + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'experiment_session': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentSession']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'participant': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Participant']"}), + 'sender': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}) + }, + u'core.like': { + 'Meta': {'ordering': "['-date_created', 'round_data', 'participant_group_relationship', 'parameter']", 'object_name': 'Like', '_ormbases': [u'core.ParticipantRoundDataValue']}, + u'participantrounddatavalue_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ParticipantRoundDataValue']", 'unique': 'True', 'primary_key': 'True'}) + }, + u'core.parameter': { + 'Meta': {'ordering': "['name']", 'unique_together': "(('name', 'experiment_metadata', 'scope'),)", 'object_name': 'Parameter'}, + 'class_name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Experimenter']"}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'default_value_string': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'description': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'}), + 'display_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'enum_choices': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'experiment_metadata': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentMetadata']", 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_required': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'scope': ('django.db.models.fields.CharField', [], {'default': "'round'", 'max_length': '32'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '32'}) + }, + u'core.participant': { + 'Meta': {'ordering': "['user']", 'object_name': 'Participant'}, + 'address': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Address']", 'null': 'True', 'blank': 'True'}), + 'authentication_token': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'birthdate': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'can_receive_invitations': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'experiments': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'participant_set'", 'symmetrical': 'False', 'through': u"orm['core.ParticipantExperimentRelationship']", 'to': u"orm['core.Experiment']"}), + 'failed_password_attempts': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'gender': ('django.db.models.fields.CharField', [], {'max_length': '1', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'participant_set'", 'symmetrical': 'False', 'through': u"orm['core.ParticipantGroupRelationship']", 'to': u"orm['core.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'institution': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Institution']", 'null': 'True', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'participant'", 'unique': 'True', 'to': u"orm['auth.User']"}) + }, + u'core.participantexperimentrelationship': { + 'Meta': {'object_name': 'ParticipantExperimentRelationship'}, + 'additional_data': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}), + 'current_location': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'participant_relationship_set'", 'to': u"orm['core.Experiment']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_completed_round_sequence_number': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'participant': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_relationship_set'", 'to': u"orm['core.Participant']"}), + 'participant_identifier': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'sequential_participant_identifier': ('django.db.models.fields.PositiveIntegerField', [], {}) + }, + u'core.participantgrouprelationship': { + 'Meta': {'ordering': "['group', 'participant_number']", 'object_name': 'ParticipantGroupRelationship'}, + 'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'first_visit': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'participant_group_relationship_set'", 'to': u"orm['core.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'notifications_since': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'null': 'True', 'blank': 'True'}), + 'participant': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'participant_group_relationship_set'", 'to': u"orm['core.Participant']"}), + 'participant_number': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'round_joined': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.participantrounddatavalue': { + 'Meta': {'ordering': "['-date_created', 'round_data', 'participant_group_relationship', 'parameter']", 'object_name': 'ParticipantRoundDataValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'participant_group_relationship': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'participant_data_value_set'", 'to': u"orm['core.ParticipantGroupRelationship']"}), + 'round_data': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'participant_data_value_set'", 'to': u"orm['core.RoundData']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'submitted': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'target_data_value': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'target_data_value_set'", 'null': 'True', 'to': u"orm['core.ParticipantRoundDataValue']"}) + }, + u'core.participantsignup': { + 'Meta': {'object_name': 'ParticipantSignup'}, + 'attendance': ('django.db.models.fields.PositiveIntegerField', [], {'max_length': '1', 'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invitation': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'signup_set'", 'to': u"orm['core.Invitation']"}), + 'participant': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'signup_set'", 'to': u"orm['core.Participant']"}) + }, + u'core.quizquestion': { + 'Meta': {'object_name': 'QuizQuestion'}, + 'answer': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'default_quiz_question_set'", 'null': 'True', 'to': u"orm['core.Experiment']"}), + 'explanation': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'input_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'label': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'quiz_question_set'", 'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.roundconfiguration': { + 'Meta': {'ordering': "['experiment_configuration', 'sequence_number', 'date_created']", 'object_name': 'RoundConfiguration'}, + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'debriefing': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'display_number': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'duration': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'experiment_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'round_configuration_set'", 'to': u"orm['core.ExperimentConfiguration']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'instructions': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'preserve_existing_groups': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'randomize_groups': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'round_type': ('django.db.models.fields.CharField', [], {'default': "'REGULAR'", 'max_length': '32'}), + 'sequence_number': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'session_id': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'survey_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'template_name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}) + }, + u'core.rounddata': { + 'Meta': {'ordering': "['round_configuration']", 'object_name': 'RoundData'}, + 'elapsed_time': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'round_data_set'", 'to': u"orm['core.Experiment']"}), + 'experimenter_notes': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'round_data_set'", 'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.roundparametervalue': { + 'Meta': {'object_name': 'RoundParameterValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'round_parameter_value_set'", 'to': u"orm['core.RoundConfiguration']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + u'core.spoolparticipantstatistics': { + 'Meta': {'object_name': 'SpoolParticipantStatistics'}, + 'absences': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'discharges': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invitations': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'participant': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'spool_statistics_set'", 'to': u"orm['core.Participant']"}), + 'participations': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}) + } + } + + complete_apps = ['core'] \ No newline at end of file diff -r 0050f5045e29e1c8502ddf2baa99ca7a1608fc02 -r 2ac61e67bd736b3f0902bf390d66e17996131156 vcweb/core/migrations/0024_auto__add_unique_rounddata_round_configuration_experiment.py --- /dev/null +++ b/vcweb/core/migrations/0024_auto__add_unique_rounddata_round_configuration_experiment.py @@ -0,0 +1,395 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding unique constraint on 'RoundData', fields ['round_configuration', 'experiment'] + db.create_unique(u'core_rounddata', ['round_configuration_id', 'experiment_id']) + + + def backwards(self, orm): + # Removing unique constraint on 'RoundData', fields ['round_configuration', 'experiment'] + db.delete_unique(u'core_rounddata', ['round_configuration_id', 'experiment_id']) + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'auth.user': { + 'Meta': {'object_name': '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': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + '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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'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'}) + }, + u'core.activitylog': { + 'Meta': {'object_name': 'ActivityLog'}, + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'log_message': ('django.db.models.fields.TextField', [], {}) + }, + u'core.address': { + 'Meta': {'object_name': 'Address'}, + 'city': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'state': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), + 'street1': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'street2': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'zipcode': ('django.db.models.fields.CharField', [], {'max_length': '8', 'blank': 'True'}) + }, + u'core.chatmessage': { + 'Meta': {'ordering': "['date_created']", 'object_name': 'ChatMessage', '_ormbases': [u'core.ParticipantRoundDataValue']}, + u'participantrounddatavalue_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ParticipantRoundDataValue']", 'unique': 'True', 'primary_key': 'True'}), + 'target_participant': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'target_participant_chat_message_set'", 'null': 'True', 'to': u"orm['core.ParticipantGroupRelationship']"}) + }, + u'core.comment': { + 'Meta': {'ordering': "['date_created']", 'object_name': 'Comment', '_ormbases': [u'core.ParticipantRoundDataValue']}, + u'participantrounddatavalue_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ParticipantRoundDataValue']", 'unique': 'True', 'primary_key': 'True'}) + }, + u'core.experiment': { + 'Meta': {'ordering': "['date_created', 'status']", 'object_name': 'Experiment'}, + 'amqp_exchange_name': ('django.db.models.fields.CharField', [], {'default': "'vcweb.default.exchange'", 'max_length': '64'}), + 'authentication_code': ('django.db.models.fields.CharField', [], {'default': "'vcweb.auth.code'", 'max_length': '32'}), + 'current_round_elapsed_time': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'current_round_sequence_number': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}), + 'current_round_start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'duration': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), + 'experiment_configuration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentConfiguration']"}), + 'experiment_metadata': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentMetadata']"}), + 'experimenter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Experimenter']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'ready_participants': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'start_date_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'INACTIVE'", 'max_length': '32'}), + 'tick_duration': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), + 'total_elapsed_time': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}) + }, + u'core.experimentactivitylog': { + 'Meta': {'object_name': 'ExperimentActivityLog', '_ormbases': [u'core.ActivityLog']}, + u'activitylog_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ActivityLog']", 'unique': 'True', 'primary_key': 'True'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'activity_log_set'", 'to': u"orm['core.Experiment']"}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.experimentconfiguration': { + 'Meta': {'ordering': "['experiment_metadata', 'creator', 'date_created']", 'object_name': 'ExperimentConfiguration'}, + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_configuration_set'", 'to': u"orm['core.Experimenter']"}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'exchange_rate': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '6', 'decimal_places': '2', 'blank': 'True'}), + 'experiment_metadata': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_configuration_set'", 'to': u"orm['core.ExperimentMetadata']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invitation_subject': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'invitation_text': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'is_experimenter_driven': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'max_group_size': ('django.db.models.fields.PositiveIntegerField', [], {'default': '5'}), + 'max_number_of_participants': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'treatment_id': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}) + }, + u'core.experimenter': { + 'Meta': {'ordering': "['user']", 'object_name': 'Experimenter'}, + 'approved': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'authentication_token': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'failed_password_attempts': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'institution': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Institution']", 'null': 'True', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'experimenter'", 'unique': 'True', 'to': u"orm['auth.User']"}) + }, + u'core.experimenterrequest': { + 'Meta': {'object_name': 'ExperimenterRequest'}, + 'approved': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['auth.User']", 'unique': 'True'}) + }, + u'core.experimentmetadata': { + 'Meta': {'ordering': "['namespace', 'date_created']", 'object_name': 'ExperimentMetadata'}, + 'about_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'default_configu... [truncated message content] |
|
From: <com...@bi...> - 2013-03-15 21:04:57
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/0050f5045e29/ changeset: 0050f5045e29 user: di...@gm... date: 2013-03-15 22:04:26 summary: adding bootstrap tour to first and second practice rounds affected #: 2 files diff -r 71e47ee1a9af5c0e35439339bab5cf4f5ba9e199 -r 0050f5045e29e1c8502ddf2baa99ca7a1608fc02 vcweb/broker/templates/broker/participate.html --- a/vcweb/broker/templates/broker/participate.html +++ b/vcweb/broker/templates/broker/participate.html @@ -1,440 +1,466 @@ {% extends "participant/base.html" %} {% load static %} {% block head %} -{{ block.super }} -<link rel='stylesheet' href='{% static "css/broker/style.css" %}'/> + {{ block.super }} + <link rel='stylesheet' href='{% static "css/broker/style.css" %}'/> {% endblock %} {% block page %} -<div clas="container"> -<div class="hero-unit"> -<form class='form-inline'> - <div class="row"> - - <div class='control-group'> - <div class='controls'> - <label class='control-label' for='pick-template'>Round template</label> - <select id='pick-template' data-bind='value: templateName()'> - <option value='WELCOME'>Welcome</option> - <option value='GENERAL_INSTRUCTIONS'>Instructions</option> - <option value='GENERAL_INSTRUCTIONS2'>Instructions page 2</option> - <option value='PRACTICE_ROUND_INSTRUCTIONS'>Practice Round Instructions</option> - <option value='PRACTICE'>Practice round</option> - <option value='REGULAR'>Actual round</option> - </select> + <div class="container"> + <div class="hero-unit"> + <form class='form-inline'> + <div class="row"> + + <div class='control-group'> + <div class='controls'> + <label class='control-label' for='pick-template'>Round template</label> + <select id='pick-template' data-bind='value: templateName()'> + <option value='WELCOME'>Welcome</option> + <option value='GENERAL_INSTRUCTIONS'>Instructions</option> + <option value='GENERAL_INSTRUCTIONS2'>Instructions page 2</option> + <option value='PRACTICE_ROUND_INSTRUCTIONS'>Practice Round Instructions</option> + <option value='PRACTICE'>Practice round</option> + <option value='REGULAR'>Actual round</option> + </select> + </div> + + + <div class='controls'> + <label class='control-label' for='pick-network-structure'>Network structure</label> + <select id='pick-network-structure' data-bind='value: networkStructure()'> + <option value='SES.jpg'>Whole System</option> + <option value='WITHIN_AB.jpg'>Within Group Communication A-B</option> + <option value='WITHIN_CD.jpg'>Within Group Communication C-D</option> + <option value='BETWEEN_AC.jpg'>Within Group Communication A-C</option> + <option value='BETWEEN_AD.jpg'>Within Group Communication A-D</option> + <option value='BETWEEN_BC.jpg'>Within Group Communication B-C</option> + <option value='BETWEEN_BD.jpg'>Within Group Communication B-D</option> + </select> + </div> + + </div> + </div> + <div class="row"> + <h3>Timers</h3> + + <div class='control-group'> + <div class='controls'> + <button data-bind='click: startHarvestDecisionTimer' type='button' class='btn btn-primary'> + Start harvest decision timer + </button> + <button data-bind='click: startChatTimer' type='button' class='btn btn-primary'>Start chat + timer + </button> + <button data-bind='click: startChatOptionTimer' type='button' class='btn btn-primary'>Start + chat option timer + </button> + <button data-bind='click: update' type='button' class='btn btn-primary' + data-bind='click: update'>Update + </button> + </div> + </div> + </div></div> - - - <div class='controls'> - <label class='control-label' for='pick-network-structure'>Network structure</label> - <select id='pick-network-structure' data-bind='value: networkStructure()'> - <option value='SES.jpg'>Whole System</option> - <option value='WITHIN_AB.jpg'>Within Group Communication A-B</option> - <option value='WITHIN_CD.jpg'>Within Group Communication C-D</option> - <option value='BETWEEN_AC.jpg'>Within Group Communication A-C</option> - <option value='BETWEEN_AD.jpg'>Within Group Communication A-D</option> - <option value='BETWEEN_BC.jpg'>Within Group Communication B-C</option> - <option value='BETWEEN_BD.jpg'>Within Group Communication B-D</option> - </select> + </form> + </div> + <div class="row"> + <div class="span9"> + <div data-bind='template: { name: templateName() }'> + </div> + </div> + </div> +{% endblock page %} + + +{% block javascript %} + {{ block.super }} + <script src='{% static "js/bootstrap-tour.js" %}'></script> + <!-- ko templates --> + <script type='text/html' id='CHAT'> + {% include "forms/chat-template.html" %} + <div data-bind='if: chatEnabled'> + <h3>Chat</h3> + + <div class='chat-sidebar well'> + <form id="chatform" class='form-inline'> + <div class='input-prepend input-append'> + <span class='add-on'><i class='text-info icon-comment'></i></span> + <input style='width: 100%;' class='chat-action' id='chatText' type="text" + placeholder="Enter a chat message"> + <button class='btn' data-bind='click: submitChatMessage'>Send</button> + </div> + </form> + <div id='chat-div'> + <div data-bind='foreach: chatMessages'> + <i class='icon-user muted'></i><strong>Participant <span + data-bind='text: participant_number'></span></strong><b class='pull-right muted' + data-bind='text: date_created'></b> + + <p> + <small><i class='icon-double-angle-right'></i></small> + <span data-bind='text: message'></span> + </p> + </div> + </div> + </div> + </div> + </script> + + + <script type='text/html' id='WELCOME'> + + <h3>Welcome</h3> + + <p class='lead'> + The experiment will begin shortly after everyone has been assigned a station and has had time to log in. + </p> + + <div class='well'> + <div class='alert alert-info'> + <i class='text-success icon-info-sign'></i> Please <strong>wait quietly and do not close this window, + open any other applications, or communicate with any of + the other participants</strong>. + </div> + <div class='alert alert-info'> + <i class='text-success icon-info-sign'></i> + Please also make sure to turn off, silence, and disable vibration alerts on your cell phones and any + mobile devices before the experiment begins. + </div> + <div> + Thank you for your cooperation. + </div> + <div class="progress progress-striped"> + <div class="bar" style="width: 20%;"></div> + </div> + </div> + </script> + + + <script type='text/html' id='GENERAL_INSTRUCTIONS'> + <div id='instructions1'> + <h4>Harvesting and Profit</h4> + + <p> + This experiment is intended to recreate management decision about natural resources. + You have been assigned randomly to a group of four people. + You represent a manager of a natural resource. + </p> + <h4> + In this game you can earn money. + </h4> + + <p> + Your earnings depend on how well you will do in the game. Let me tell you how the game works. + </p> + + <br> + <h4>The game setup</h4> + <img class="image image-1" src="{{ STATIC_URL }}images/broker/SES.jpg" '> + <p> + Imagine you have an ecological resource at your disposal. + This resource is also shared with another player. + In the image you see, players on the left-hand side share the first resource and + players on the right hand-side share another resource. + In other words, there are two groups of <strong data-bind='text:participantsPerSubGroup'></strong> + people within the larger group of <strong data-bind='text:participantsPerGroup'></strong> people. + </p> + + <h4>Resources influence each other</h4> + + <p> + The resources you see in the picture, they influence each other. Which means that + the decision you take also influences the resources of the other group. + </p> + + <ul class='pager'> + <li class='next'> + <a href='javascript: void();' data-bind='click: activateInstructionsPageTwo'>OK, I understand</a> + </li> + </ul> + </div> + </script> + + + <script type='text/html' id='GENERAL_INSTRUCTIONS2'> + <div id='instructions2'> + <h4>How to play</h4> + + <p> + At each round you have <strong data-bind='text: maxHarvestDecision'></strong> hours available to work on + this resource, + and you can invest your time in two different types of activities: + You can spend time harvesting the resource or spend time in conserving the resource. + </br> + Notice that if you prefer, you can invest all your time in only one of the activities. + You will play several rounds. + As I said before you can earn money in this game. + At the end of each round the amount of time you spent in harvesting will be transformed into earnings. + So the amount of money you get depends primarily on the amount of time you invest into harvesting. + + For each hour you harvest you will receive <strong + data-bind='text: formatCurrency(dollarsPerToken())'></strong> + This is your standard earning. + + <p> + <strong data-bind='text: formatCurrency(maxEarnings())'></strong> + </p> + </p> + <h4>Your standard earning can increase</h4> + + <p> + This standard revenue can change in two ways: + If players of subgroup A, taken together, reach <span class='badge badge-important' + data-bind='text: localThreshold'></span> hours of + conservation, + then each hour they spend harvesting will be paid <span class='badge badge-important' + data-bind='text: localBonus'></span>% more than + the standard revenue. + The same applies for subgroup B. + If all players in the game, taken together, reach <span class='badge badge-important' + data-bind='text: globalThreshold'></span> hours + of conservation, + then returns will again increase by <span class='badge badge-important' + data-bind='text: globalBonus'></span>%. + </p> + + <h4>Decisions are private</h4> + + <p> + Keep in mind that decisions are private, and everyone decides for themselves how much time they want to + invest in each activity. + </p> + <ul class='pager'> + <li class='previous'> + <a href='javascript: void();' data-bind='click: activateInstructionsPageOne'>Back</a> + </li> + <li class='next'> + <a href='javascript: void();' data-bind='click: activatePracticeRoundInstructions'>OK, Continue to + practice rounds</a> + </li> + </ul> + </div> + </script> + + + <script type='text/html' id='PRACTICE_ROUND_INSTRUCTIONS'> + <h3> + Practicing + </h3> + + <p> + Let’s do some practicing so you can get familiar with the interface. + </p> + + <h3>No Payment</h3> + This practice will NOT count for your real earnings. <br> + It is just an opportunity for you to get familiar with the game. + + + </p> + <ul class='pager'> + <li class='previous'> + <a href='javascript:void();' data-bind='click: activateInstructionsPageTwo'>Back</a> + </li> + <li class='next'> + <a href='javascript: void();' data-bind='click: finishedInstructions'>I have fully read and understand + these instructions</a> + </li> + </ul> + </script> + + + + <script type='text/html' id='INSTRUCTIONS'> + <div data-bind='html: instructions'> + </div> + </script> + + + <script type='text/html' id='REGULAR'> + <div class='row'> + <div class='span4'> + <h3>My Current Earnings</h3> + + <div> + <span id="totalEarning" data-bind='text: totalEarning'></span> + </div> + + <div data-bind='if: isTimerRunning'> + <div class='alert alert-error'> + <b><i class='icon-time'></i> Time left:</b> + <span data-bind='text: secondsLeft'></span> + </div> + </div> + </div> + + <p> + You will have a maximum of <i class='icon-clock'></i>seconds + to make a + harvest decision each round. A countdown will alert you when there are + <span data-bind='text: warningCountdownTime'></span> seconds remaining to make a harvest choice. When the + countdown + reaches zero, any value you have selected will be submitted. <strong>The default harvest is zero.</strong> + </p> + + + + + <!-- only show when chatOption enabled --> + <div clas="span6" data-bind="if: chatOptionEnabled"> + <div data-bind='if: isTimerRunning'> + <div class='alert alert-error'> + <b><i class='icon-time'></i> Time left:</b> + <span data-bind='text: secondsLeft'></span>s + </div> + </div> + <div class="span1"> + <a href="#" class="btn btn-primary" data-bind="submitChatOptionLocal"> + <i class="icon-home icon-white"></i> + <span><strong>Talk within group FREE</strong></span> + </a> + </div> + <div class="span1"> + <a href="#" class="btn btn-primary" data-bind="submitChatOptionGlobal"> + <i class="icon-globe icon-white"></i> + <span><strong>Talk with other group $$ 2h</strong></span> + </a> + </div> + </div> + + + <!-- The table for decision and showing payments from last round --> + <div class='span6'> + <table class="table table-hover"> + <thead> + <tr> + <th colspan="3">Round Decisions</th> + </tr> + </thead> + <tbody> + <tr> + <td class="td-1">Harvesting</td> + <td><input class="textinput" type="text" id="harvestID" name="harvest" placeholder="Placeholder"></td> + <td class="td-1"> + </table> + <p> + <table class="table" data-bind="with: chosenFolderData"> + <thead> + <tr> + <th colspan="3">Your decisions last round</th> + </tr> + </thead> + <tbody> + <tr> + <td class="td-1">Harvesting</td> + <td><strong class='text-success'><span data-bind='text:lastRoundHarvestDecision'></span><i + class='icon-leaf'></i></strong></td> + <td class="td-1"></td> + </tr> + <tr> + <td class="td-1">Conservation</td> + <td span="2"><strong class='text-success'><span id="lastRoundMyGroupConservation" data-bind='text:lastRoundMyGroupConservation'></span><i class='icon-leaf'></i></strong> + </td> + </tr> + <tr> + <td class="td-1">Global Conservation</td> + <td span="2"><strong class='text-success'><span data-bind='text:lastRoundGlobalConservation'></span><i class='icon-leaf'></i></strong> + </td> + </tr> + </table> + <p> + <table class="table" > + <thead> + <tr> + <th colspan="3">Payments from last round</th> + </tr> + </thead> + <tbody> + <tr> + <td class="td-1">from your harvesting</td> + <td><span id="lastRoundHarvestPayOff" data-bind="lastRoundHarvestPayOff"></span></td> + <td class="td-1"></td> + </tr> + <tr> + <td class="td-1">from within group bonus</td> + <td span="2"><span id="lastRoundGroupLocalBonus" data-bind="lastRoundGroupLocalBonus"></span></td> + </tr> + <tr> + <td class="td-1">from between group bonus</td> + <td span="2"><span id="lastRoundGroupGlobalBonus" data-bind="lastRoundGroupGlobalBonus"></span></td> + </tr> + </table> + + </div> + + </div> - </div> - </div> - <div class="row"> - <h3>Timers</h3> - <div class='control-group'> - <div class='controls'> - <button data-bind='click: startHarvestDecisionTimer' type='button' class='btn btn-primary'>Start harvest decision timer</button> - <button data-bind='click: startChatTimer' type='button' class='btn btn-primary'>Start chat timer</button> - <button data-bind='click: startChatOptionTimer' type='button' class='btn btn-primary'>Start chat option timer</button> - <button data-bind='click: update' type='button' class='btn btn-primary' data-bind='click: update'>Update</button> + <div data-bind='if: practiceRound'> + <div class='alert alert-error alert-block'> + <h4>PRACTICE ROUND</h4> + This is a practice round. The decisions you make in this round will <b>NOT</b> contribute to your + earnings. + <span data-bind="if: isFirstPracticeRound"> + <a href="#" data-bind="">Show me 1st Instructions again</input> + </span> + </div> - </div> - </div> - </div> -</form> -</div> -<div class="row"> - <div class="span9"> - <div data-bind='template: { name: templateName() }'> - </div> -</div> -</div> -{% endblock page %} + <div data-bind='style: { width: networkStructureImageWidth, height: systemImageHeight, background: networkStructureImageBackgroundUrl }'> + + </div> + <div data-bind="ifnot: isTimeOut" id='resourceDisplay'> + <div class='alert alert-info'>You have <strong class='badge badge-success' + data-bind='text:hoursLeft'></strong> hours left to use today. + </div> -{% block javascript %} -{{ block.super }} -<script src='{% static "js/bootstrap-tour.js" %}'></script> -<!-- ko templates --> -<script type='text/html' id='CHAT'> -{% include "forms/chat-template.html" %} -<div data-bind='if: chatEnabled'> -<h3>Chat</h3> -<div class='chat-sidebar well'> - <form id="chatform" class='form-inline'> - <div class='input-prepend input-append'> - <span class='add-on'><i class='text-info icon-comment'></i></span> - <input style='width: 100%;' class='chat-action' id='chatText' type="text" placeholder="Enter a chat message"> - <button class='btn' data-bind='click: submitChatMessage'>Send</button></div> - </form> - <div id='chat-div'> - <div data-bind='foreach: chatMessages'> - <i class='icon-user muted'></i><strong>Participant <span data-bind='text: participant_number'></span></strong><b class='pull-right muted' data-bind='text: date_created'></b> - <p> - <small><i class='icon-double-angle-right'></i></small><span data-bind='text: message'></span> - </p> + <div data-bind="if: isTimeOut"> + <div style='padding: 8px; margin: auto; border: solid 1px; background: url("{{ STATIC_URL }}images/forestry/deforestation.jpg") no-repeat center; height: 282px; width:425px;'> + + </div> + <div class='alert alert-error'>You have no time left today. Please wait until the next round begins.</div></div> - </div> -</div> -</div> -</script> + <div data-bind='if: hasSubmit'> + <div class='alert alert-error'> + You have invested <span class='badge badge-important' data-bind='text: harvestDecision'></span> hours in + harvesting today. + You have invested <span class='badge badge-important' data-bind='text: conservationDecision'></span> + hours in conservation today. + </div> + </div> + <h3>Harvest</h3> + <div data-bind='ifnot: isResourceEmpty'> + <form id='vcweb-form' action='' method='post' class='form-inline'> + {% csrf_token %} + <div class='control-group'> + <div class='controls'> + <input id='participantGroupId' type='hidden' name='participant_group_id' + data-bind='value: participantGroupId'/> + <input id='harvestDecision' type="number" size="1" maxlength="1" name='harvest_decision' + class='required' min="0" + data-bind="value: harvestDecision, attr: { max: maxHarvestDecision }"/> + <input id='conservationDecision' type="number" size="1" maxlength="1" + name='conservation_decision' class='disabled' min="0" + data-bind="value: conservationDecision, attr: { max: maxConservationDecision }"/> + <button id='submitDecision' data-bind='click: submitDecision' type='submit' class='btn'> + Harvest + </button> + </div> + </div> + </form> + </div> + </script> -<script type='text/html' id='WELCOME'> -<h3>Welcome</h3> -<p class='lead'> - The experiment will begin shortly after everyone has been assigned a station and has had time to log in. -</p> -<div class='well'> - <div class='alert alert-info'> - <i class='text-success icon-info-sign'></i> Please <strong>wait quietly and do not close this window, open any other applications, or communicate with any of - the other participants</strong>. - </div> - <div class='alert alert-info'> - <i class='text-success icon-info-sign'></i> - Please also make sure to turn off, silence, and disable vibration alerts on your cell phones and any mobile devices before the experiment begins. - </div> - <div> - Thank you for your cooperation. - </div> - <div class="progress progress-striped"> - <div class="bar" style="width: 20%;"></div> - </div> -</div> -</script> -<script type='text/html' id='GENERAL_INSTRUCTIONS'> -<div id='instructions1'> -<h4>Harvesting and Profit</h4> -<p> -This experiment is intended to recreate management decision about natural resources. -You have been assigned randomly to a group of four people. -You represent a manager of a natural resource. -</p> -<h4> -In this game you can earn money. -</h4> -<p> -Your earnings depend on how well you will do in the game. Let me tell you how the game works. -</p> - -<br> -<h4>The game setup</h4> - <img class="image image-1" src="{{STATIC_URL}}images/broker/SES.jpg" '> -<p> -Imagine you have an ecological resource at your disposal. -This resource is also shared with another player. -In the image you see, players on the left-hand side share the first resource and -players on the right hand-side share another resource. -In other words, there are two groups of <strong data-bind='text:participantsPerSubGroup'></strong> people within the larger group of <strong data-bind='text:participantsPerGroup'></strong> people. -</p> - -<h4>Resources influence each other</h4> -<p> -The resources you see in the picture, they influence each other. Which means that -the decision you take also influences the resources of the other group. -</p> - -<ul class='pager'> -<li class='next'> -<a href='javascript: void();' data-bind='click: activateInstructionsPageTwo'>OK, I understand</a> -</li> -</ul> -</div> -</script> - - -<script type='text/html' id='GENERAL_INSTRUCTIONS2'> -<div id='instructions2'> -<h4>How to play</h4> -<p> -At each round you have <strong data-bind='text: maxHarvestDecision'></strong> hours available to work on this resource, -and you can invest your time in two different types of activities: -You can spend time harvesting the resource or spend time in conserving the resource. -</br> -Notice that if you prefer, you can invest all your time in only one of the activities. -You will play several rounds. -As I said before you can earn money in this game. -At the end of each round the amount of time you spent in harvesting will be transformed into earnings. -So the amount of money you get depends primarily on the amount of time you invest into harvesting. - -For each hour you harvest you will receive <strong data-bind='text: formatCurrency(dollarsPerToken())'></strong> -This is your standard earning. - <p> -<strong data-bind='text: formatCurrency(maxEarnings())'></strong> - </p> -</p> -<h4>Your standard earning can increase</h4> -<p> -This standard revenue can change in two ways: -If players of subgroup A, taken together, reach <span class='badge badge-important' data-bind='text: localThreshold'></span> hours of conservation, -then each hour they spend harvesting will be paid <span class='badge badge-important' data-bind='text: localBonus'></span>% more than the standard revenue. -The same applies for subgroup B. -If all players in the game, taken together, reach <span class='badge badge-important' data-bind='text: globalThreshold'></span> hours of conservation, -then returns will again increase by <span class='badge badge-important' data-bind='text: globalBonus'></span>%. -</p> - -<h4>Decisions are private</h4> -<p> -Keep in mind that decisions are private, and everyone decides for themselves how much time they want to invest in each activity. -</p> -<ul class='pager'> -<li class='previous'> -<a href='javascript: void();' data-bind='click: activateInstructionsPageOne' >Back</a> -</li> -<li class='next'> -<a href='javascript: void();' data-bind='click: activatePracticeRoundInstructions'>OK, Continue to practice rounds</a> -</li> -</ul> -</div> -</script> - -<script type='text/html' id='PRACTICE_ROUND_INSTRUCTIONS'> -<h3> -Practicing -</h3> -<p> -Let’s do some practicing so you can get familiar with the interface. -</p> - -<h3>No Payment</h3> -This practice will NOT count for your real earnings. <br> -It is just an opportunity for you to get familiar with the game. - - -At the center of the page is where you insert your decision. -For this practice round, put 6 hours into harvesting. -Note that the rest of your available hours will be put into conservation. -{Then click Play! To submit your choice.} You immediately see how much you earned in that day. - -You receive 0.6 from harvesting. Because everyone contributed 4 hours to conservation, resulting in 8 hours for group A and 8 hours for group B. So the standard revenue of $0.10/hour has been increased by 50% you receive an extra $0.30 and your total is $0.90. - If the sum within your group was less than 5 hours you would not receive benefits. If the sum of conservation time of all players was more than 22 hours you would get a further increase of 50% in the revenues. -On the right hand side of the page you can see the accumulation of your earning through the game. - -At some point during the game you will be allowed to communicate to other players. This will be done through the chat window. Each message you send will be targeted a single player. … -Go ahead and send a message. It will not be seen by others now. -Remember that all your choices are independent and none will see what your decisions are. Communications will be limited by time. - -</p> - -<h3>Harvest Choice</h3> -<p> -Each round you will have a maximum of 1 minute to make a harvest decision. THere are two ways to submit a harvest -decision: -</p> -<ol> -<li>Select a harvest amount and click submit</li> -<li>Select a harvest amount and wait for the end of the session</li> -</ol> -<p> -At the end of each round a countdown will alert you when there are 10 seconds remaining to make a harvest choice. When -the countdown reaches zero, any value you have selected will be auto-submitted. The default harvest is zero. -</p> -<ul class='pager'> -<li class='previous'> -<a href='javascript:void();' data-bind='click: activateInstructionsPageTwo'>Back</a> -</li> -<li class='next'> -<a href='javascript: void();' data-bind='click: finishedInstructions'>I have fully read and understand these instructions</a> -</li> -</ul> -</script> -<script type='text/html' id='PAID_EXPERIMENT_INSTRUCTIONS'> -<h2>Paid Experiment Instructions</h2> -<h3>Two Sessions</h3> -<p> -This experiment is composed of two different, unconnected sessions. Your group will be randomly selected for each -session, so you will be playing with a different group each time. We will pay you for one of these two sessions, chosen -at random. You have exactly 50% chance of being paid for your earnings in either session. -</p> -<h3>Group and Individual Status</h3> -<p> -You will be able to observe the status of the members of your group each round. Likewise your group members can see -your status and those of the group. -</p> -<h3>Group Chat</h3> -<p> -You will be able to chat with the other members of your group via group text chat. Once you have made a harvest -decision, you will no longer be able to chat for that round. -</p> -<h3>Harvest Choice</h3> -<p> -You will have a maximum of <i class='icon-clock'></i><span data-bind='text: roundDuration'></span> seconds to make a -harvest decision each round. A countdown will alert you when there are -<span data-bind='text: warningCountdownTime'></span> seconds remaining to make a harvest choice. When the countdown -reaches zero, any value you have selected will be submitted. <strong>The default harvest is zero.</strong> -</p> -</script> -<script type='text/html' id='INSTRUCTIONS'> - <div data-bind='html: instructions'> - </div> -</script> -<script type='text/html' id='REGULAR'> -<div class='row'> - <div class='span4'> - <h3>My Current Earnings</h3> - <div> - <span data-bind='text: totalEarning'></span> - </div> - - <div data-bind='if: isTimerRunning'> - <div class='alert alert-error'> - <b><i class='icon-time'></i> Time left:</b> - <span data-bind='text: secondsLeft'></span> - </div> - </div> - - - - </div> - -<!-- only show when chatOption enabled --> -<div clas="span6" data-bind="if: chatOptionEnabled"> -<div data-bind='if: isTimerRunning'> - <div class='alert alert-error'> - <b><i class='icon-time'></i> Time left:</b> - <span data-bind='text: secondsLeft'></span>s - </div> - </div> -<div class="span1" > - <a href="#" class="btn btn-primary" data-bind="submitChatOptionLocal"> - <i class="icon-home icon-white"></i> - <span><strong>Talk within group FREE</strong></span> - </a> -</div> -<div class="span1"> - <a href="#" class="btn btn-primary" data-bind="submitChatOptionGlobal"> - <i class="icon-globe icon-white"></i> - <span><strong>Talk with other group $$ 2h</strong></span> - </a> -</div> -</div> - - - -<!-- The table for decision and showing payments from last round --> -<div class='span6'> -<table class="table table-hover"> - <thead> - <tr> - <th colspan="3">Decisions Today</th> - </tr> - </thead> - <tbody> - <tr> - <td class="td-1">Harvesting</td> - <td><input class="textinput" type="text" id="harvestID" name="harvest" placeholder="Placeholder"></td> - <td class="td-1"> -</table> -<p> -<table class="table" data-bind="with: chosenFolderData"> - <thead> - <tr> - <th colspan="3" >Your decisions last round</th> - </tr> - </thead> - <tbody> - <tr> - <td class="td-1">Harvesting</td> - <td><strong class='text-success'><span data-bind='text:lastHarvestDecision'></span><i class='icon-leaf'></i></strong></td> - <td class="td-1"></td> - </tr> - <tr> - <td class="td-1">Conservation</td> - <td span="2"><strong class='text-success'><span data-bind='text:lastConservationDecision'></span><i class='icon-leaf'></i></strong></td> - </tr> -</table> -<p> -<table class="table" data-bind="with: chosenFolderData"> - <thead> - <tr> - <th colspan="3" >Payments from last round</th> - </tr> - </thead> - <tbody> - <tr> - <td class="td-1">from your harvesting</td> - <td><input class="textinput" type="text" id="harvestID" name="harvest" placeholder="Placeholder"></td> - <td class="td-1"></td> - </tr> - <tr> - <td class="td-1">from within group bonus</td> - <td span="2"><input class="textinput" type="text" id="conservationID" name="conservation" ></td> - </tr> - <tr> - <td class="td-1">from between group bonus</td> - <td span="2"><input class="textinput" type="text" id="conservationID" name="conservation" ></td> - </tr> -</table> - -</div> - - -</div> - -<div data-bind='if: practiceRound'> -<div class='alert alert-error alert-block'> -<h4>PRACTICE ROUND</h4> -This is a practice round. The decisions you make in this round will <b>NOT</b> contribute to your earnings. -</div> -</div> -<div data-bind='style: { width: networkStructureImageWidth, height: systemImageHeight, background: networkStructureImageBackgroundUrl }'> - - </div> - -<div data-bind="ifnot: isTimeOut" id='resourceDisplay'> - <div class='alert alert-info'>You have <strong class='badge badge-success' data-bind='text:hoursLeft'></strong> hours left to use today.</div> - -</div> -<div data-bind="if: isTimeOut"> - <div style='padding: 8px; margin: auto; border: solid 1px; background: url("{{STATIC_URL}}images/forestry/deforestation.jpg") no-repeat center; height: 282px; width:425px;'> - - </div> - <div class='alert alert-error'>You have no time left today. Please wait until the next round begins.</div> -</div> -<div data-bind='if: hasSubmit'> -<div class='alert alert-error'> - You have invested <span class='badge badge-important' data-bind='text: harvestDecision'></span> hours in harvesting today. - You have invested <span class='badge badge-important' data-bind='text: conservationDecision'></span> hours in conservation today. -</div> -</div> - - -<h3>Harvest</h3> -<div data-bind='ifnot: isResourceEmpty'> -<form id='vcweb-form' action='' method='post' class='form-inline'> - {% csrf_token %} - <div class='control-group'> - <div class='controls'> - <input id='participantGroupId' type='hidden' name='participant_group_id' data-bind='value: participantGroupId'/> - <input id='harvestDecision' type="number" size="1" maxlength="1" name='harvest_decision' class='required' min="0" data-bind="value: harvestDecision, attr: { max: maxHarvestDecision }" /> - <input id='conservationDecision' type="number" size="1" maxlength="1" name='conservation_decision' class='disabled' min="0" data-bind="value: conservationDecision, attr: { max: maxConservationDecision }" /> - - <button id='submitDecision' data-bind='click: submitDecision' type='submit' class='btn'>Harvest</button> - </div> - </div> -</form> -</div> -</script> -<script type="text/javascript"> - $(function() { + <script type="text/javascript"> + $(function () { function ExperimentModel(experimentModelJson) { var self = this; var model = ko.mapping.fromJS(experimentModelJson); @@ -442,68 +468,74 @@ model.secondsLeft = ko.observable(0); model.currentInterval = ko.observable(); - model.setCurrentInterval = function(intervalId) { + model.setCurrentInterval = function (intervalId) { model.clearCurrentInterval(); model.currentInterval(intervalId); } - model.clearCurrentInterval = function() { + model.clearCurrentInterval = function () { console.debug("clearing current interval: " + model.currentInterval()); if (model.currentInterval()) { clearInterval(model.currentInterval()); model.currentInterval(undefined); } } - model.tick = function() { + model.tick = function () { model.secondsLeft(model.secondsLeft() - 1); } - model.isTimerRunning = ko.computed(function() { + model.isTimerRunning = ko.computed(function () { return model.secondsLeft() > 0; }); - model.setupFirstPracticeRoundTour = function() { + model.setupFirstPracticeRoundTour = function () { // set up first bootstrap tour alert("setting up first practice round tour"); }; - model.setupSecondPracticeRoundTour = function() { + model.setupSecondPracticeRoundTour = function () { alert("setting up second practice round tour"); }; - model.update = function() { + model.update = function () { $.get('view-model', { participant_group_id: {{ participant_group_relationship.pk }}, }, - function(response) { - console.debug("updating with response: "); - console.debug(response); - ko.mapping.fromJS(response, model); - if (model.isFirstPracticeRound()) { - model.setupFirstPracticeRoundTour(); - } - else if (model.isSecondPracticeRound()) { - model.setupSecondPracticeRoundTour(); - } - }); + function (response) { + console.debug("updating with response: "); + console.debug(response); + ko.mapping.fromJS(response, model); + if (model.isFirstPracticeRound()) { + model.setupFirstPracticeRoundTour(); + } + else if (model.isSecondPracticeRound()) { + model.setupSecondPracticeRoundTour(); + } + }); }; model.templateName = ko.observable("WELCOME"); // activate instructions click bindings - model.activateInstructionsPageOne = function() { + model.activateInstructionsPageOne = function () { model.templateName('GENERAL_INSTRUCTIONS'); }; - model.activateInstructionsPageTwo = function() { + model.activateInstructionsPageTwo = function () { model.templateName('GENERAL_INSTRUCTIONS2'); }; - model.activateInstructionsPageThree = function() { + model.activateInstructionsPageThree = function () { model.templateName('GENERAL_INSTRUCTIONS3'); }; - model.activatePracticeRoundInstructions = function() { + model.activatePracticeRoundInstructions = function () { model.templateName("PRACTICE_ROUND_INSTRUCTIONS"); } - model.activateTreatmentInstructions = function() { + model.activateTreatmentInstructions = function () { model.templateName("TREATMENT_INSTRUCTIONS"); } + model.dysplayFirstInstructionsAgain = function () { + tourFirst.start(true); + } + model.dysplaySecondInstructionsAgain = function () { + tourSecond.start(true); + } //for displaying the different network structures - model.networkStructure = ko.observable("{{STATIC_URL}}images/broker/SES.jpg"); - model.networkStructureImageWidth = ko.observable("600px"); + model.networkStructure = ko.observable("{{STATIC_URL}}images/broker/SES.jpg"); + model.networkStructureImageWidth = ko.observable("600px"); model.networkStructureImageHeight = ko.observable("80px"); - model.finishedInstructions = function() { + model.finishedInstructions = function () { console.debug("instructions were finished, notifying experimenter"); $.post('/experiment/participant-ready', { participant_group_id: {{ participant_group_relationship.pk }} }, function(response) { console.debug("successfully posted to server, notifying sockjs: " + response); @@ -513,8 +545,8 @@ model.chatEnabled = ko.observable(false); // round configurations model.chatOptionEnabled = ko.observable(false); // round configurations model.harvestDecision = ko.observable(0); - model.conservationDecision = ko.computed(function() { - return model.maxHarvestDecision - model.harvestDecision + model.conservationDecision = ko.computed(function () { + return model.maxHarvestDecision - model.harvestDecision }); // model.numberOfTreesPerRow = ko.observable(10); // model.isResourceEmpty = ko.computed(function() { @@ -526,46 +558,46 @@ // } // return 0; // }); - + // - model.startChatTimer = function() { + model.startChatTimer = function () { model.enableChat(); model.secondsLeft(60); model.setCurrentInterval( - setInterval(function() { - model.tick(); - if (! model.isTimerRunning()) { - model.disableChat(); - model.clearCurrentInterval(); - } - }, - 1000)); + setInterval(function () { + model.tick(); + if (!model.isTimerRunning()) { + model.disableChat(); + model.clearCurrentInterval(); + } + }, + 1000)); }; - model.startHarvestDecisionTimer = function() { + model.startHarvestDecisionTimer = function () { model.secondsLeft(10); - model.setCurrentInterval(setInterval(function() { - model.tick(); - if (! model.isTimerRunning()) { - model.submitDecision(); - model.clearCurrentInterval(); - } - }, - 1000)); + model.setCurrentInterval(setInterval(function () { + model.tick(); + if (!model.isTimerRunning()) { + model.submitDecision(); + model.clearCurrentInterval(); + } + }, + 1000)); }; - model.startChatOptionTimer = function() { + model.startChatOptionTimer = function () { model.enableChatOption(); model.secondsLeft(10); model.setCurrentInterval( - setInterval(function() { - model.tick(); - if (! model.isTimerRunning()) { - model.disableChatOption(); - model.clearCurrentInterval(); - } - }, - 1000)); + setInterval(function () { + model.tick(); + if (!model.isTimerRunning()) { + model.disableChatOption(); + model.clearCurrentInterval(); + } + }, + 1000)); }; - // model.submitDecision = function(data, evt) { + // model.submitDecision = function(data, evt) { // if (evt) { // evt.preventDefault(); // } @@ -612,11 +644,12 @@ // return model; } + function initialize(experimentModelJson) { var experimentModel = new ExperimentModel(experimentModelJson); ko.applyBindings(experimentModel); var s = connect(); - s.onmessage = function(json) { + s.onmessage = function (json) { console.debug(json); var data = $.parseJSON(json.data); console.debug(data); @@ -637,12 +670,97 @@ // $('#harvestDecision').keyup(function() { // $('#harvestDecision').val(this.value.match(/\d+/)); // }); - $('#pick-template').change(function() { + $('#pick-template').change(function () { var templateName = $(this).val(); console.debug("switching to template: " + templateName); if (templateName === "PRACTICE") { templateName = "REGULAR"; experimentModel.practiceRound(true); + if (isFirstPracticeRound){ + var tourFirst = new Tour({ + onEnd: function (tourFirst) { + // send player to next practice round where isSecondPracticeRound = TRUE and EnabledChatOption=TRUE + + }, + }); + tourFirst.addStep({ + element: "harvestDecision", + title: "Here's where you insert your harvesting decision", + content: "For this practice round, go ahead and put 6 hours into harvesting. Each round you will have a maximum of <span data-bind='text: roundDuration'></span> minute to make a harvest decision." /* content of the popover */ + placement:"right" + }); + tourFirst.addStep({ + element: "conservationDecision", + title: "Your conservation decision", + content: "Note that the rest of your available hours will be put into conservation." + placement:"right" + }); + tourFirst.addStep({ + element: "submitDecision", + title: "Submit your decision", + content: "Now click here to submit your harvest choice. Your choice will be submitted automatically when time is up. A countdown will alert you when there are 10 seconds remaining to make a harvest. The default harvest is zero." /* content of the popover */ + placement:"right" + }); + tourFirst.addStep({ + element: "lastRoundHarvestPayOff", + title: "Your round earnings", + content: "Here you will see how much you earned in each round. You receive 0.6 from harvesting. Because everyone contributed 4 hours to conservation, resulting in 8 hours for group A and 8 hours for group B." + placement:"right" + }); + tourFirst.addStep({ + element: "lastRoundGroupLocalBonus", + title: "Bonus", + content: "So the standard revenue of $0.10/hour has been increased by 50% you receive an extra $0.30 and your total is $0.90. If the sum within your group was less than 5 hours you would not receive benefits. " + placement:"right" + }); + tourFirst.addStep({ + element: "lastRoundMyGroupConservation", + title: "Bonus", + content: "If the sum of conservation time of all players were more than 22 hours you would get a further increase of 50% in the revenues." + placement:"right" + }); + tourFirst.addStep({ + element: "totalEarning", + title: "Total Earning", + content: "Here you can your total earning throughout the game" + placement:"right" + }); + + tourFirst.start(); + } else if (isSecondPracticeRound) { + var tourSecond = new Tour(); + tourSecond.addStep({ + element: "", + title: "Communication", + content: "At some point during the game you will have the option of communicating to other players. Communication to the other player within your group is FREE. Communication with the other group costs 2 hours." + }); + tourSecond.addStep({ + element: "", + title: "", + content: "For this practice, go ahead and choose 'Communication within Group' and 'Communication with other Group'" + }); + tourSecond.addStep({ + element: "", + title: "Chat rooms", + content: "Communication will happen through these chat windows. Communications is time bound. Each message you send will be targeted a single player. Go ahead and send a message. It will not be seen by others for this practice." + onHide: function (tourSecond) { + // post a dummy message to the chat... "Here's an example of a reply message" + } + + }); + tourSecond.addStep({ + element: "", + title: "Chat rooms", + content: "Remember that all your choices are independent and none will see what your decisions are." + }); + tourSecond.start(); + + + + + + + } } else if (templateName === "REGULAR") { experimentModel.practiceRound(false); @@ -656,8 +774,9 @@ // }); } + var experimentModelJson = $.parseJSON("{{ experimentModelJson|escapejs }}"); initialize(experimentModelJson); }); -</script> + </script> {% endblock %} diff -r 71e47ee1a9af5c0e35439339bab5cf4f5ba9e199 -r 0050f5045e29e1c8502ddf2baa99ca7a1608fc02 vcweb/broker/views.py --- a/vcweb/broker/views.py +++ b/vcweb/broker/views.py @@ -96,10 +96,16 @@ experiment_model_dict['lastRoundGroupBConservation'] = 10 experiment_model_dict['lastRoundGroupLocalBonus'] = 10 experiment_model_dict['lastRoundGroupGlobalBonus'] = 10 + experiment_model_dict['lastRoundHarvestPayOff'] = 5 experiment_model_dict['totalEarning'] = 100 number_of_connected_groups = round_configuration.get_parameter_value(name='number_of_connected_groups', default=2).int_value experiment_model_dict['participantsPerSubGroup'] = group.max_size experiment_model_dict['participantsPerGroup'] = group.max_size * number_of_connected_groups + + + + + experiment_model_dict.update(**kwargs) return dumps(experiment_model_dict) Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
|
From: <com...@bi...> - 2013-03-15 04:09:38
|
3 new commits in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/80a34203bea7/ changeset: 80a34203bea7 user: alllee date: 2013-03-15 01:53:21 summary: allow SECRET_KEY override from local settings affected #: 1 file diff -r 172ee566c3cb08c89d7c204000af619f88cae552 -r 80a34203bea7ed17f0d1d72b7921d81d485b0441 vcweb/settings.py --- a/vcweb/settings.py +++ b/vcweb/settings.py @@ -321,6 +321,7 @@ SENTRY_DSN = getattr(local_settings, 'SENTRY_DSN', None) EMAIL_BACKEND = getattr(local_settings, 'EMAIL_BACKEND', EMAIL_BACKEND) DATABASES = getattr(local_settings, 'DATABASES', DATABASES) + SECRET_KEY = getattr(local_settings, 'SECRET_KEY', SECRET_KEY) add_settings_tuples('MIDDLEWARE_CLASSES', local_settings) add_settings_tuples('INSTALLED_APPS', local_settings) add_settings_tuples('ALLOWED_HOSTS', local_settings) https://bitbucket.org/virtualcommons/vcweb/commits/43e7a5ca2e91/ changeset: 43e7a5ca2e91 user: alllee date: 2013-03-15 04:54:57 summary: replacing direct group-group relationship with GroupCluster one to many field that allows for arbitrary numbers of group relationships and direct data values on those group clusters affected #: 2 files diff -r 80a34203bea7ed17f0d1d72b7921d81d485b0441 -r 43e7a5ca2e914ecd7bf3dc78fb373d6b88ecf5f7 vcweb/core/migrations/0021_auto__del_grouprelationshipdatavalue__add_groupclusterdatavalue__add_g.py --- /dev/null +++ b/vcweb/core/migrations/0021_auto__del_grouprelationshipdatavalue__add_groupclusterdatavalue__add_g.py @@ -0,0 +1,466 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Deleting model 'GroupRelationshipDataValue' + db.delete_table(u'core_grouprelationshipdatavalue') + + # Adding model 'GroupClusterDataValue' + db.create_table(u'core_groupclusterdatavalue', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('parameter', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['core.Parameter'])), + ('string_value', self.gf('django.db.models.fields.TextField')(null=True, blank=True)), + ('int_value', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)), + ('float_value', self.gf('django.db.models.fields.FloatField')(null=True, blank=True)), + ('boolean_value', self.gf('django.db.models.fields.NullBooleanField')(null=True, blank=True)), + ('date_created', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now, db_index=True)), + ('last_modified', self.gf('vcweb.core.models.AutoDateTimeField')(default=datetime.datetime.now)), + ('is_active', self.gf('django.db.models.fields.BooleanField')(default=True)), + ('group_cluster', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['core.GroupCluster'])), + ('round_data', self.gf('django.db.models.fields.related.ForeignKey')(related_name='group_cluster_data_value_set', to=orm['core.RoundData'])), + )) + db.send_create_signal(u'core', ['GroupClusterDataValue']) + + # Adding model 'GroupCluster' + db.create_table(u'core_groupcluster', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('date_created', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)), + ('name', self.gf('django.db.models.fields.CharField')(max_length=64, null=True, blank=True)), + ('session_id', self.gf('django.db.models.fields.CharField')(max_length=64, null=True, blank=True)), + )) + db.send_create_signal(u'core', ['GroupCluster']) + + # Deleting field 'GroupRelationship.second_group' + db.delete_column(u'core_grouprelationship', 'second_group_id') + + # Deleting field 'GroupRelationship.first_group' + db.delete_column(u'core_grouprelationship', 'first_group_id') + + # Adding field 'GroupRelationship.cluster' + db.add_column(u'core_grouprelationship', 'cluster', + self.gf('django.db.models.fields.related.ForeignKey')(default=None, related_name='group_set', to=orm['core.GroupCluster']), + keep_default=False) + + # Adding field 'GroupRelationship.group' + db.add_column(u'core_grouprelationship', 'group', + self.gf('django.db.models.fields.related.ForeignKey')(default=None, to=orm['core.Group']), + keep_default=False) + + + def backwards(self, orm): + # Adding model 'GroupRelationshipDataValue' + db.create_table(u'core_grouprelationshipdatavalue', ( + ('string_value', self.gf('django.db.models.fields.TextField')(null=True, blank=True)), + ('is_active', self.gf('django.db.models.fields.BooleanField')(default=True)), + ('last_modified', self.gf('vcweb.core.models.AutoDateTimeField')(default=datetime.datetime.now)), + ('float_value', self.gf('django.db.models.fields.FloatField')(null=True, blank=True)), + ('round_data', self.gf('django.db.models.fields.related.ForeignKey')(related_name='group_relationship_data_value_set', to=orm['core.RoundData'])), + ('boolean_value', self.gf('django.db.models.fields.NullBooleanField')(null=True, blank=True)), + ('group_relationship', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['core.GroupRelationship'])), + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('int_value', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)), + ('date_created', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now, db_index=True)), + ('parameter', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['core.Parameter'])), + )) + db.send_create_signal(u'core', ['GroupRelationshipDataValue']) + + # Deleting model 'GroupClusterDataValue' + db.delete_table(u'core_groupclusterdatavalue') + + # Deleting model 'GroupCluster' + db.delete_table(u'core_groupcluster') + + + # User chose to not deal with backwards NULL issues for 'GroupRelationship.second_group' + raise RuntimeError("Cannot reverse this migration. 'GroupRelationship.second_group' and its values cannot be restored.") + + # User chose to not deal with backwards NULL issues for 'GroupRelationship.first_group' + raise RuntimeError("Cannot reverse this migration. 'GroupRelationship.first_group' and its values cannot be restored.") + # Deleting field 'GroupRelationship.cluster' + db.delete_column(u'core_grouprelationship', 'cluster_id') + + # Deleting field 'GroupRelationship.group' + db.delete_column(u'core_grouprelationship', 'group_id') + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'auth.user': { + 'Meta': {'object_name': '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': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + '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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'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'}) + }, + u'core.activitylog': { + 'Meta': {'object_name': 'ActivityLog'}, + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'log_message': ('django.db.models.fields.TextField', [], {}) + }, + u'core.address': { + 'Meta': {'object_name': 'Address'}, + 'city': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'state': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), + 'street1': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'street2': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'zipcode': ('django.db.models.fields.CharField', [], {'max_length': '8', 'blank': 'True'}) + }, + u'core.chatmessage': { + 'Meta': {'ordering': "['date_created']", 'object_name': 'ChatMessage', '_ormbases': [u'core.ParticipantRoundDataValue']}, + u'participantrounddatavalue_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ParticipantRoundDataValue']", 'unique': 'True', 'primary_key': 'True'}), + 'target_participant': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'target_participant_chat_message_set'", 'null': 'True', 'to': u"orm['core.ParticipantGroupRelationship']"}) + }, + u'core.comment': { + 'Meta': {'ordering': "['date_created']", 'object_name': 'Comment', '_ormbases': [u'core.ParticipantRoundDataValue']}, + u'participantrounddatavalue_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ParticipantRoundDataValue']", 'unique': 'True', 'primary_key': 'True'}) + }, + u'core.experiment': { + 'Meta': {'ordering': "['date_created', 'status']", 'object_name': 'Experiment'}, + 'amqp_exchange_name': ('django.db.models.fields.CharField', [], {'default': "'vcweb.default.exchange'", 'max_length': '64'}), + 'authentication_code': ('django.db.models.fields.CharField', [], {'default': "'vcweb.auth.code'", 'max_length': '32'}), + 'current_round_elapsed_time': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'current_round_sequence_number': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}), + 'current_round_start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'duration': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), + 'experiment_configuration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentConfiguration']"}), + 'experiment_metadata': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentMetadata']"}), + 'experimenter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Experimenter']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_experimenter_driven': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'ready_participants': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'start_date_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'INACTIVE'", 'max_length': '32'}), + 'tick_duration': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), + 'total_elapsed_time': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}) + }, + u'core.experimentactivitylog': { + 'Meta': {'object_name': 'ExperimentActivityLog', '_ormbases': [u'core.ActivityLog']}, + u'activitylog_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ActivityLog']", 'unique': 'True', 'primary_key': 'True'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'activity_log_set'", 'to': u"orm['core.Experiment']"}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.experimentconfiguration': { + 'Meta': {'ordering': "['experiment_metadata', 'creator', 'date_created']", 'object_name': 'ExperimentConfiguration'}, + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_configuration_set'", 'to': u"orm['core.Experimenter']"}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'exchange_rate': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '6', 'decimal_places': '2', 'blank': 'True'}), + 'experiment_metadata': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_configuration_set'", 'to': u"orm['core.ExperimentMetadata']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invitation_subject': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'invitation_text': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'max_group_size': ('django.db.models.fields.PositiveIntegerField', [], {'default': '5'}), + 'max_number_of_participants': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'treatment_id': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}) + }, + u'core.experimenter': { + 'Meta': {'ordering': "['user']", 'object_name': 'Experimenter'}, + 'approved': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'authentication_token': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'failed_password_attempts': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'institution': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Institution']", 'null': 'True', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'experimenter'", 'unique': 'True', 'to': u"orm['auth.User']"}) + }, + u'core.experimenterrequest': { + 'Meta': {'object_name': 'ExperimenterRequest'}, + 'approved': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['auth.User']", 'unique': 'True'}) + }, + u'core.experimentmetadata': { + 'Meta': {'ordering': "['namespace', 'date_created']", 'object_name': 'ExperimentMetadata'}, + 'about_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'default_configuration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentConfiguration']", 'null': 'True', 'blank': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'logo_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'namespace': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'short_name': ('django.db.models.fields.SlugField', [], {'max_length': '32', 'unique': 'True', 'null': 'True', 'blank': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + u'core.experimentparametervalue': { + 'Meta': {'object_name': 'ExperimentParameterValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'experiment_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_parameter_value_set'", 'to': u"orm['core.ExperimentConfiguration']"}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + u'core.experimentsession': { + 'Meta': {'object_name': 'ExperimentSession'}, + 'capacity': ('django.db.models.fields.PositiveIntegerField', [], {'default': '20'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_session_set'", 'to': u"orm['auth.User']"}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'experiment_metadata': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_session_set'", 'to': u"orm['core.ExperimentMetadata']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invitation_text': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'scheduled_date': ('django.db.models.fields.DateTimeField', [], {}), + 'scheduled_end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}) + }, + u'core.group': { + 'Meta': {'ordering': "['experiment', 'number']", 'object_name': 'Group'}, + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Experiment']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'max_size': ('django.db.models.fields.PositiveIntegerField', [], {'default': '5'}), + 'number': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'session_id': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}) + }, + u'core.groupactivitylog': { + 'Meta': {'object_name': 'GroupActivityLog', '_ormbases': [u'core.ActivityLog']}, + u'activitylog_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ActivityLog']", 'unique': 'True', 'primary_key': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'activity_log_set'", 'to': u"orm['core.Group']"}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.groupcluster': { + 'Meta': {'object_name': 'GroupCluster'}, + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'session_id': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}) + }, + u'core.groupclusterdatavalue': { + 'Meta': {'object_name': 'GroupClusterDataValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + 'group_cluster': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.GroupCluster']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'round_data': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'group_cluster_data_value_set'", 'to': u"orm['core.RoundData']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + u'core.grouprelationship': { + 'Meta': {'object_name': 'GroupRelationship'}, + 'cluster': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'group_set'", 'to': u"orm['core.GroupCluster']"}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + u'core.grouprounddatavalue': { + 'Meta': {'ordering': "['round_data', 'group', 'parameter']", 'object_name': 'GroupRoundDataValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'data_value_set'", 'to': u"orm['core.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'round_data': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'group_data_value_set'", 'to': u"orm['core.RoundData']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + u'core.institution': { + 'Meta': {'object_name': 'Institution'}, + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}) + }, + u'core.invitation': { + 'Meta': {'object_name': 'Invitation'}, + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'experiment_session': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentSession']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'participant': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Participant']"}), + 'sender': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}) + }, + u'core.like': { + 'Meta': {'ordering': "['-date_created', 'round_data', 'participant_group_relationship', 'parameter']", 'object_name': 'Like', '_ormbases': [u'core.ParticipantRoundDataValue']}, + u'participantrounddatavalue_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ParticipantRoundDataValue']", 'unique': 'True', 'primary_key': 'True'}) + }, + u'core.parameter': { + 'Meta': {'ordering': "['name']", 'unique_together': "(('name', 'experiment_metadata', 'scope'),)", 'object_name': 'Parameter'}, + 'class_name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Experimenter']"}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'default_value_string': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'description': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'}), + 'display_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'enum_choices': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'experiment_metadata': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentMetadata']", 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_required': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'scope': ('django.db.models.fields.CharField', [], {'default': "'round'", 'max_length': '32'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '32'}) + }, + u'core.participant': { + 'Meta': {'ordering': "['user']", 'object_name': 'Participant'}, + 'address': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Address']", 'null': 'True', 'blank': 'True'}), + 'authentication_token': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'birthdate': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'can_receive_invitations': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'experiments': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'participant_set'", 'symmetrical': 'False', 'through': u"orm['core.ParticipantExperimentRelationship']", 'to': u"orm['core.Experiment']"}), + 'failed_password_attempts': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'gender': ('django.db.models.fields.CharField', [], {'max_length': '1', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'participant_set'", 'symmetrical': 'False', 'through': u"orm['core.ParticipantGroupRelationship']", 'to': u"orm['core.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'institution': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Institution']", 'null': 'True', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'participant'", 'unique': 'True', 'to': u"orm['auth.User']"}) + }, + u'core.participantexperimentrelationship': { + 'Meta': {'object_name': 'ParticipantExperimentRelationship'}, + 'additional_data': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}), + 'current_location': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'participant_relationship_set'", 'to': u"orm['core.Experiment']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_completed_round_sequence_number': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'participant': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_relationship_set'", 'to': u"orm['core.Participant']"}), + 'participant_identifier': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'sequential_participant_identifier': ('django.db.models.fields.PositiveIntegerField', [], {}) + }, + u'core.participantgrouprelationship': { + 'Meta': {'ordering': "['group', 'participant_number']", 'object_name': 'ParticipantGroupRelationship'}, + 'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'first_visit': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'participant_group_relationship_set'", 'to': u"orm['core.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'notifications_since': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'null': 'True', 'blank': 'True'}), + 'participant': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'participant_group_relationship_set'", 'to': u"orm['core.Participant']"}), + 'participant_number': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'round_joined': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.participantrounddatavalue': { + 'Meta': {'ordering': "['-date_created', 'round_data', 'participant_group_relationship', 'parameter']", 'object_name': 'ParticipantRoundDataValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'participant_group_relationship': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'participant_data_value_set'", 'to': u"orm['core.ParticipantGroupRelationship']"}), + 'round_data': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'participant_data_value_set'", 'to': u"orm['core.RoundData']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'submitted': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'target_data_value': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'target_data_value_set'", 'null': 'True', 'to': u"orm['core.ParticipantRoundDataValue']"}) + }, + u'core.participantsignup': { + 'Meta': {'object_name': 'ParticipantSignup'}, + 'attendance': ('django.db.models.fields.PositiveIntegerField', [], {'max_length': '1', 'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invitation': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'signup_set'", 'to': u"orm['core.Invitation']"}), + 'participant': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'signup_set'", 'to': u"orm['core.Participant']"}) + }, + u'core.quizquestion': { + 'Meta': {'object_name': 'QuizQuestion'}, + 'answer': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'default_quiz_question_set'", 'null': 'True', 'to': u"orm['core.Experiment']"}), + 'explanation': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'input_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'label': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'quiz_question_set'", 'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.roundconfiguration': { + 'Meta': {'ordering': "['experiment_configuration', 'sequence_number', 'date_created']", 'object_name': 'RoundConfiguration'}, + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'debriefing': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'display_number': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'duration': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'experiment_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'round_configuration_set'", 'to': u"orm['core.ExperimentConfiguration']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'instructions': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'preserve_existing_groups': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'randomize_groups': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'round_type': ('django.db.models.fields.CharField', [], {'default': "'REGULAR'", 'max_length': '32'}), + 'sequence_number': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'session_id': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'survey_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'template_name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}) + }, + u'core.rounddata': { + 'Meta': {'ordering': "['round_configuration']", 'object_name': 'RoundData'}, + 'elapsed_time': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'round_data_set'", 'to': u"orm['core.Experiment']"}), + 'experimenter_notes': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'round_data_set'", 'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.roundparametervalue': { + 'Meta': {'object_name': 'RoundParameterValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'round_parameter_value_set'", 'to': u"orm['core.RoundConfiguration']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + u'core.spoolparticipantstatistics': { + 'Meta': {'object_name': 'SpoolParticipantStatistics'}, + 'absences': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'discharges': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invitations': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'participant': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'spool_statistics_set'", 'to': u"orm['core.Participant']"}), + 'participations': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}) + } + } + + complete_apps = ['core'] \ No newline at end of file diff -r 80a34203bea7ed17f0d1d72b7921d81d485b0441 -r 43e7a5ca2e914ecd7bf3dc78fb373d6b88ecf5f7 vcweb/core/models.py --- a/vcweb/core/models.py +++ b/vcweb/core/models.py @@ -1255,7 +1255,6 @@ The experiment that contains this Group. """ session_id = models.CharField(max_length=64, null=True, blank=True) - related_groups = models.ManyToManyField('Group', through='GroupRelationship') @property def name(self): @@ -1462,10 +1461,15 @@ class Meta: ordering = ['experiment', 'number'] +class GroupCluster(models.Model): + date_created = models.DateTimeField(default=datetime.now) + name = models.CharField(max_length=64, null=True, blank=True) + session_id = models.CharField(max_length=64, null=True, blank=True) + class GroupRelationship(models.Model): date_created = models.DateTimeField(default=datetime.now) - first_group = models.ForeignKey(Group, related_name='first_group_relationship_set') - second_group = models.ForeignKey(Group, related_name='second_group_relationship_set') + cluster = models.ForeignKey(GroupCluster, related_name='group_set') + group = models.ForeignKey(Group) class RoundData(models.Model): """ @@ -1488,9 +1492,9 @@ class Meta: ordering = [ 'round_configuration' ] -class GroupRelationshipDataValue(ParameterizedValue): - group_relationship = models.ForeignKey(GroupRelationship) - round_data = models.ForeignKey(RoundData, related_name='group_relationship_data_value_set') +class GroupClusterDataValue(ParameterizedValue): + group_cluster = models.ForeignKey(GroupCluster) + round_data = models.ForeignKey(RoundData, related_name='group_cluster_data_value_set') class GroupRoundDataValue(ParameterizedValue): group = models.ForeignKey(Group, related_name='data_value_set') https://bitbucket.org/virtualcommons/vcweb/commits/71e47ee1a9af/ changeset: 71e47ee1a9af user: alllee date: 2013-03-15 05:02:35 summary: GroupClusters should know which Experiment they belong to affected #: 2 files diff -r 43e7a5ca2e914ecd7bf3dc78fb373d6b88ecf5f7 -r 71e47ee1a9af5c0e35439339bab5cf4f5ba9e199 vcweb/core/migrations/0022_auto__add_field_groupcluster_experiment.py --- /dev/null +++ b/vcweb/core/migrations/0022_auto__add_field_groupcluster_experiment.py @@ -0,0 +1,397 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding field 'GroupCluster.experiment' + db.add_column(u'core_groupcluster', 'experiment', + self.gf('django.db.models.fields.related.ForeignKey')(default=None, to=orm['core.Experiment']), + keep_default=False) + + + def backwards(self, orm): + # Deleting field 'GroupCluster.experiment' + db.delete_column(u'core_groupcluster', 'experiment_id') + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'auth.user': { + 'Meta': {'object_name': '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': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + '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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'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'}) + }, + u'core.activitylog': { + 'Meta': {'object_name': 'ActivityLog'}, + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'log_message': ('django.db.models.fields.TextField', [], {}) + }, + u'core.address': { + 'Meta': {'object_name': 'Address'}, + 'city': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'state': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), + 'street1': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'street2': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'zipcode': ('django.db.models.fields.CharField', [], {'max_length': '8', 'blank': 'True'}) + }, + u'core.chatmessage': { + 'Meta': {'ordering': "['date_created']", 'object_name': 'ChatMessage', '_ormbases': [u'core.ParticipantRoundDataValue']}, + u'participantrounddatavalue_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ParticipantRoundDataValue']", 'unique': 'True', 'primary_key': 'True'}), + 'target_participant': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'target_participant_chat_message_set'", 'null': 'True', 'to': u"orm['core.ParticipantGroupRelationship']"}) + }, + u'core.comment': { + 'Meta': {'ordering': "['date_created']", 'object_name': 'Comment', '_ormbases': [u'core.ParticipantRoundDataValue']}, + u'participantrounddatavalue_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ParticipantRoundDataValue']", 'unique': 'True', 'primary_key': 'True'}) + }, + u'core.experiment': { + 'Meta': {'ordering': "['date_created', 'status']", 'object_name': 'Experiment'}, + 'amqp_exchange_name': ('django.db.models.fields.CharField', [], {'default': "'vcweb.default.exchange'", 'max_length': '64'}), + 'authentication_code': ('django.db.models.fields.CharField', [], {'default': "'vcweb.auth.code'", 'max_length': '32'}), + 'current_round_elapsed_time': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'current_round_sequence_number': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}), + 'current_round_start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'duration': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), + 'experiment_configuration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentConfiguration']"}), + 'experiment_metadata': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentMetadata']"}), + 'experimenter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Experimenter']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_experimenter_driven': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'ready_participants': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'start_date_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'INACTIVE'", 'max_length': '32'}), + 'tick_duration': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), + 'total_elapsed_time': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}) + }, + u'core.experimentactivitylog': { + 'Meta': {'object_name': 'ExperimentActivityLog', '_ormbases': [u'core.ActivityLog']}, + u'activitylog_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ActivityLog']", 'unique': 'True', 'primary_key': 'True'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'activity_log_set'", 'to': u"orm['core.Experiment']"}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.experimentconfiguration': { + 'Meta': {'ordering': "['experiment_metadata', 'creator', 'date_created']", 'object_name': 'ExperimentConfiguration'}, + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_configuration_set'", 'to': u"orm['core.Experimenter']"}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'exchange_rate': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '6', 'decimal_places': '2', 'blank': 'True'}), + 'experiment_metadata': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_configuration_set'", 'to': u"orm['core.ExperimentMetadata']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invitation_subject': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'invitation_text': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'max_group_size': ('django.db.models.fields.PositiveIntegerField', [], {'default': '5'}), + 'max_number_of_participants': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'treatment_id': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}) + }, + u'core.experimenter': { + 'Meta': {'ordering': "['user']", 'object_name': 'Experimenter'}, + 'approved': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'authentication_token': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'failed_password_attempts': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'institution': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Institution']", 'null': 'True', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'experimenter'", 'unique': 'True', 'to': u"orm['auth.User']"}) + }, + u'core.experimenterrequest': { + 'Meta': {'object_name': 'ExperimenterRequest'}, + 'approved': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['auth.User']", 'unique': 'True'}) + }, + u'core.experimentmetadata': { + 'Meta': {'ordering': "['namespace', 'date_created']", 'object_name': 'ExperimentMetadata'}, + 'about_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'default_configuration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentConfiguration']", 'null': 'True', 'blank': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'logo_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'namespace': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'short_name': ('django.db.models.fields.SlugField', [], {'max_length': '32', 'unique': 'True', 'null': 'True', 'blank': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + u'core.experimentparametervalue': { + 'Meta': {'object_name': 'ExperimentParameterValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'experiment_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_parameter_value_set'", 'to': u"orm['core.ExperimentConfiguration']"}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + u'core.experimentsession': { + 'Meta': {'object_name': 'ExperimentSession'}, + 'capacity': ('django.db.models.fields.PositiveIntegerField', [], {'default': '20'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_session_set'", 'to': u"orm['auth.User']"}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'experiment_metadata': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_session_set'", 'to': u"orm['core.ExperimentMetadata']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invitation_text': ('... [truncated message content] |