virtualcommons-svn Mailing List for Virtual Commons Experiment Software (Page 33)
Status: Beta
Brought to you by:
alllee
You can subscribe to this list here.
2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
(21) |
Aug
(31) |
Sep
(6) |
Oct
(15) |
Nov
(2) |
Dec
(9) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2009 |
Jan
(4) |
Feb
(6) |
Mar
(12) |
Apr
(52) |
May
(14) |
Jun
(19) |
Jul
(81) |
Aug
(115) |
Sep
(36) |
Oct
(88) |
Nov
(46) |
Dec
(58) |
2010 |
Jan
(52) |
Feb
(55) |
Mar
(48) |
Apr
(15) |
May
(5) |
Jun
(38) |
Jul
(27) |
Aug
(24) |
Sep
(28) |
Oct
(1) |
Nov
(2) |
Dec
(29) |
2011 |
Jan
(87) |
Feb
(39) |
Mar
(63) |
Apr
(42) |
May
(26) |
Jun
(53) |
Jul
(23) |
Aug
(43) |
Sep
(37) |
Oct
(25) |
Nov
(4) |
Dec
(7) |
2012 |
Jan
(73) |
Feb
(79) |
Mar
(62) |
Apr
(28) |
May
(12) |
Jun
(2) |
Jul
(9) |
Aug
(1) |
Sep
(8) |
Oct
|
Nov
(3) |
Dec
(3) |
2013 |
Jan
(8) |
Feb
(16) |
Mar
(38) |
Apr
(74) |
May
(62) |
Jun
(15) |
Jul
(49) |
Aug
(19) |
Sep
(9) |
Oct
|
Nov
|
Dec
|
2014 |
Jan
|
Feb
|
Mar
|
Apr
(2) |
May
(25) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <vir...@li...> - 2011-05-14 00:24:02
|
Subject: hg.virtualcommons 364 details: http://virtualcommons.hg.sourceforge.net:8000/hgroot/virtualcommons/virtualcommons/hgrepo/v/vi/virtualcommons/virtualcommons/rev/e968bd915583 changeset: 364:e968bd915583 user: Allen Lee <all...@as...> date: Fri May 13 17:23:53 2011 -0700 description: adding guard for non-playable rounds diffstat: vcweb/core/models.py | 7 +++++-- vcweb/forestry/models.py | 7 +++---- 2 files changed, 8 insertions(+), 6 deletions(-) diffs (48 lines): diff -r 96461595018a -r e968bd915583 vcweb/core/models.py --- a/vcweb/core/models.py Fri May 13 17:05:41 2011 -0700 +++ b/vcweb/core/models.py Fri May 13 17:23:53 2011 -0700 @@ -412,10 +412,13 @@ self.register_participants(users=users, institution=institution) def initialize_parameters(self, group_parameters=None, participant_parameters=None): + if not self.is_playable_round: + logger.warn("ignoring request to initialize parameters for round %s", self.current_round) + return if group_parameters is None: - group_parameters = [] + group_parameters = self.parameters(scope=Parameter.GROUP_SCOPE) if participant_parameters is None: - participant_parameters = [] + participant_parameters = self.parameters(scope=Parameter.PARTICIPANT_SCOPE) current_round_data = self.current_round_data for group in self.groups.select_related(depth=1).all(): for parameter in group_parameters: diff -r 96461595018a -r e968bd915583 vcweb/forestry/models.py --- a/vcweb/forestry/models.py Fri May 13 17:05:41 2011 -0700 +++ b/vcweb/forestry/models.py Fri May 13 17:23:53 2011 -0700 @@ -1,6 +1,5 @@ from django.dispatch import receiver -from vcweb.core.models import (ExperimentMetadata, Parameter, ParticipantGroupRelationship, - ParticipantRoundDataValue,Group) +from vcweb.core.models import (ExperimentMetadata, Parameter, ParticipantRoundDataValue) from vcweb.core import signals, simplecache from celery.decorators import task import logging @@ -108,7 +107,7 @@ group_parameters=(regrowth_parameter, group_harvest_parameter, resource_level_parameter), participant_parameters=[harvest_decision_parameter]) ''' - practice or regular round, set up resource levels and participant + during a practice or regular round, set up resource levels and participant harvest decision parameters ''' if round_configuration.get_parameter_value('reset.resource_level', default=False): @@ -124,7 +123,7 @@ def round_teardown(experiment, **kwargs): ''' round teardown calculates new resource levels for practice or regular rounds based on the group harvest and resultant regrowth and transferring''' - logger.debug("forestry: round_teardown for %s", experiment) + logger.debug("%s", experiment) resource_level_parameter = get_resource_level_parameter() current_round_configuration = experiment.current_round max_resource_level = 100 |
From: <vir...@li...> - 2011-05-14 00:05:48
|
Subject: hg.virtualcommons 363 details: http://virtualcommons.hg.sourceforge.net:8000/hgroot/virtualcommons/virtualcommons/hgrepo/v/vi/virtualcommons/virtualcommons/rev/96461595018a changeset: 363:96461595018a user: Allen Lee <all...@as...> date: Fri May 13 17:05:41 2011 -0700 description: removing group.initialize_data_parameters in favor of initializing all parameters (group and participant) at round_start diffstat: vcweb/core/models.py | 7 +--- vcweb/core/tests.py | 62 ++++++++++++------------------- vcweb/forestry/models.py | 2 +- vcweb/forestry/tests.py | 17 ++++++++ 4 files changed, 43 insertions(+), 45 deletions(-) diffs (163 lines): diff -r 40f32088cbde -r 96461595018a vcweb/core/models.py --- a/vcweb/core/models.py Fri May 13 15:03:47 2011 -0700 +++ b/vcweb/core/models.py Fri May 13 17:05:41 2011 -0700 @@ -450,7 +450,6 @@ self.groups.all().delete() # seed the initial group. current_group = self.groups.create(number=1, max_size=self.experiment_configuration.max_group_size) - current_group.initialize_data_parameters() participants = list(self.participants.all()) if randomize: random.shuffle(participants) @@ -458,7 +457,6 @@ for p in participants: if current_group.is_full: current_group = current_group.create_next_group() - current_group.initialize_data_parameters() current_group.add_participant(p) # XXX: if there a performance hit here, should probably do a void return instead @@ -486,9 +484,6 @@ self.current_round_elapsed_time = 0 self.current_round_sequence_number += 1 self.save() - # initialize group parameters if necessary - for g in self.groups.all(): - g.initialize_data_parameters() else: logger.warning("trying to advance past the last round - no-op") @@ -926,7 +921,6 @@ ''' Initializes data parameters for all groups in this round, as necessary. If this round already has data parameters, is a no-op. - ''' def initialize_data_parameters(self): if self.current_round.is_playable_round: round_data = self.current_round_data @@ -936,6 +930,7 @@ for group_data_parameter in self.data_parameters: self.data_values.create(round_data=round_data, parameter=group_data_parameter) + ''' ''' Not as efficient as a simple SQL update because we need to do some type diff -r 40f32088cbde -r 96461595018a vcweb/core/tests.py --- a/vcweb/core/tests.py Fri May 13 15:03:47 2011 -0700 +++ b/vcweb/core/tests.py Fri May 13 17:05:41 2011 -0700 @@ -170,6 +170,30 @@ self.assertEqual(experiment.current_round_elapsed_time, current_round_elapsed_time + 1) self.assertEqual(experiment.total_elapsed_time, total_elapsed_time + 1) + def test_instructions_round_parameters(self): + e = self.experiment + e.activate() + e.start_round() + # instructions round + current_round_data = e.current_round_data + self.assertEqual(current_round_data.group_data_values.count(), 0) + self.assertEqual(current_round_data.participant_data_values.count(), 0) + + def test_playable_round(self): + e = self.advance_to_data_round() + e.start_round() + current_round_data = e.current_round_data + for group in e.groups.all(): + for parameter in group.data_parameters.all(): + group_data_value, created = current_round_data.group_data_values.get_or_create(group=group, + parameter=parameter) + self.assertFalse(created) + for pgr in group.participant_group_relationships.all(): + for parameter in e.parameters(scope=Parameter.PARTICIPANT_SCOPE): + participant_data_value, created = current_round_data.participant_data_values.get_or_create(participant_group_relationship=pgr, + parameter=parameter) + self.assertFalse(created) + class GroupTest(BaseVcwebTest): def test_set_data_value_activity_log(self): e = self.advance_to_data_round() @@ -204,44 +228,6 @@ g.transfer_to_next_round(parameter) e.advance_to_next_round() - def test_initialize_data_parameters(self): - e = self.experiment - e.activate() - e.start_round() - # instructions round - for g in e.groups.all(): - g.initialize_data_parameters() - self.assertEqual(e.current_round_data.group_data_values.count(), 0) - self.assertEqual(e.current_round_data.participant_data_values.count(), 0) - # quiz round - e.advance_to_next_round() - e.start_round() - for g in e.groups.all(): - g.initialize_data_parameters() -# FIXME: (changed to practice round for demo purposes) - #self.assertEqual(e.current_round_data.group_data_values.count(), 0) - #self.assertEqual(e.current_round_data.participant_data_values.count(), 0) - # first practice round - e.advance_to_next_round() - e.start_round() - for g in e.groups.all(): - for i in xrange(10): - self.assertEqual(e.current_round_data.group_data_values.count(), 2) - # multiple invocations to initialize_data_parameters should be harmless. - g.initialize_data_parameters() - self.assertEqual(e.current_round_data.group_data_values.count(), 2) - g.initialize_data_parameters() - self.assertEqual(e.current_round_data.group_data_values.count(), 2) - g.initialize_data_parameters() - # first chat round (practice) - e.end_round() - e.advance_to_next_round() - e.start_round() - for g in e.groups.all(): - g.initialize_data_parameters() - self.assertEqual(e.current_round_data.group_data_values.count(), 2) - self.assertEqual(e.current_round_data.participant_data_values.count(), 0) - # second practice round def test_group_add(self): diff -r 40f32088cbde -r 96461595018a vcweb/forestry/models.py --- a/vcweb/forestry/models.py Fri May 13 15:03:47 2011 -0700 +++ b/vcweb/forestry/models.py Fri May 13 17:05:41 2011 -0700 @@ -106,7 +106,7 @@ # initialize group and participant data values experiment.initialize_parameters( group_parameters=(regrowth_parameter, group_harvest_parameter, resource_level_parameter), - participant_parameters=(harvest_decision_parameter)) + participant_parameters=[harvest_decision_parameter]) ''' practice or regular round, set up resource levels and participant harvest decision parameters diff -r 40f32088cbde -r 96461595018a vcweb/forestry/tests.py --- a/vcweb/forestry/tests.py Fri May 13 15:03:47 2011 -0700 +++ b/vcweb/forestry/tests.py Fri May 13 17:05:41 2011 -0700 @@ -95,6 +95,23 @@ ''' class ForestryParametersTest(BaseVcwebTest): + def test_initialize_parameters_at_round_start(self): + e = self.advance_to_data_round() + e.start_round() + current_round_data = e.current_round_data + group_parameters = (get_regrowth_parameter(), get_group_harvest_parameter(), get_resource_level_parameter()) + for group in e.groups.select_related(depth=1).all(): + for parameter in group_parameters: + group_data_value = group.data_values.get(round_data=current_round_data, parameter=parameter) + self.assertTrue(group_data_value.parameter in group_parameters) + self.assertTrue(group_data_value) +# single participant data parameter, harvest decisions + for pgr in group.participant_group_relationships.all(): + prdv = pgr.round_data_values.get(round_data=current_round_data, + parameter=get_harvest_decision_parameter()) + self.assertTrue(prdv) + self.assertEquals(prdv.parameter, get_harvest_decision_parameter()) + def test_get_set_harvest_decisions(self): e = self.advance_to_data_round() # generate harvest decisions |
From: <vir...@li...> - 2011-05-13 22:56:37
|
Subject: hg.virtualcommons 362 details: http://virtualcommons.hg.sourceforge.net:8000/hgroot/virtualcommons/virtualcommons/hgrepo/v/vi/virtualcommons/virtualcommons/rev/40f32088cbde changeset: 362:40f32088cbde user: Allen Lee <all...@as...> date: Fri May 13 15:03:47 2011 -0700 description: initializing all group and participant params at round_started diffstat: vcweb/core/models.py | 20 ++++++++++++++++++-- vcweb/core/views.py | 7 ++----- vcweb/forestry/models.py | 36 ++++++++++++++---------------------- 3 files changed, 34 insertions(+), 29 deletions(-) diffs (135 lines): diff -r ab025f13a7d3 -r 40f32088cbde vcweb/core/models.py --- a/vcweb/core/models.py Fri May 13 13:30:14 2011 -0700 +++ b/vcweb/core/models.py Fri May 13 15:03:47 2011 -0700 @@ -411,6 +411,21 @@ users.append(user) self.register_participants(users=users, institution=institution) + def initialize_parameters(self, group_parameters=None, participant_parameters=None): + if group_parameters is None: + group_parameters = [] + if participant_parameters is None: + participant_parameters = [] + current_round_data = self.current_round_data + for group in self.groups.select_related(depth=1).all(): + for parameter in group_parameters: + group_data_value, created = current_round_data.group_data_values.get_or_create(group=group, parameter=parameter) + logger.debug("%s (%s)", group_data_value, created) + for pgr in group.participant_group_relationships.all(): + for parameter in participant_parameters: + participant_data_value, created = current_round_data.participant_data_values.get_or_create(participant_group_relationship=pgr, parameter=parameter) + logger.debug("%s (%s)", participant_data_value, created) + def log(self, log_message): if log_message: self.activity_log.create(round_configuration=self.current_round, log_message=log_message) @@ -804,7 +819,7 @@ return value def __unicode__(self): - return u"%s parameter: %s (%s, %s)" % (self.experiment_metadata.namespace, self.name, self.type, self.scope) + return u"%s (type:%s, scope:%s, experiment: %s)" % (self.name, self.type, self.scope, self.experiment_metadata) class Meta: ordering = ['name'] @@ -1076,7 +1091,8 @@ return self.round_data.round_configuration def __unicode__(self): - return u"data value {0}: {1} (group {2}, round {3})".format(self.parameter, self.value, self.group, self.round_configuration) + return u"{0}={1} ({2}, {3})".format(self.parameter, self.value, self.group, self.round_configuration) + class Meta: ordering = [ 'round_data', 'group', 'parameter' ] diff -r ab025f13a7d3 -r 40f32088cbde vcweb/core/views.py --- a/vcweb/core/views.py Fri May 13 13:30:14 2011 -0700 +++ b/vcweb/core/views.py Fri May 13 15:03:47 2011 -0700 @@ -31,10 +31,7 @@ context_object_name = 'experiments' def get_template_names(self): user = self.request.user - if is_experimenter(user): - return ['experimenter/dashboard.html'] - else: - return ['participant/dashboard.html'] + return ['experimenter/dashboard.html'] if is_experimenter(user) else ['participant/dashboard.html'] def get_queryset(self): user = self.request.user if is_experimenter(user): @@ -46,7 +43,7 @@ if not experiment.experiment_metadata in experiment_dict: experiment_dict[experiment.experiment_metadata] = dict([(choice[0], list()) for choice in Experiment.STATUS_CHOICES]) experiment_dict[experiment.experiment_metadata][experiment.status].append(experiment) - logger.debug("experiment_dict %s" % experiment_dict) + logger.info("experiment_dict %s", experiment_dict) return experiment_dict def set_authentication_token(user, authentication_token=None): diff -r ab025f13a7d3 -r 40f32088cbde vcweb/forestry/models.py --- a/vcweb/forestry/models.py Fri May 13 13:30:14 2011 -0700 +++ b/vcweb/forestry/models.py Fri May 13 15:03:47 2011 -0700 @@ -1,5 +1,6 @@ from django.dispatch import receiver -from vcweb.core.models import (ExperimentMetadata, Parameter, ParticipantGroupRelationship, ParticipantRoundDataValue,) +from vcweb.core.models import (ExperimentMetadata, Parameter, ParticipantGroupRelationship, + ParticipantRoundDataValue,Group) from vcweb.core import signals, simplecache from celery.decorators import task import logging @@ -93,22 +94,19 @@ group.set_data_value(parameter=get_resource_level_parameter(), value=value) def round_setup(experiment, **kwargs): - logger.debug("forestry: round_setup for %s", experiment) + logger.debug(experiment) round_configuration = experiment.current_round - ''' - FIXME: replace with dict-based dispatch on round_configuration.round_type? - ''' - if round_configuration.is_instructions_round: - logger.debug("set up instructions round") - # do instructions stuff - elif round_configuration.is_quiz_round: - logger.debug("setting up quiz round") - elif round_configuration.is_chat_round: - logger.debug("set up chat round") - elif round_configuration.is_debriefing_round: - logger.debug("set up debriefing round") - if round_configuration.is_playable_round: + # participant parameter + harvest_decision_parameter = get_harvest_decision_parameter() + # group parameters + regrowth_parameter = get_regrowth_parameter() + group_harvest_parameter = get_group_harvest_parameter() + resource_level_parameter = get_resource_level_parameter() + # initialize group and participant data values + experiment.initialize_parameters( + group_parameters=(regrowth_parameter, group_harvest_parameter, resource_level_parameter), + participant_parameters=(harvest_decision_parameter)) ''' practice or regular round, set up resource levels and participant harvest decision parameters @@ -119,12 +117,6 @@ ''' set resource level to initial default ''' group.log("Setting resource level to initial value [%s]" % initial_resource_level) set_resource_level(group, initial_resource_level) - ''' initialize participant data values ''' - current_round_data = experiment.current_round_data - harvest_decision_parameter = get_harvest_decision_parameter() - for pgr in ParticipantGroupRelationship.objects.filter(group__experiment=experiment): - harvest_decision, created = current_round_data.participant_data_values.get_or_create(participant_group_relationship=pgr, parameter=harvest_decision_parameter) - logger.debug("%s (%s)", harvest_decision, created) @task def stop_round_task(): @@ -137,7 +129,7 @@ current_round_configuration = experiment.current_round max_resource_level = 100 for group in experiment.groups.all(): - # FIXME: simplify logic + # FIXME: simplify logic if has_resource_level(group): current_resource_level = get_resource_level(group) if current_round_configuration.is_playable_round: |
From: <vir...@li...> - 2011-05-13 20:30:28
|
Subject: hg.virtualcommons 361 details: http://virtualcommons.hg.sourceforge.net:8000/hgroot/virtualcommons/virtualcommons/hgrepo/v/vi/virtualcommons/virtualcommons/rev/ab025f13a7d3 changeset: 361:ab025f13a7d3 user: Allen Lee <all...@as...> date: Fri May 13 13:30:14 2011 -0700 description: moving logging configuration after importing local settings diffstat: vcweb/settings.py | 157 +++++++++++++++++++++++++-------------------------- 1 files changed, 77 insertions(+), 80 deletions(-) diffs (178 lines): diff -r dde03a53a2e7 -r ab025f13a7d3 vcweb/settings.py --- a/vcweb/settings.py Fri May 13 12:56:25 2011 -0700 +++ b/vcweb/settings.py Fri May 13 13:30:14 2011 -0700 @@ -1,89 +1,10 @@ # Django settings for vcweb project. from os import path, makedirs -import logging import sys DEBUG = True TEMPLATE_DEBUG = DEBUG -LOG_DIRECTORY = 'logs' -try: - makedirs(LOG_DIRECTORY) -except OSError: - pass - - -# logging configuration -VCWEB_LOG_FILENAME = 'vcweb.log' -TORNADIO_LOG_FILENAME = 'tornadio.log' - -LOGGING = { - 'version': 1, - 'disable_existing_loggers': True, - 'formatters': { - 'verbose': { - 'format': '%(levelname)s %(asctime)s [%(name)s|%(funcName)s:%(lineno)d] %(message)s' - }, - 'simple': { - 'format': '%(levelname)s %(message)s' - }, - }, - 'handlers': { - 'null': { - 'level':'DEBUG', - 'class':'django.utils.log.NullHandler', - }, - 'stdout':{ - 'level':'DEBUG', - 'class':'logging.StreamHandler', - 'formatter': 'verbose', - 'stream':sys.stdout, - }, - 'stderr':{ - 'level': 'DEBUG', - 'class':'logging.StreamHandler', - 'formatter': 'verbose', - 'stream':sys.stderr, - }, - 'vcweb-file': { - 'level': 'DEBUG', - 'class':'logging.handlers.RotatingFileHandler', - 'formatter': 'verbose', - 'filename': path.join(LOG_DIRECTORY, VCWEB_LOG_FILENAME), - 'backupCount': 6, - 'maxBytes': 10000000, - }, - 'tornadio-file': { - 'level': 'DEBUG', - 'class':'logging.handlers.RotatingFileHandler', - 'formatter': 'verbose', - 'filename': path.join(LOG_DIRECTORY, TORNADIO_LOG_FILENAME), - 'backupCount': 6, - 'maxBytes': 10000000, - }, - }, - 'loggers': { - 'django': { - 'handlers':['null'], - 'propagate': True, - 'level':'INFO', - }, - 'django.request': { - 'handlers': ['null'], - 'level': 'ERROR', - 'propagate': False, - }, - 'vcweb': { - 'handlers': ['vcweb-file', 'stdout'], - 'level': 'DEBUG', - }, - 'tornadio.vcweb': { - 'handlers': ['tornadio-file', 'stderr'], - 'level': 'DEBUG', - 'propagate': False, - }, - } -} ADMINS = ( ('Allen Lee', 'all...@as...') @@ -230,7 +151,83 @@ try: from settings_local import * except ImportError: - logging.debug("Couldn't load local settings") pass +LOG_DIRECTORY = 'logs' if DEBUG else '/opt/vcweb/logs' +try: + makedirs(LOG_DIRECTORY) +except OSError: + pass +# logging configuration +VCWEB_LOG_FILENAME = 'vcweb.log' +TORNADIO_LOG_FILENAME = 'tornadio.log' + +LOGGING = { + 'version': 1, + 'disable_existing_loggers': True, + 'formatters': { + 'verbose': { + 'format': '%(levelname)s %(asctime)s [%(name)s|%(funcName)s:%(lineno)d] %(message)s' + }, + 'simple': { + 'format': '%(levelname)s %(message)s' + }, + }, + 'handlers': { + 'null': { + 'level':'DEBUG', + 'class':'django.utils.log.NullHandler', + }, + 'stdout':{ + 'level':'DEBUG', + 'class':'logging.StreamHandler', + 'formatter': 'verbose', + 'stream':sys.stdout, + }, + 'stderr':{ + 'level': 'DEBUG', + 'class':'logging.StreamHandler', + 'formatter': 'verbose', + 'stream':sys.stderr, + }, + 'vcweb-file': { + 'level': 'DEBUG', + 'class':'logging.handlers.RotatingFileHandler', + 'formatter': 'verbose', + 'filename': path.join(LOG_DIRECTORY, VCWEB_LOG_FILENAME), + 'backupCount': 6, + 'maxBytes': 10000000, + }, + 'tornadio-file': { + 'level': 'DEBUG', + 'class':'logging.handlers.RotatingFileHandler', + 'formatter': 'verbose', + 'filename': path.join(LOG_DIRECTORY, TORNADIO_LOG_FILENAME), + 'backupCount': 6, + 'maxBytes': 10000000, + }, + }, + 'loggers': { + 'django': { + 'handlers':['null'], + 'propagate': True, + 'level':'INFO', + }, + 'django.request': { + 'handlers': ['null'], + 'level': 'ERROR', + 'propagate': False, + }, + 'vcweb': { + 'handlers': ['vcweb-file', 'stdout'], + 'level': 'DEBUG', + }, + 'tornadio.vcweb': { + 'handlers': ['tornadio-file', 'stderr'], + 'level': 'DEBUG', + 'propagate': False, + }, + } +} + |
From: <vir...@li...> - 2011-05-13 19:56:34
|
Subject: hg.virtualcommons 360 details: http://virtualcommons.hg.sourceforge.net:8000/hgroot/virtualcommons/virtualcommons/hgrepo/v/vi/virtualcommons/virtualcommons/rev/dde03a53a2e7 changeset: 360:dde03a53a2e7 user: Allen Lee <all...@as...> date: Fri May 13 12:56:25 2011 -0700 description: updating logging dict configuration and version bumps for jquery diffstat: vcweb/core/decorators.py | 4 +- vcweb/core/forms.py | 5 +- vcweb/core/models.py | 35 ++++++++--------- vcweb/core/templates/base.html | 2 +- vcweb/core/templates/experimenter/monitor.html | 2 +- vcweb/core/templates/includes/jquery.ui.html | 6 ++- vcweb/core/tests.py | 8 +-- vcweb/forestry/models.py | 6 +- vcweb/forestry/views.py | 6 +- vcweb/settings.py | 48 +++++++++++++++--------- vcweb/static/images/famfamfam/user_add.png | vcweb/vcwebio.py | 49 +++++++++++------------- 12 files changed, 89 insertions(+), 82 deletions(-) diffs (575 lines): diff -r c9bc3e12b102 -r dde03a53a2e7 vcweb/core/decorators.py --- a/vcweb/core/decorators.py Wed May 11 07:08:50 2011 -0700 +++ b/vcweb/core/decorators.py Fri May 13 12:56:25 2011 -0700 @@ -34,10 +34,10 @@ def decorator(fn): def _decorated_view(request, *args, **kwargs): if is_valid_user(request.user): - logger.debug('user was valid: %s' % request.user) + logger.debug('user was valid: %s', request.user) return fn(request, *args, **kwargs) else: - logger.debug('user was invalid, redirecting to %s' % redirect_to) + logger.debug('user was invalid, redirecting to %s', redirect_to) return redirect(redirect_to) _decorated_view.__name__ = fn.__name__ _decorated_view.__dict__ = fn.__dict__ diff -r c9bc3e12b102 -r dde03a53a2e7 vcweb/core/forms.py --- a/vcweb/core/forms.py Wed May 11 07:08:50 2011 -0700 +++ b/vcweb/core/forms.py Fri May 13 12:56:25 2011 -0700 @@ -95,15 +95,14 @@ if institution_name is None and institution_url is None: self.institution = None else: - logger.debug("get or create institution with name [%s] and url [%s]" % (institution_name, - institution_url)) + logger.debug("get or create institution with name [%s] and url [%s]", institution_name, institution_url) (institution, created) = Institution.objects.get_or_create(name=institution_name, url=institution_url) self.institution = institution return self.cleaned_data class RegisterSimpleParticipantsForm(RegisterParticipantsForm): - email_suffix = forms.CharField(min_length=3, initial='asu.edu', + email_suffix = forms.CharField(min_length=3, initial='asu.edu', help_text='An email suffix without the "@" symbol. Generated participants will have usernames of the format s1..sn@email_suffix. For example, if you register 20 participants with an email suffix of example.edu, the system will generate 20 participants with usernames ranging from s1...@ex..., s2...@ex..., s3...@ex..., ... s2...@ex....') number_of_participants = forms.IntegerField(min_value=1, help_text='The number of participants to register with this experiment.') diff -r c9bc3e12b102 -r dde03a53a2e7 vcweb/core/models.py --- a/vcweb/core/models.py Wed May 11 07:08:50 2011 -0700 +++ b/vcweb/core/models.py Fri May 13 12:56:25 2011 -0700 @@ -27,8 +27,8 @@ controlled experiments and for longer-scale experiments use 1 minute granularity for performance sake. """ def second_tick_handler(sender, time=None, **kwargs): - logger.debug("handling second tick signal at %s" % time) - logger.debug("kwargs: %s" % kwargs) + logger.debug("handling second tick signal at %s", time) + logger.debug("kwargs: %s", kwargs) # inspect all active experiments and update their time left Experiment.objects.increment_elapsed_time(status='ROUND_IN_PROGRESS') @@ -369,8 +369,7 @@ def register_participants(self, users=None, emails=None, institution=None, password=None): if self.participants.count() > 0: - logger.warning("This experiment %s already has %d participants - aborting" % (self, - self.participants.count())) + logger.warning("This experiment %s already has %d participants - aborting", self, self.participants.count()) return if users is None: users = [] @@ -397,8 +396,7 @@ ''' hardcoded defaults for the slovakia pretest ''' def setup_test_participants(self, count=20, institution=None, email_suffix='sav.sk', password='test'): if self.participants.count() > 0: - logger.warning("This experiment %s already has %d participants - aborting" - % (self, self.participants.count())) + logger.warning("This experiment %s already has %d participants - aborting", self, self.participants.count()) return users = [] for i in xrange(1, count+1): @@ -491,7 +489,7 @@ sender = self.experiment_metadata.pk if sender is None else sender #sender = self.namespace.encode('utf-8') # notify registered game handlers - logger.debug("About to send round started signal with sender %s" % sender) + logger.debug("About to send round started signal with sender %s", sender) return signals.round_started.send(sender, experiment=self, time=datetime.now(), round_configuration=self.current_round) def end_round(self, sender=None): @@ -501,7 +499,7 @@ self.log('Ending round with elapsed time %s' % self.current_round_elapsed_time) sender = self.experiment_metadata.pk if sender is None else sender #sender = self.namespace.encode('utf-8') - logger.debug("about to send round ended signal with sender %s" % sender) + logger.debug("about to send round ended signal with sender %s", sender) return signals.round_ended.send(sender, experiment=self, round_configuration=self.current_round) def stop(self): @@ -542,7 +540,7 @@ ParticipantExperimentRelationship.objects.create(participant=participant, experiment=experiment, created_by=self.experimenter.user) else: - logger.warning("Tried to transfer participants to an experiment %s that already had participants %s" % (experiment, experiment.participants.all())) + logger.warning("Tried to transfer participants to an experiment %s that already had participants %s", experiment, experiment.participants.all()) def __unicode__(self): return u"%s #%s | %s" % (self.experiment_metadata.title, self.pk, self.experimenter) @@ -641,7 +639,7 @@ parameter = Parameter.objects.get(name=name, scope=Parameter.ROUND_SCOPE) round_parameter, created = self.round_parameter_values.get_or_create(parameter=parameter) if created: - logger.debug("created new parameter %s for %s" % (parameter, self)) + logger.debug("created new parameter %s for %s", parameter, self) return round_parameter def set_parameter(self, name=None, value=None): @@ -918,7 +916,7 @@ if self.current_round.is_playable_round: round_data = self.current_round_data if round_data.group_data_values.filter(group=self).count() == 0: - logger.debug("no group data values for the current round %s, creating new ones." % round_data) + logger.debug("no group data values for the current round %s, creating new ones.", round_data) self.log("Initializing %s data parameters" % round_data) for group_data_parameter in self.data_parameters: self.data_values.create(round_data=round_data, parameter=group_data_parameter) @@ -947,7 +945,7 @@ ''' updated_rows = self.data_values.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) + logger.error("Updated %s rows, should have been only one.", updated_rows) ''' data_value = self.current_round_data.data_values.get(parameter=parameter) data_value.value += amount @@ -968,7 +966,7 @@ criteria = self._data_parameter_criteria(parameter=parameter, parameter_name=parameter_name, round_data=round_data) data_value, created = self.data_values.get_or_create(**criteria) if created: - logger.debug("Created new data value in get_data_value: %s" % data_value) + logger.debug("Created new data value in get_data_value: %s", data_value) return data_value def _data_parameter_criteria(self, parameter=None, parameter_name=None, round_data=None): @@ -997,7 +995,7 @@ ''' def transfer_to_next_round(self, parameter=None, value=None, transfer_existing_value=True): if self.experiment.is_last_round: - logger.warning("Trying to transfer parameter %s to next round but this is the last round" % parameter) + logger.warning("Trying to transfer parameter %s to next round but this is the last round", parameter) return value = self.get_scalar_data_value(parameter=parameter) if transfer_existing_value else value if not parameter: @@ -1008,8 +1006,9 @@ def transfer_parameter(self, parameter, value): next_round_data, created = self.experiment.round_data.get_or_create(round_configuration=self.experiment.next_round) - logger.debug("next round data: %s (%s)" % (next_round_data, "created" if created else "retrieved")) + logger.debug("next round data: %s (%s)", next_round_data, created) group_data_value, created = next_round_data.group_data_values.get_or_create(group=self, parameter=parameter, defaults={'value': value}) + logger.debug("group data value %s (%s)", group_data_value, created) if not created: group_data_value.value = value group_data_value.save() @@ -1029,7 +1028,7 @@ """ def add_participant(self, participant): if not participant: - logger.warning("Trying to add invalid participant %s to group %s" % (participant, self)) + logger.warning("Trying to add invalid participant %s to group %s", participant, self) return self ''' add the participant to this group if there is room, otherwise create and add to a fresh group ''' @@ -1151,7 +1150,7 @@ try: return self.select_related(depth=1).get(group__experiment=experiment, participant=participant) except ParticipantGroupRelationship.DoesNotExist: - logger.warning("Participant %s does not belong to a group in %s" % (participant, experiment)) + logger.warning("Participant %s does not belong to a group in %s", participant, experiment) return None class ParticipantGroupRelationship(models.Model): @@ -1186,7 +1185,7 @@ participant_data_value.submitted = True participant_data_value.save() else: - logger.warning("Unable to set data value %s on round data %s for %s" % (value, current_round_data, parameter)) + logger.warning("Unable to set data value %s on round data %s for %s", value, current_round_data, parameter) def __unicode__(self): diff -r c9bc3e12b102 -r dde03a53a2e7 vcweb/core/templates/base.html --- a/vcweb/core/templates/base.html Wed May 11 07:08:50 2011 -0700 +++ b/vcweb/core/templates/base.html Fri May 13 12:56:25 2011 -0700 @@ -10,7 +10,7 @@ <link href="{{STATIC_URL}}css/guarantee/style.css" rel="stylesheet" type="text/css" media="screen" /> <link href="{{STATIC_URL}}css/style.css" rel="stylesheet" type="text/css" media="screen" /> <!-- vcweb common js --> - <script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js'></script> + <script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js'></script> <script type='text/javascript' src='{{STATIC_URL}}js/common.js'></script> <script type='text/javascript' src='{{STATIC_URL}}js/jquery.qtip-1.0.0-rc3.min.js'></script> {% include "includes/jquery.ui.html" %} diff -r c9bc3e12b102 -r dde03a53a2e7 vcweb/core/templates/experimenter/monitor.html --- a/vcweb/core/templates/experimenter/monitor.html Wed May 11 07:08:50 2011 -0700 +++ b/vcweb/core/templates/experimenter/monitor.html Fri May 13 12:56:25 2011 -0700 @@ -42,9 +42,9 @@ }); }); $('#statusSpinner').hide(); + $('#statusDiv [title]').qtip(qtipOptions); $('#statusDiv').show('fast'); $('#experimentData').show('fast'); - $('#statusDiv [title]').qtip(qtipOptions); if (round_data_count > 0) { $('#experimentData').accordion({ active: active_round_number - 1, diff -r c9bc3e12b102 -r dde03a53a2e7 vcweb/core/templates/includes/jquery.ui.html --- a/vcweb/core/templates/includes/jquery.ui.html Wed May 11 07:08:50 2011 -0700 +++ b/vcweb/core/templates/includes/jquery.ui.html Fri May 13 12:56:25 2011 -0700 @@ -1,2 +1,4 @@ -<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.11/themes/pepper-grinder/jquery-ui.css" rel="stylesheet" type="text/css" media="screen" /> -<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.11/jquery-ui.min.js"></script> +{% with jquery_ui_version="1.8.12" %} +<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/{{jquery_ui_version}}/themes/pepper-grinder/jquery-ui.css" rel="stylesheet" type="text/css" media="screen" /> +<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/{{jquery_ui_version}}/jquery-ui.min.js"></script> +{% endwith %} diff -r c9bc3e12b102 -r dde03a53a2e7 vcweb/core/tests.py --- a/vcweb/core/tests.py Wed May 11 07:08:50 2011 -0700 +++ b/vcweb/core/tests.py Fri May 13 12:56:25 2011 -0700 @@ -120,8 +120,7 @@ class ExperimentTest(BaseVcwebTest): def round_started_test_handler(self, experiment=None, time=None, round_configuration=None, **kwargs): - logger.debug("invoking round started test handler with args experiment:%s time:%s round_configuration_id:%s" - % (experiment, time, round_configuration)) + logger.debug("invoking round started test handler with args experiment:%s time:%s round_configuration_id:%s", experiment, time, round_configuration) self.assertEqual(experiment, self.experiment) self.assertEqual(round_configuration, self.experiment.current_round) self.assertTrue(time, "time should be set") @@ -268,8 +267,7 @@ per = ParticipantExperimentRelationship.objects.create(participant=p, experiment=e, created_by=self.experimenter.user) self.assertTrue(per.id > 0) - logger.debug("Participant identifier is %s - sequential id is %i" - % (per.participant_identifier, per.sequential_participant_identifier)) + logger.debug("Participant identifier is %s - sequential id is %i", per.participant_identifier, per.sequential_participant_identifier) self.assertTrue(per.participant_identifier) self.assertTrue(per.sequential_participant_identifier > 0) @@ -332,7 +330,7 @@ def test_get_templates(self): e = self.experiment for round_type, data in RoundConfiguration.ROUND_TYPES_DICT.items(): - logger.debug("inspecting round type: %s with data %s" % (round_type, data)) + logger.debug("inspecting round type: %s with data %s", round_type, data) rc = self.create_new_round_configuration(round_type=round_type) e.current_round_sequence_number = rc.sequence_number self.assertEqual(e.current_round_template, "%s/%s" % (e.namespace, data[1]), 'should have returned template for ' + data[0]) diff -r c9bc3e12b102 -r dde03a53a2e7 vcweb/forestry/models.py --- a/vcweb/forestry/models.py Wed May 11 07:08:50 2011 -0700 +++ b/vcweb/forestry/models.py Fri May 13 12:56:25 2011 -0700 @@ -93,7 +93,7 @@ group.set_data_value(parameter=get_resource_level_parameter(), value=value) def round_setup(experiment, **kwargs): - logger.debug("forestry: round_setup for %s" % experiment) + logger.debug("forestry: round_setup for %s", experiment) round_configuration = experiment.current_round ''' FIXME: replace with dict-based dispatch on round_configuration.round_type? @@ -124,7 +124,7 @@ harvest_decision_parameter = get_harvest_decision_parameter() for pgr in ParticipantGroupRelationship.objects.filter(group__experiment=experiment): harvest_decision, created = current_round_data.participant_data_values.get_or_create(participant_group_relationship=pgr, parameter=harvest_decision_parameter) - logger.debug("%s harvest decision %s" % ("created" if created else "retrieved", harvest_decision)) + logger.debug("%s (%s)", harvest_decision, created) @task def stop_round_task(): @@ -132,7 +132,7 @@ def round_teardown(experiment, **kwargs): ''' round teardown calculates new resource levels for practice or regular rounds based on the group harvest and resultant regrowth and transferring''' - logger.debug("forestry: round_teardown for %s" % experiment) + logger.debug("forestry: round_teardown for %s", experiment) resource_level_parameter = get_resource_level_parameter() current_round_configuration = experiment.current_round max_resource_level = 100 diff -r c9bc3e12b102 -r dde03a53a2e7 vcweb/forestry/views.py --- a/vcweb/forestry/views.py Wed May 11 07:08:50 2011 -0700 +++ b/vcweb/forestry/views.py Fri May 13 12:56:25 2011 -0700 @@ -26,7 +26,7 @@ #return render_to_response('forestry/experimenter-index.html') return redirect('forestry:experimenter_index') else: - logger.warning("user %s isn't an experimenter or participant" % request.user) + logger.warning("user %s isn't an experimenter or participant", request.user) return redirect('home') @experimenter_required @@ -58,7 +58,7 @@ { 'experiment': experiment }, context_instance=RequestContext(request)) except Experiment.DoesNotExist: - logger.warning("No experiment available with id [%s]" % experiment_id) + logger.warning("No experiment available with id [%s]", experiment_id) return redirect('core:experimenter_index') class ParticipantRoundData(object): @@ -107,7 +107,7 @@ }, context_instance=RequestContext(request)) except Experiment.DoesNotExist: - logger.warning("No experiment found with id %s" % experiment_id) + logger.warning("No experiment found with id %s", experiment_id) return redirect('forestry:participant_index') diff -r c9bc3e12b102 -r dde03a53a2e7 vcweb/settings.py --- a/vcweb/settings.py Wed May 11 07:08:50 2011 -0700 +++ b/vcweb/settings.py Fri May 13 12:56:25 2011 -0700 @@ -1,27 +1,28 @@ # Django settings for vcweb project. -import os -from os import path +from os import path, makedirs import logging +import sys DEBUG = True TEMPLATE_DEBUG = DEBUG LOG_DIRECTORY = 'logs' try: - os.makedirs(LOG_DIRECTORY) + makedirs(LOG_DIRECTORY) except OSError: pass -LOG_FILENAME = 'vcweb.log' + + +# logging configuration +VCWEB_LOG_FILENAME = 'vcweb.log' TORNADIO_LOG_FILENAME = 'tornadio.log' + LOGGING = { 'version': 1, 'disable_existing_loggers': True, 'formatters': { 'verbose': { - 'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s' - }, - 'medium': { - 'format': '%(asctime)s %(levelname)s %(message)s' + 'format': '%(levelname)s %(asctime)s [%(name)s|%(funcName)s:%(lineno)d] %(message)s' }, 'simple': { 'format': '%(levelname)s %(message)s' @@ -32,22 +33,33 @@ 'level':'DEBUG', 'class':'django.utils.log.NullHandler', }, - 'console':{ + 'stdout':{ 'level':'DEBUG', 'class':'logging.StreamHandler', - 'formatter': 'simple' + 'formatter': 'verbose', + 'stream':sys.stdout, }, - 'file': { + 'stderr':{ + 'level': 'DEBUG', + 'class':'logging.StreamHandler', + 'formatter': 'verbose', + 'stream':sys.stderr, + }, + 'vcweb-file': { 'level': 'DEBUG', 'class':'logging.handlers.RotatingFileHandler', - 'formatter': 'medium', - 'filename': path.join(LOG_DIRECTORY, LOG_FILENAME), + 'formatter': 'verbose', + 'filename': path.join(LOG_DIRECTORY, VCWEB_LOG_FILENAME), + 'backupCount': 6, + 'maxBytes': 10000000, }, 'tornadio-file': { 'level': 'DEBUG', 'class':'logging.handlers.RotatingFileHandler', - 'formatter': 'medium', + 'formatter': 'verbose', 'filename': path.join(LOG_DIRECTORY, TORNADIO_LOG_FILENAME), + 'backupCount': 6, + 'maxBytes': 10000000, }, }, 'loggers': { @@ -57,17 +69,16 @@ 'level':'INFO', }, 'django.request': { - 'handlers': ['console'], + 'handlers': ['null'], 'level': 'ERROR', 'propagate': False, }, 'vcweb': { - 'handlers': ['console', 'file'], + 'handlers': ['vcweb-file', 'stdout'], 'level': 'DEBUG', - 'propagate': True, }, 'tornadio.vcweb': { - 'handlers': ['console', 'tornadio-file'], + 'handlers': ['tornadio-file', 'stderr'], 'level': 'DEBUG', 'propagate': False, }, @@ -169,6 +180,7 @@ 'dajaxice', 'djcelery', 'djkombu', +# 'django_extensions', ) diff -r c9bc3e12b102 -r dde03a53a2e7 vcweb/static/images/famfamfam/user_add.png Binary file vcweb/static/images/famfamfam/user_add.png has changed diff -r c9bc3e12b102 -r dde03a53a2e7 vcweb/vcwebio.py --- a/vcweb/vcwebio.py Wed May 11 07:08:50 2011 -0700 +++ b/vcweb/vcwebio.py Fri May 13 12:56:25 2011 -0700 @@ -44,8 +44,9 @@ experimenter_pk = int(incoming_experimenter_pk) experiment_id = int(incoming_experiment_pk) experimenter_tuple = (experimenter_pk, experiment_id) - logger.debug("registering experimenter %s with connection %s" % (experimenter_pk, connection)) + logger.debug("registering experimenter %s with connection %s", experimenter_pk, connection) if connection in self.connection_to_experimenter: + logger.debug("experimenter already registered, removing previous mapping") self.remove_experimenter(connection) self.connection_to_experimenter[connection] = experimenter_tuple self.experimenter_to_connection[experimenter_tuple] = connection @@ -53,7 +54,7 @@ def remove_experimenter(self, connection): if connection in self.connection_to_experimenter: experimenter_tuple = self.connection_to_experimenter[connection] - logger.debug("removing experimenter %s" % experimenter_tuple[0]) + logger.debug("removing experimenter %s", experimenter_tuple[0]) del self.connection_to_experimenter[connection] if experimenter_tuple in self.experimenter_to_connection: del self.experimenter_to_connection[experimenter_tuple] @@ -61,10 +62,9 @@ def get_participant_group_relationship(self, connection): if connection in self.connection_to_participant: (participant_pk, experiment_pk) = self.connection_to_participant[connection] - logger.debug("Looking for ParticipantGroupRelationship with tuple (%s, %s)" % - (participant_pk, experiment_pk)) + logger.debug("Looking for ParticipantGroupRelationship with tuple (%s, %s)", participant_pk, experiment_pk) return ParticipantGroupRelationship.objects.get(participant__pk=participant_pk, group__experiment__pk = experiment_pk) - logger.debug("Didn't find connection %s in connection map %s." % (connection, self.connection_to_participant)) + logger.debug("Didn't find connection %s in connection map %s.", connection, self.connection_to_participant) return None def get_experiment(self, connection): @@ -95,7 +95,7 @@ del self.participant_to_connection[participant_tuple] del self.connection_to_participant[connection] except KeyError as k: - logger.warning("caught key error %s while trying to remove participant connection %s" % (connection, k) ) + logger.warning("caught key error %s while trying to remove participant connection %s", connection, k) ''' Generator function that yields (participant_group_relationship_id, connection) tuples @@ -118,18 +118,15 @@ for participant_group_pk, connection in self.connections(group): yield (participant_group_pk, connection) else: - logger.warning("Experimenter %s tried to refresh experiment %s" % - (experimenter_pk, experiment)) + logger.warning("Experimenter %s tried to refresh experiment %s", experimenter_pk, experiment) else: - logger.warning("No experimenter available for connection %s" % - connection) + logger.warning("No experimenter available for connection %s", connection) ''' experimenter functions ''' def send_refresh(self, connection, experiment, experimenter_id=None): for (participant_group_pk, connection) in self.all_participants(connection, experiment): - logger.debug("sending refresh to %s, %s" % (participant_group_pk, - connection)) + logger.debug("sending refresh to %s, %s", participant_group_pk, connection) connection.send(ConnectionManager.refresh_json) def send_goto(self, connection, experiment, url): @@ -143,14 +140,14 @@ def send_to_experimenter(self, experimenter_tuple, json): (experimenter_pk, experiment_pk) = experimenter_tuple - logger.debug("sending %s to experimenter %s" % (json, experimenter_tuple)) + logger.debug("sending %s to experimenter %s", json, experimenter_tuple) if experimenter_tuple in self.experimenter_to_connection: connection = self.experimenter_to_connection[experimenter_tuple] - logger.debug("sending to connection %s" % connection) + logger.debug("sending to connection %s", connection) connection.send(json) else: - logger.debug("no experimenter found with pk %s" % experimenter_pk) - logger.debug("all experimenters: %s" % self.experimenter_to_connection) + logger.debug("no experimenter found with pk %s", experimenter_pk) + logger.debug("all experimenters: %s", self.experimenter_to_connection) def send_to_group(self, group, json): for participant_group_pk, connection in self.connections(group): @@ -175,14 +172,14 @@ def on_open(self, *args, **kwargs): try: extra = kwargs['extra'] - logger.debug('%s received extra: %s' % (self, extra)) + logger.debug('%s received extra: %s', self, extra) experimenter_id = extra except Experimenter.DoesNotExist: - logger.warning("Tried to establish connection but there isn't any experimenter with id %s" % experimenter_id) + logger.warning("Tried to establish connection but there isn't any experimenter with id %s", experimenter_id) def on_message(self, message): event = to_event(message) - logger.debug("%s received message %s" % (self, message)) + logger.debug("%s received message %s", self, message) if event.message_type == 'connect': connection_manager.add_experimenter(self, event.experimenter_id, event.experiment_id) elif event.message_type == 'refresh': @@ -197,7 +194,7 @@ url = event.message notified_participants = connection_manager.send_goto(self, experiment, url) self.send(info_json("Sent goto:%s to all participants" % url)) - logger.debug("sending all connected participants %s to %s" % (notified_participants, url)) + logger.debug("sending all connected participants %s to %s", notified_participants, url) def on_close(self): connection_manager.remove_experimenter(self) @@ -231,12 +228,12 @@ 'message_type': 'info', })) except KeyError as e: - logger.debug("no participant group relationship id %s" % e) + logger.debug("no participant group relationship id %s", e) except ParticipantExperimentRelationship.DoesNotExist as e: - logger.debug("no participant experiment relationship with id %s (%s)" % (relationship_id, e)) + logger.debug("no participant experiment relationship with id %s (%s)", relationship_id, e) def on_message(self, message, *args, **kwargs): - logger.debug("received message %s from handler %s" % (message, self)) + logger.debug("received message %s from handler %s", message, self) event = to_event(message) # could handle connection here or in on_open, revisit if 'connect' in event.message_type: @@ -255,14 +252,14 @@ event.participant_number = participant_group_relationship.participant_number event.participant_group = participant_group_relationship.group_number json = simplejson.dumps(event.__dict__) - logger.debug("json is: %s" % json) + logger.debug("json is: %s", json) connection_manager.send_to_experimenter(experimenter_tuple, json) if experiment.all_participants_have_submitted: connection_manager.send_to_experimenter( experimenter_tuple, info_json('All participants have submitted a decision.')) else: - logger.debug("No data round in progress, received late submit event: %s" % event) + logger.debug("No data round in progress, received late submit event: %s", event) elif event.message_type == 'chat': participant_group_relationship = connection_manager.get_participant_group_relationship(self) @@ -282,7 +279,7 @@ connection_manager.send_to_group(participant_group_relationship.group, chat_json) def on_close(self): - logger.debug("closing %s" % self) + logger.debug("removing participant connection %s", self) connection_manager.remove_participant(self) def main(argv=None): |
From: Bitbucket <iss...@bi...> - 2011-05-12 16:11:28
|
--- you can reply above this line --- New issue 7: multiple group round data values https://bitbucket.org/virtualcommons/vcweb/issue/7/multiple-group-round-data-values virtualcommons on Thu, 12 May 2011 18:11:17 +0200: Description: {{{ #!python [Thu May 12 09:08:08 2011] [error] ERROR Internal Server Error: /forestry/7/wait [Thu May 12 09:08:08 2011] [error] Traceback (most recent call last): [Thu May 12 09:08:08 2011] [error] File "/opt/virtualenvs/vcweb/lib/python2.6/site-packages/django/core/handlers/base.py", line 111, in get_response [Thu May 12 09:08:08 2011] [error] response = callback(request, *callback_args, **callback_kwargs) [Thu May 12 09:08:08 2011] [error] File "/opt/virtualenvs/vcweb/lib/python2.6/site-packages/django/contrib/auth/decorators.py", line 23, in _wrapped_view [Thu May 12 09:08:08 2011] [error] return view_func(request, *args, **kwargs) [Thu May 12 09:08:08 2011] [error] File "/opt/webapps/virtualcommons/vcweb/forestry/views.py", line 102, in wait [Thu May 12 09:08:08 2011] [error] participant_history = generate_participant_history(participant_group_relationship) [Thu May 12 09:08:08 2011] [error] File "/opt/webapps/virtualcommons/vcweb/forestry/views.py", line 75, in generate_participant_history [Thu May 12 09:08:08 2011] [error] data.group_harvest = get_group_harvest(group, round_data=round_data) [Thu May 12 09:08:08 2011] [error] File "/opt/webapps/virtualcommons/vcweb/forestry/models.py", line 20, in get_group_harvest [Thu May 12 09:08:08 2011] [error] return group.get_data_value(parameter=get_group_harvest_parameter(), round_data=round_data) [Thu May 12 09:08:08 2011] [error] File "/opt/webapps/virtualcommons/vcweb/core/models.py", line 969, in get_data_value [Thu May 12 09:08:08 2011] [error] data_value, created = self.data_values.get_or_create(**criteria) [Thu May 12 09:08:08 2011] [error] File "/opt/virtualenvs/vcweb/lib/python2.6/site-packages/django/db/models/fields/related.py", line 444, in get_or_create [Thu May 12 09:08:08 2011] [error] return super(RelatedManager, self.db_manager(db)).get_or_create(**kwargs) [Thu May 12 09:08:08 2011] [error] File "/opt/virtualenvs/vcweb/lib/python2.6/site-packages/django/db/models/manager.py", line 135, in get_or_create [Thu May 12 09:08:08 2011] [error] return self.get_query_set().get_or_create(**kwargs) [Thu May 12 09:08:08 2011] [error] File "/opt/virtualenvs/vcweb/lib/python2.6/site-packages/django/db/models/query.py", line 378, in get_or_create [Thu May 12 09:08:08 2011] [error] return self.get(**lookup), False [Thu May 12 09:08:08 2011] [error] File "/opt/virtualenvs/vcweb/lib/python2.6/site-packages/django/db/models/query.py", line 351, in get [Thu May 12 09:08:08 2011] [error] % (self.model._meta.object_name, num, kwargs)) [Thu May 12 09:08:08 2011] [error] MultipleObjectsReturned: get() returned more than one GroupRoundDataValue -- it returned 2! Lookup parameters were {'group': <Group: Group #2>, 'parameter': <Parameter: forestry parameter: group_harvest (int, group)>, 'round_data': <RoundData: Data for Round 8 (Regular interactive experiment round)>} }}} Responsible: alllee -- This is an issue notification from bitbucket.org. You are receiving this either because you are the owner of the issue, or you are following the issue. |
From: Bitbucket <iss...@bi...> - 2011-05-12 15:39:01
|
--- you can reply above this line --- New issue 6: fix logging https://bitbucket.org/virtualcommons/vcweb/issue/6/fix-logging virtualcommons on Thu, 12 May 2011 17:38:52 +0200: Description: tornadio logging is better now, but regular vcweb file logging is not working. -- This is an issue notification from bitbucket.org. You are receiving this either because you are the owner of the issue, or you are following the issue. |
From: Bitbucket <iss...@bi...> - 2011-05-12 15:35:39
|
--- you can reply above this line --- New issue 5: tornadio experimenter removed prematurely https://bitbucket.org/virtualcommons/vcweb/issue/5/tornadio-experimenter-removed-prematurely virtualcommons on Thu, 12 May 2011 17:35:30 +0200: Description: Figure out why 'removing experimenter 3' is being invoked multiple times (and without cause as well). {{{ #!python DEBUG <__main__.ExperimenterHandler object at 0x1a46a510> received extra: 3 DEBUG <__main__.ExperimenterHandler object at 0x1a46a510> received message {u'message': u'Reconnecting from disconnect', u'message_type': u'reconnect', u'experiment_id': 7, u'experimenter_id': 3} DEBUG <__main__.ExperimenterHandler object at 0x1a46a510> received message {u'message': u'Initial connection', u'message_type': u'connect', u'experiment_id': 7, u'experimenter_id': 3} DEBUG registering experimenter 3 with connection <__main__.ExperimenterHandler object at 0x1a46a510> DEBUG <__main__.ExperimenterHandler object at 0x1a46a9d0> received extra: 3 DEBUG <__main__.ExperimenterHandler object at 0x1a46a9d0> received message {u'message': u'Initial connection', u'message_type': u'connect', u'experiment_id': 7, u'experimenter_id': 3} DEBUG registering experimenter 3 with connection <__main__.ExperimenterHandler object at 0x1a46a9d0> DEBUG removing experimenter 3 DEBUG removing experimenter 3 DEBUG participant already has a connection, removing previous mappings. DEBUG Looking for ParticipantGroupRelationship with tuple (45, 7) DEBUG sending {"message": "Participant 1 (Group #2) connected.", "message_type": "info"} to experimenter (3, 7) DEBUG no experimenter found with pk 3 DEBUG all experimenters: {} DEBUG received message {u'participant_group_relationship_id': 66, u'message': u'Initial connection', u'message_type': u'connect'} from handler <__main__.ParticipantHandler object at 0x1a38bed0> DEBUG <__main__.ExperimenterHandler object at 0x1a475e90> received extra: 3 DEBUG <__main__.ExperimenterHandler object at 0x1a475e90> received message {u'message': u'Initial connection', u'message_type': u'connect', u'experiment_id': 7, u'experimenter_id': 3} DEBUG registering experimenter 3 with connection <__main__.ExperimenterHandler object at 0x1a475e90> DEBUG removing experimenter 3 DEBUG <__main__.ExperimenterHandler object at 0x1a397ad0> received extra: 3 DEBUG <__main__.ExperimenterHandler object at 0x1a397ad0> received message {u'message': u'Initial connection', u'message_type': u'connect', u'experiment_id': 7, u'experimenter_id': 3} DEBUG registering experimenter 3 with connection <__main__.ExperimenterHandler object at 0x1a397ad0> DEBUG <__main__.ExperimenterHandler object at 0x1a397ad0> received message {u'message': u'wait', u'message_type': u'goto', u'experiment_id': 7, u'experimenter_id': 3} DEBUG sending all connected participants [61, 62, 63, 64, 65, 66, 67, 68, 69, 70] to wait DEBUG participant already has a connection, removing previous mappings. DEBUG Looking for ParticipantGroupRelationship with tuple (45, 7) DEBUG sending {"message": "Participant 1 (Group #2) connected.", "message_type": "info"} to experimenter (3, 7) DEBUG sending to connection <__main__.ExperimenterHandler object at 0x1a397ad0> DEBUG received message {u'participant_group_relationship_id': 66, u'message': u'Initial connection', u'message_type': u'connect'} from handler <__main__.ParticipantHandler object at 0x1a3a9390> DEBUG participant already has a connection, removing previous mappings. DEBUG Looking for ParticipantGroupRelationship with tuple (47, 7) DEBUG sending {"message": "Participant 1 (Group #1) connected.", "message_type": "info"} to experimenter (3, 7) DEBUG sending to connection <__main__.ExperimenterHandler object at 0x1a397ad0> DEBUG participant already has a connection, removing previous mappings. DEBUG Looking for ParticipantGroupRelationship with tuple (50, 7) DEBUG sending {"message": "Participant 4 (Group #1) connected.", "message_type": "info"} to experimenter (3, 7) DEBUG sending to connection <__main__.ExperimenterHandler object at 0x1a397ad0> DEBUG participant already has a connection, removing previous mappings. DEBUG Looking for ParticipantGroupRelationship with tuple (49, 7) DEBUG sending {"message": "Participant 5 (Group #1) connected.", "message_type": "info"} to experimenter (3, 7) DEBUG sending to connection <__main__.ExperimenterHandler object at 0x1a397ad0> DEBUG participant already has a connection, removing previous mappings. DEBUG Looking for ParticipantGroupRelationship with tuple (51, 7) DEBUG sending {"message": "Participant 2 (Group #1) connected.", "message_type": "info"} to experimenter (3, 7) DEBUG sending to connection <__main__.ExperimenterHandler object at 0x1a397ad0> DEBUG participant already has a connection, removing previous mappings. DEBUG Looking for ParticipantGroupRelationship with tuple (52, 7) DEBUG sending {"message": "Participant 3 (Group #2) connected.", "message_type": "info"} to experimenter (3, 7) DEBUG sending to connection <__main__.ExperimenterHandler object at 0x1a397ad0> DEBUG participant already has a connection, removing previous mappings. DEBUG Looking for ParticipantGroupRelationship with tuple (48, 7) DEBUG sending {"message": "Participant 5 (Group #2) connected.", "message_type": "info"} to experimenter (3, 7) DEBUG sending to connection <__main__.ExperimenterHandler object at 0x1a397ad0> DEBUG participant already has a connection, removing previous mappings. DEBUG Looking for ParticipantGroupRelationship with tuple (44, 7) DEBUG sending {"message": "Participant 4 (Group #2) connected.", "message_type": "info"} to experimenter (3, 7) DEBUG sending to connection <__main__.ExperimenterHandler object at 0x1a397ad0> DEBUG received message {u'participant_group_relationship_id': 61, u'message': u'Initial connection', u'message_type': u'connect'} from handler <__main__.ParticipantHandler object at 0x1a3a96d0> DEBUG participant already has a connection, removing previous mappings. DEBUG Looking for ParticipantGroupRelationship with tuple (43, 7) DEBUG sending {"message": "Participant 2 (Group #2) connected.", "message_type": "info"} to experimenter (3, 7) DEBUG sending to connection <__main__.ExperimenterHandler object at 0x1a397ad0> }}} -- This is an issue notification from bitbucket.org. You are receiving this either because you are the owner of the issue, or you are following the issue. |
From: Bitbucket <iss...@bi...> - 2011-05-11 14:26:51
|
--- you can reply above this line --- New issue 4: add javascript unit testing https://bitbucket.org/virtualcommons/vcweb/issue/4/add-javascript-unit-testing virtualcommons on Wed, 11 May 2011 16:26:45 +0200: Description: It'd be good to add some unit tests to the views (especially JS). See http://stackoverflow.com/questions/300855/looking-for-a-better-javascript-unit-test-tool and hopefully https://github.com/weluse/django-nose-selenium works properly. Responsible: alllee -- This is an issue notification from bitbucket.org. You are receiving this either because you are the owner of the issue, or you are following the issue. |
From: <vir...@li...> - 2011-05-11 14:08:58
|
Subject: hg.virtualcommons 359 details: http://virtualcommons.hg.sourceforge.net:8000/hgroot/virtualcommons/virtualcommons/hgrepo/v/vi/virtualcommons/virtualcommons/rev/c9bc3e12b102 changeset: 359:c9bc3e12b102 user: Allen Lee <all...@as...> date: Wed May 11 07:08:50 2011 -0700 description: typo on dajaxice.core.js import diffstat: vcweb/core/templates/base.html | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r de35692593f4 -r c9bc3e12b102 vcweb/core/templates/base.html --- a/vcweb/core/templates/base.html Wed May 04 14:40:29 2011 -0700 +++ b/vcweb/core/templates/base.html Wed May 11 07:08:50 2011 -0700 @@ -18,7 +18,7 @@ {% load dajaxice_templatetags %} {% dajaxice_js_import %} {% else %} - <script type='/text/javascript' src='{{STATIC_URL}}js/dajaxice.core.js'></script> + <script type='text/javascript' src='{{STATIC_URL}}js/dajaxice.core.js' charset='utf-8'></script> {% endif %} <script type='text/javascript'> <!-- sets all external links to open up in new windows and jquery-ui buttonifies all buttons--> |
From: <al...@us...> - 2011-05-08 02:02:45
|
Revision: 534 http://virtualcommons.svn.sourceforge.net/virtualcommons/?rev=534&view=rev Author: alllee Date: 2011-05-08 02:02:39 +0000 (Sun, 08 May 2011) Log Message: ----------- initial changes to round configuration for proposed fall 2011 experiments Modified Paths: -------------- foraging/trunk/src/main/java/edu/asu/commons/foraging/conf/RoundConfiguration.java Added Paths: ----------- foraging/trunk/src/main/resources/configuration/asu-experiments/fall-2011/ foraging/trunk/src/main/resources/configuration/asu-experiments/fall-2011/stationary-limitedvision/ foraging/trunk/src/main/resources/configuration/asu-experiments/fall-2011/stationary-limitedvision/round0.xml foraging/trunk/src/main/resources/configuration/asu-experiments/fall-2011/stationary-limitedvision/round1.xml foraging/trunk/src/main/resources/configuration/asu-experiments/fall-2011/stationary-limitedvision/round2.xml foraging/trunk/src/main/resources/configuration/asu-experiments/fall-2011/stationary-limitedvision/round3.xml foraging/trunk/src/main/resources/configuration/asu-experiments/fall-2011/stationary-limitedvision/round4.xml foraging/trunk/src/main/resources/configuration/asu-experiments/fall-2011/stationary-limitedvision/round5.xml foraging/trunk/src/main/resources/configuration/asu-experiments/fall-2011/stationary-limitedvision/round6.xml foraging/trunk/src/main/resources/configuration/asu-experiments/fall-2011/stationary-limitedvision/server.xml Modified: foraging/trunk/src/main/java/edu/asu/commons/foraging/conf/RoundConfiguration.java =================================================================== --- foraging/trunk/src/main/java/edu/asu/commons/foraging/conf/RoundConfiguration.java 2010-11-23 19:31:57 UTC (rev 533) +++ foraging/trunk/src/main/java/edu/asu/commons/foraging/conf/RoundConfiguration.java 2011-05-08 02:02:39 UTC (rev 534) @@ -43,22 +43,15 @@ private static final double DEFAULT_TOKEN_BIRTH_PROBABILITY = 0.01d; - - private final static Map<String, SanctionType> sanctionTypeMap = new HashMap<String, SanctionType>(3); public enum SanctionType { - REAL_TIME("real-time"), POST_ROUND("post-round"), NONE("none"); - private SanctionType(String name) { - sanctionTypeMap.put(name, this); - } + REAL_TIME, POST_ROUND, NONE; public static SanctionType find(String name) { - SanctionType type = sanctionTypeMap.get(name); - if (type == null) { - type = valueOf(name); - if (type == null) { - type = NONE; - } + try { + return valueOf(name.toUpperCase().replaceAll("-", "_")); } - return type; + catch (Exception exception) { + return NONE; + } } } @@ -511,6 +504,14 @@ return getBooleanProperty("censored-chat-enabled", false); } + public boolean isTrustGameEnabled() { + return getBooleanProperty("trust-game", false); + } + + public boolean isInRoundChatEnabled() { + return getBooleanProperty("in-round-chat-enabled", false); + } + public String getCensoredChatInstructions() { return getProperty("censored-chat-instructions", "Your messages must be approved before they will be relayed to the rest of your group."); @@ -568,7 +569,6 @@ instructionsBuilder.append("<hr><b>"); instructionsBuilder.append(getQuizInstructions()).append("</b>"); } - return instructionsBuilder; } Added: foraging/trunk/src/main/resources/configuration/asu-experiments/fall-2011/stationary-limitedvision/round0.xml =================================================================== (Binary files differ) Property changes on: foraging/trunk/src/main/resources/configuration/asu-experiments/fall-2011/stationary-limitedvision/round0.xml ___________________________________________________________________ Added: svn:mime-type + application/xml Added: foraging/trunk/src/main/resources/configuration/asu-experiments/fall-2011/stationary-limitedvision/round1.xml =================================================================== (Binary files differ) Property changes on: foraging/trunk/src/main/resources/configuration/asu-experiments/fall-2011/stationary-limitedvision/round1.xml ___________________________________________________________________ Added: svn:mime-type + application/xml Added: foraging/trunk/src/main/resources/configuration/asu-experiments/fall-2011/stationary-limitedvision/round2.xml =================================================================== (Binary files differ) Property changes on: foraging/trunk/src/main/resources/configuration/asu-experiments/fall-2011/stationary-limitedvision/round2.xml ___________________________________________________________________ Added: svn:mime-type + application/xml Added: foraging/trunk/src/main/resources/configuration/asu-experiments/fall-2011/stationary-limitedvision/round3.xml =================================================================== (Binary files differ) Property changes on: foraging/trunk/src/main/resources/configuration/asu-experiments/fall-2011/stationary-limitedvision/round3.xml ___________________________________________________________________ Added: svn:mime-type + application/xml Added: foraging/trunk/src/main/resources/configuration/asu-experiments/fall-2011/stationary-limitedvision/round4.xml =================================================================== (Binary files differ) Property changes on: foraging/trunk/src/main/resources/configuration/asu-experiments/fall-2011/stationary-limitedvision/round4.xml ___________________________________________________________________ Added: svn:mime-type + application/xml Added: foraging/trunk/src/main/resources/configuration/asu-experiments/fall-2011/stationary-limitedvision/round5.xml =================================================================== (Binary files differ) Property changes on: foraging/trunk/src/main/resources/configuration/asu-experiments/fall-2011/stationary-limitedvision/round5.xml ___________________________________________________________________ Added: svn:mime-type + application/xml Added: foraging/trunk/src/main/resources/configuration/asu-experiments/fall-2011/stationary-limitedvision/round6.xml =================================================================== (Binary files differ) Property changes on: foraging/trunk/src/main/resources/configuration/asu-experiments/fall-2011/stationary-limitedvision/round6.xml ___________________________________________________________________ Added: svn:mime-type + application/xml Added: foraging/trunk/src/main/resources/configuration/asu-experiments/fall-2011/stationary-limitedvision/server.xml =================================================================== (Binary files differ) Property changes on: foraging/trunk/src/main/resources/configuration/asu-experiments/fall-2011/stationary-limitedvision/server.xml ___________________________________________________________________ Added: svn:mime-type + application/xml This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: Bitbucket <iss...@bi...> - 2011-05-07 07:18:00
|
--- you can reply above this line --- New issue 3: investigate jquery .live() https://bitbucket.org/virtualcommons/vcweb/issue/3/investigate-jquery-live virtualcommons on Sat, 7 May 2011 09:17:54 +0200: Description: There's a few places where we bind callbacks to dom elements added from ajax. It's been abstracted out into a function called by both document.ready and the ajax update but could probably be handled once via .live(). See http://api.jquery.com/live/ for more details. Responsible: alllee -- This is an issue notification from bitbucket.org. You are receiving this either because you are the owner of the issue, or you are following the issue. |
From: <vir...@li...> - 2011-05-04 21:40:37
|
Subject: hg.virtualcommons 358 details: http://virtualcommons.hg.sourceforge.net:8000/hgroot/virtualcommons/virtualcommons/hgrepo/v/vi/virtualcommons/virtualcommons/rev/de35692593f4 changeset: 358:de35692593f4 user: Allen Lee <all...@as...> date: Wed May 04 14:40:29 2011 -0700 description: adding conditional dajaxice static include based on settings.DEBUG diffstat: vcweb/core/templates/base.html | 7 +++++-- vcweb/fabfile.py | 5 +++++ vcweb/settings.py | 9 +++++---- vcweb/static/js/dajaxice.core.js | 17 +---------------- 4 files changed, 16 insertions(+), 22 deletions(-) diffs (109 lines): diff -r b575d301bf6e -r de35692593f4 vcweb/core/templates/base.html --- a/vcweb/core/templates/base.html Wed May 04 14:14:50 2011 -0700 +++ b/vcweb/core/templates/base.html Wed May 04 14:40:29 2011 -0700 @@ -1,5 +1,4 @@ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -{% load dajaxice_templatetags %} <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> {% block head %} @@ -15,8 +14,12 @@ <script type='text/javascript' src='{{STATIC_URL}}js/common.js'></script> <script type='text/javascript' src='{{STATIC_URL}}js/jquery.qtip-1.0.0-rc3.min.js'></script> {% include "includes/jquery.ui.html" %} + {% if debug_mode %} + {% load dajaxice_templatetags %} {% dajaxice_js_import %} - <!-- <script type='/text/javascript' src='{{STATIC_URL}}js/dajaxice.core.js'></script> --> + {% else %} + <script type='/text/javascript' src='{{STATIC_URL}}js/dajaxice.core.js'></script> + {% endif %} <script type='text/javascript'> <!-- sets all external links to open up in new windows and jquery-ui buttonifies all buttons--> $(function() { diff -r b575d301bf6e -r de35692593f4 vcweb/fabfile.py --- a/vcweb/fabfile.py Wed May 04 14:14:50 2011 -0700 +++ b/vcweb/fabfile.py Wed May 04 14:40:29 2011 -0700 @@ -101,6 +101,7 @@ def push(): local('hg push') + local('hg push ssh://hg...@bi.../virtualcommons/vcweb') def dev(): env.project_path = env.deploy_path + env.project_name @@ -115,6 +116,10 @@ env.apache = 'apache2' env.hosts = ['localhost'] +def staticg(): + local('%(python)s manage.py generate_static_dajaxice > static/js/dajaxice.core.js' % env) + local('%(python)s manage.py collectstatic' % env) + def setup(): setup_virtualenv() sudo('hg clone %(hg_url)s %(deploy_path)s' % env, pty=True, user=env.deploy_user) diff -r b575d301bf6e -r de35692593f4 vcweb/settings.py --- a/vcweb/settings.py Wed May 04 14:14:50 2011 -0700 +++ b/vcweb/settings.py Wed May 04 14:40:29 2011 -0700 @@ -3,6 +3,9 @@ from os import path import logging +DEBUG = True +TEMPLATE_DEBUG = DEBUG + LOG_DIRECTORY = 'logs' try: os.makedirs(LOG_DIRECTORY) @@ -71,9 +74,6 @@ } } -DEBUG = True -TEMPLATE_DEBUG = DEBUG - ADMINS = ( ('Allen Lee', 'all...@as...') # ('Your Name', 'you...@do...'), @@ -133,6 +133,7 @@ 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', 'vcweb.core.context_processors.socket_io', + 'vcweb.core.context_processors.debug_mode', ) MIDDLEWARE_CLASSES = ( @@ -165,9 +166,9 @@ 'django.contrib.staticfiles', 'vcweb.core', 'vcweb.forestry', + 'dajaxice', 'djcelery', 'djkombu', - 'dajaxice', ) diff -r b575d301bf6e -r de35692593f4 vcweb/static/js/dajaxice.core.js --- a/vcweb/static/js/dajaxice.core.js Wed May 04 14:14:50 2011 -0700 +++ b/vcweb/static/js/dajaxice.core.js Wed May 04 14:40:29 2011 -0700 @@ -1,16 +1,1 @@ -var t=null,v={n:function(a){var p=t;if(document.cookie&&document.cookie!="")for(var m=document.cookie.split(";"),o=0;o<m.length;o++){var q=m[o].toString().replace(/^\s+/,"").replace(/\s+$/,"");if(q.substring(0,a.length+1)==a+"="){p=decodeURIComponent(q.substring(a.length+1));break}}return p},call:function(a,p,m){var o=[];(is_callback_a_function=typeof p=="function")||o.push("callback="+p);o.push("argv="+encodeURIComponent(JSON.stringify(m)));o=o.join("&");m=new XMLHttpRequest;m.open("POST","/dajaxice/"+ -a+"/");m.setRequestHeader("X-Requested-With","XMLHttpRequest");m.setRequestHeader("X-CSRFToken",this.n("csrftoken"));m.onreadystatechange=function(){if(this.readyState==XMLHttpRequest.DONE)if(is_callback_a_function)try{p(JSON.parse(this.responseText))}catch(q){p(this.responseText)}else eval(this.responseText)};m.send(o)}};v.o="DAJAXICE_EXCEPTION";window.Dajaxice=v; -(function(){function a(){this.a=q?new q:new window.j("Microsoft.XMLHTTP");this.m=[]}function p(c){a.onreadystatechange&&a.onreadystatechange.apply(c);c.dispatchEvent({type:"readystatechange",bubbles:false,cancelable:false,timeStamp:new Date+0})}function m(c){try{c.responseText=c.a.responseText}catch(h){}try{var b;a:{var g=c.a,e=g.responseXML,f=g.responseText;if(s&&f&&e&&!e.documentElement&&g.getResponseHeader("Content-Type").match(/[^\/]+\/[^\+]+\+xml/)){e=new window.j("Microsoft.XMLDOM");e.async= -false;e.validateOnParse=false;e.loadXML(f)}if(e)if(s&&e.parseError!=0||!e.documentElement||e.documentElement&&e.documentElement.tagName=="parsererror"){b=t;break a}b=e}c.responseXML=b}catch(r){}try{c.status=c.a.status}catch(l){}try{c.statusText=c.a.statusText}catch(i){}}function o(c){c.a.onreadystatechange=new window.d}var q=window.XMLHttpRequest,n=!!window.controllers,s=window.document.all&&!window.opera;if(n&&q.i)a.i=q.i;a.c=0;a.e=1;a.p=2;a.LOADING=3;a.DONE=4;a.prototype.readyState=a.c;a.prototype.responseText= -"";a.prototype.responseXML=t;a.prototype.status=0;a.prototype.statusText="";a.prototype.onreadystatechange=t;a.onreadystatechange=t;a.onopen=t;a.h=t;a.onabort=t;a.prototype.open=function(c,h,b,g,e){delete this.b;if(arguments.length<3)b=true;this.l=b;var f=this,r=this.readyState,l;if(s&&b){l=function(){if(r!=a.DONE){o(f);f.abort()}};window.attachEvent("onunload",l)}a.onopen&&a.onopen.apply(this,arguments);if(arguments.length>4)this.a.open(c,h,b,g,e);else arguments.length>3?this.a.open(c,h,b,g):this.a.open(c, -h,b);if(!n&&!s){this.readyState=a.e;p(this)}this.a.onreadystatechange=function(){if(!(n&&!b)){f.readyState=f.a.readyState;m(f);if(f.g)f.readyState=a.c;else{if(f.readyState==a.DONE){o(f);s&&b&&window.detachEvent("onunload",l)}r!=f.readyState&&p(f);r=f.readyState}}}};a.prototype.send=function(c){a.h&&a.h.apply(this,arguments);if(c&&c.nodeType){c=window.k?(new window.k).serializeToString(c):c.xml;this.b["Content-Type"]||this.a.setRequestHeader("Content-Type","application/xml")}this.a.send(c);if(n&&!this.l){this.readyState= -a.e;for(m(this);this.readyState<a.DONE;){this.readyState++;p(this);if(this.g)break}}};a.prototype.abort=function(){a.onabort&&a.onabort.apply(this,arguments);if(this.readyState>a.c)this.g=true;this.a.abort();o(this)};a.prototype.getResponseHeader=function(c){return this.a.getResponseHeader(c)};a.prototype.setRequestHeader=function(c,h){if(!this.b)this.b={};this.b[c]=h;return this.a.setRequestHeader(c,h)};a.prototype.dispatchEvent=function(c){c={type:c.type,target:this,currentTarget:this,eventPhase:2, -bubbles:c.bubbles,cancelable:c.cancelable,timeStamp:c.timeStamp,stopPropagation:function(){},preventDefault:function(){},initEvent:function(){}};if(c.type=="readystatechange"&&this.onreadystatechange)(this.onreadystatechange.handleEvent||this.onreadystatechange).apply(this,[c]);for(var h=0,b;b=this.m[h];h++)if(b[0]==c.type&&!b[2])(b[1].handleEvent||b[1]).apply(this,[c])};a.prototype.toString=function(){return"[object XMLHttpRequest]"};a.toString=function(){return"[XMLHttpRequest]"};if(!window.d.prototype.apply)window.d.prototype.apply= -function(c,h){h||(h=[]);c.f=this;c.f(h[0],h[1],h[2],h[3],h[4]);delete c.f};window.XMLHttpRequest=a})();if(!this.JSON)this.JSON={}; -(function(){function a(b){return b<10?"0"+b:b}function p(b){q.lastIndex=0;return q.test(b)?'"'+b.replace(q,function(g){var e=c[g];return typeof e==="string"?e:"\\u"+("0000"+g.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+b+'"'}function m(b,g){var e,f,r=n,l,i=g[b];if(i&&typeof i==="object"&&typeof i.toJSON==="function")i=i.toJSON(b);if(typeof h==="function")i=h.call(g,b,i);switch(typeof i){case "string":return p(i);case "number":return isFinite(i)?String(i):"null";case "boolean":case "null":return String(i); -case "object":if(!i)return"null";n+=s;l=[];if(Object.prototype.toString.apply(i)==="[object Array]"){f=i.length;for(b=0;b<f;b+=1)l[b]=m(b,i)||"null";g=l.length===0?"[]":n?"[\n"+n+l.join(",\n"+n)+"\n"+r+"]":"["+l.join(",")+"]";n=r;return g}if(h&&typeof h==="object"){f=h.length;for(b=0;b<f;b+=1){e=h[b];if(typeof e==="string")if(g=m(e,i))l.push(p(e)+(n?": ":":")+g)}}else for(e in i)if(Object.hasOwnProperty.call(i,e))if(g=m(e,i))l.push(p(e)+(n?": ":":")+g);g=l.length===0?"{}":n?"{\n"+n+l.join(",\n"+n)+ -"\n"+r+"}":"{"+l.join(",")+"}";n=r;return g}}if(typeof Date.prototype.toJSON!=="function"){Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+a(this.getUTCMonth()+1)+"-"+a(this.getUTCDate())+"T"+a(this.getUTCHours())+":"+a(this.getUTCMinutes())+":"+a(this.getUTCSeconds())+"Z":t};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(){return this.valueOf()}}var o=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, -q=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,n,s,c={"\u0008":"\\b","\t":"\\t","\n":"\\n","\u000c":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},h;if(typeof JSON.stringify!=="function")JSON.stringify=function(b,g,e){var f;s=n="";if(typeof e==="number")for(f=0;f<e;f+=1)s+=" ";else if(typeof e==="string")s=e;if((h=g)&&typeof g!=="function"&&(typeof g!=="object"||typeof g.length!=="number"))throw Error("JSON.stringify");return m("", -{"":b})};if(typeof JSON.parse!=="function")JSON.parse=function(b,g){function e(f,r){var l,i,u=f[r];if(u&&typeof u==="object")for(l in u)if(Object.hasOwnProperty.call(u,l)){i=e(u,l);if(i!==undefined)u[l]=i;else delete u[l]}return g.call(f,r,u)}o.lastIndex=0;if(o.test(b))b=b.replace(o,function(f){return"\\u"+("0000"+f.charCodeAt(0).toString(16)).slice(-4)});if(/^[\],:{}\s]*$/.test(b.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, -"]").replace(/(?:^|:|,)(?:\s*\[)+/g,""))){b=eval("("+b+")");return typeof g==="function"?e({"":b},""):b}throw new SyntaxError("JSON.parse");}})(); - +var Dajaxice={vcweb:{core:{experiment_controller:function(b,a){Dajaxice.call("vcweb.core.experiment_controller",b,a)}}},get_cookie:function(a){var e=null;if(document.cookie&&document.cookie!=""){var d=document.cookie.split(";");for(var c=0;c<d.length;c++){var b=d[c].toString().replace(/^\s+/,"").replace(/\s+$/,"");if(b.substring(0,a.length+1)==(a+"=")){e=decodeURIComponent(b.substring(a.length+1));break}}}return e},call:function(dajaxice_function,dajaxice_callback,argv){var send_data=[];is_callback_a_function=(typeof(dajaxice_callback)=="function");if(!is_callback_a_function){send_data.push("callback="+dajaxice_callback)}send_data.push("argv="+encodeURIComponent(JSON.stringify(argv)));send_data=send_data.join("&");var oXMLHttpRequest=new XMLHttpRequest;oXMLHttpRequest.open("POST","/dajaxice/"+dajaxice_function+"/");oXMLHttpRequest.setRequestHeader("X-Requested-With","XMLHttpRequest");oXMLHttpRequest.setRequestHeader("X-CSRFToken",Dajaxice.get_cookie("csrftoken"));oXMLHttpRequest.onreadystatechange=function(){if(this.readyState==XMLHttpRequest.DONE){if(is_callback_a_function){try{dajaxice_callback(JSON.parse(this.responseText))}catch(exception){dajaxice_callback(this.responseText)}}else{eval(this.responseText)}}};oXMLHttpRequest.send(send_data)}};Dajaxice.EXCEPTION="DAJAXICE_EXCEPTION";window.Dajaxice=Dajaxice;(function(){function a(){this._object=f?new f:new window.ActiveXObject("Microsoft.XMLHTTP");this._listeners=[]}function d(b){a.onreadystatechange&&a.onreadystatechange.apply(b);b.dispatchEvent({type:"readystatechange",bubbles:false,cancelable:false,timeStamp:new Date+0})}function m(b){var i=b.responseXML,h=b.responseText;if(g&&h&&i&&!i.documentElement&&b.getResponseHeader("Content-Type").match(/[^\/]+\/[^\+]+\+xml/)){i=new window.ActiveXObject("Microsoft.XMLDOM");i.async=false;i.validateOnParse=false;i.loadXML(h)}if(i){if(g&&i.parseError!=0||!i.documentElement||i.documentElement&&i.documentElement.tagName=="parsererror"){return null}}return i}function n(b){try{b.responseText=b._object.responseText}catch(k){ |
From: <vir...@li...> - 2011-05-04 21:14:56
|
Subject: hg.virtualcommons 357 details: http://virtualcommons.hg.sourceforge.net:8000/hgroot/virtualcommons/virtualcommons/hgrepo/v/vi/virtualcommons/virtualcommons/rev/b575d301bf6e changeset: 357:b575d301bf6e user: Allen Lee <all...@as...> date: Wed May 04 14:14:50 2011 -0700 description: re-adding configurable socket_io_port in Django settings and pushing window.location.hostname into socket.io.html duplicate log messages and other minor fixes diffstat: vcweb/core/context_processors.py | 2 + vcweb/core/templates/experimenter/monitor.html | 2 +- vcweb/core/templates/includes/socket.io.html | 9 +- vcweb/core/templates/participant/base.html | 3 +- vcweb/fabfile.py | 28 +- vcweb/settings.py | 10 +- vcweb/vcweb-tornadio.py | 316 ---------------------------- vcweb/vcwebio.py | 310 ++++++++++++++++++++++++++++ 8 files changed, 339 insertions(+), 341 deletions(-) diffs (813 lines): diff -r 7c8575d6c02e -r b575d301bf6e vcweb/core/context_processors.py --- a/vcweb/core/context_processors.py Wed May 04 13:20:25 2011 -0700 +++ b/vcweb/core/context_processors.py Wed May 04 14:14:50 2011 -0700 @@ -3,3 +3,5 @@ def debug_mode(request): return {'debug_mode': settings.DEBUG} +def socket_io(request): + return {'SOCKET_IO_PORT' : settings.SOCKET_IO_PORT} diff -r 7c8575d6c02e -r b575d301bf6e vcweb/core/templates/experimenter/monitor.html --- a/vcweb/core/templates/experimenter/monitor.html Wed May 04 13:20:25 2011 -0700 +++ b/vcweb/core/templates/experimenter/monitor.html Wed May 04 14:14:50 2011 -0700 @@ -60,7 +60,7 @@ registerCallbacks({{ experiment.round_data.count }}, {{ experiment.current_round.sequence_number }}); // socket.io connection // FIXME: add auth - var s = connect(window.location.hostname, 8888, 'experimenter/{{request.user.experimenter.pk}}'); + var s = connect('experimenter/{{request.user.experimenter.pk}}'); s.on('message', function(json_string) { console.log("Received message: " + json_string); var json = jQuery.parseJSON(json_string); diff -r 7c8575d6c02e -r b575d301bf6e vcweb/core/templates/includes/socket.io.html --- a/vcweb/core/templates/includes/socket.io.html Wed May 04 13:20:25 2011 -0700 +++ b/vcweb/core/templates/includes/socket.io.html Wed May 04 14:14:50 2011 -0700 @@ -5,14 +5,17 @@ <script type="text/javascript"> var cachedSocket; -function connect(host, port, resource) { +var defaultPort = 8881; +function connect(resource) { + var host = window.location.hostname; if ( !host ) { console.log("Tried to connect to invalid host, connecting to vcweb.asu.edu instead."); host = "vcweb.asu.edu"; } + var port = {{SOCKET_IO_PORT}}; if ( !port ) { - console.log("using default port 8888"); - port = 8888; + console.log("using default port: " + defaultPort); + port = defaultPort; } cachedSocket = new io.Socket(host, {"port": port, "resource": resource}); cachedSocket.connect(); diff -r 7c8575d6c02e -r b575d301bf6e vcweb/core/templates/participant/base.html --- a/vcweb/core/templates/participant/base.html Wed May 04 13:20:25 2011 -0700 +++ b/vcweb/core/templates/participant/base.html Wed May 04 14:14:50 2011 -0700 @@ -8,11 +8,10 @@ {% include "includes/socket.io.html" %} <script type='text/javascript'> var qtipOptions = {position: { corner: {target: 'topMiddle', tooltip: 'bottomMiddle'}}, style: { name: 'green', tip: 'bottomMiddle'} }; - connect(window.location.hostname, 8888, 'participant/{{participant_experiment_relationship.pk}}'); + connect('participant/{{participant_experiment_relationship.pk}}'); $(function() { $('[title]').qtip(qtipOptions); }); -</script> </script> {% endblock %} {% endblock %} diff -r 7c8575d6c02e -r b575d301bf6e vcweb/fabfile.py --- a/vcweb/fabfile.py Wed May 04 13:20:25 2011 -0700 +++ b/vcweb/fabfile.py Wed May 04 14:14:50 2011 -0700 @@ -1,6 +1,7 @@ from fabric.api import local, run, sudo, cd, env, hide from fabric.contrib.console import confirm from fabric.contrib import django +from fabric.context_managers import settings as fab_settings import os, sys @@ -25,6 +26,8 @@ # django integration for access to settings, etc. django.project(env.project_name) +from vcweb import settings as vcweb_settings + """ this currently only works for sqlite3 development database. do it by hand with postgres a few times to figure out what to automate, probably with south? @@ -49,22 +52,19 @@ run('virtualenv -p %(python)s --no-site-packages %(virtualenv_path)s;' % env) def clear_rabbitmq_db(): - from fabric.context_managers import settings - with settings(warn_only=True): + with fab_settings(warn_only=True): sudo_chain(["rabbitmqctl %s" % cmd for cmd in ['stop_app', 'reset', 'start_app']]) def setup_rabbitmq(): - from vcweb import settings - from fabric.context_managers import settings as fab_settings clear_rabbitmq_db() with fab_settings(warn_only=True): - sudo("rabbitmqctl delete_user %s" % settings.BROKER_USER, pty=True) - sudo("rabbitmqctl add_user %s %s" % (settings.BROKER_USER, settings.BROKER_PASSWORD), pty=True) + sudo("rabbitmqctl delete_user %s" % vcweb_settings.BROKER_USER, pty=True) + sudo("rabbitmqctl add_user %s %s" % (vcweb_settings.BROKER_USER, vcweb_settings.BROKER_PASSWORD), pty=True) with fab_settings(warn_only=True): - sudo("rabbitmqctl delete_vhost %s" % settings.BROKER_VHOST, pty=True) - sudo("rabbitmqctl add_vhost %s" % settings.BROKER_VHOST, pty=True) + sudo("rabbitmqctl delete_vhost %s" % vcweb_settings.BROKER_VHOST, pty=True) + sudo("rabbitmqctl add_vhost %s" % vcweb_settings.BROKER_VHOST, pty=True) # figure out what the appropriate rabbitmq perms are here. - sudo('rabbitmqctl set_permissions -p %s %s ".*" ".*" ".*"' % (settings.BROKER_VHOST, settings.BROKER_USER), pty=True) + sudo('rabbitmqctl set_permissions -p %s %s ".*" ".*" ".*"' % (vcweb_settings.BROKER_VHOST, vcweb_settings.BROKER_USER), pty=True) def _virtualenv(*commands, **kwargs): """ source the virtualenv before executing this command """ @@ -87,11 +87,8 @@ with cd(env.project_path): _virtualenv('%(python)s manage.py test %(apps)s' % env) -def tornado(ip="149.169.203.115", port=8888): - local("{python} vcweb-tornado.py {port}".format(python=env.python, **locals()), capture=False) - -def tornadio(ip="149.169.203.115", port=8888): - local("{python} vcweb-tornadio.py {port}".format(python=env.python, **locals()), capture=False) +def tornadio(ip="149.169.203.115", port=vcweb_settings.SOCKET_IO_PORT): + local("{python} vcwebio.py {port}".format(python=env.python, **locals()), capture=False) def server(ip="149.169.203.115", port=8000): local("{python} manage.py runserver {ip}:{port}".format(python=env.python, **locals()), capture=False) @@ -145,8 +142,7 @@ sudo('hg pull && hg up', user=env.deploy_user, pty=True) if confirm("syncdb?"): syncdb() - from vcweb import settings - env.static_root = settings.STATIC_ROOT + env.static_root = vcweb_settings.STATIC_ROOT _virtualenv('%(python)s manage.py collectstatic' % env) sudo_chain('chmod -R ug+rw .', 'find %(static_root)s -type d -exec chmod a+x {} \;' % env, diff -r 7c8575d6c02e -r b575d301bf6e vcweb/settings.py --- a/vcweb/settings.py Wed May 04 13:20:25 2011 -0700 +++ b/vcweb/settings.py Wed May 04 14:14:50 2011 -0700 @@ -61,10 +61,12 @@ 'vcweb': { 'handlers': ['console', 'file'], 'level': 'DEBUG', + 'propagate': True, }, - 'vcweb.tornadio': { + 'tornadio.vcweb': { 'handlers': ['console', 'tornadio-file'], 'level': 'DEBUG', + 'propagate': False, }, } } @@ -130,6 +132,7 @@ 'django.core.context_processors.static', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', + 'vcweb.core.context_processors.socket_io', ) MIDDLEWARE_CLASSES = ( @@ -169,8 +172,10 @@ DAJAXICE_MEDIA_PREFIX = "dajaxice" +EMAIL_HOST = "smtp.asu.edu" -EMAIL_HOST = "smtp.asu.edu" +# socket.io configuration +SOCKET_IO_PORT = 8882; # celery rabbitmq/amqp configuration BROKER_HOST = "localhost" @@ -184,7 +189,6 @@ CELERYBEAT_LOG_FILE = 'celerybeat.log' CELERYBEAT_LOG_LEVEL = 'ERROR' - # activation window ACCOUNT_ACTIVATION_DAYS = 30 diff -r 7c8575d6c02e -r b575d301bf6e vcweb/vcweb-tornadio.py --- a/vcweb/vcweb-tornadio.py Wed May 04 13:20:25 2011 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,316 +0,0 @@ -#!/usr/bin/env python -import tornado.web -from tornadio import SocketConnection, get_router, server -import os -import sys -import logging -import simplejson - -sys.path.append(os.path.abspath('..')) - -os.environ['DJANGO_SETTINGS_MODULE'] = 'vcweb.settings' - -from vcweb.core.models import ParticipantExperimentRelationship, ParticipantGroupRelationship, ChatMessage, Experimenter, Experiment - -logger = logging.getLogger('vcweb.tornadio') - - -def info_json(message): - return simplejson.dumps({'message_type': 'info', 'message': message}) - -def goto_json(url): - return simplejson.dumps({'message_type': 'goto', 'url': url}) - -def chat_json(chat_message): - return simplejson.dumps({ - "pk": chat_message.pk, - "date_created": chat_message.date_created.strftime("%H:%M:%S"), - "message" : unicode(chat_message), - "message_type": 'chat', - }) - -class Message(object): - def __init__(self, message_type='info', **kwargs): - self.message_type = message_type - self.__dict__.update(**kwargs) - -class ConnectionManager: - ''' - Manages socket.io connections to tornadio. - ''' - # bidi maps for (participant.pk, experiment.pk) -> connection - connection_to_participant = {} - participant_to_connection = {} - # bidi maps for (experimenter.pk, experiment.pk) -> connection - connection_to_experimenter = {} - experimenter_to_connection = {} - refresh_json = simplejson.dumps({ 'message_type': 'refresh' }) - - def add_experimenter(self, connection, incoming_experimenter_pk, incoming_experiment_pk): - experimenter_pk = int(incoming_experimenter_pk) - experiment_id = int(incoming_experiment_pk) - experimenter_tuple = (experimenter_pk, experiment_id) - logger.debug("registering experimenter %s with connection %s" % (experimenter_pk, connection)) - if connection in self.connection_to_experimenter: - self.remove_experimenter(connection) - self.connection_to_experimenter[connection] = experimenter_tuple - self.experimenter_to_connection[experimenter_tuple] = connection - - def remove_experimenter(self, connection): - if connection in self.connection_to_experimenter: - experimenter_tuple = self.connection_to_experimenter[connection] - logger.debug("removing experimenter %s" % experimenter_tuple[0]) - del self.connection_to_experimenter[connection] - if experimenter_tuple in self.experimenter_to_connection: - del self.experimenter_to_connection[experimenter_tuple] - - def get_participant_group_relationship(self, connection): - if connection in self.connection_to_participant: - (participant_pk, experiment_pk) = self.connection_to_participant[connection] - logger.debug("Looking for ParticipantGroupRelationship with tuple (%s, %s)" % - (participant_pk, experiment_pk)) - return ParticipantGroupRelationship.objects.get(participant__pk=participant_pk, group__experiment__pk = experiment_pk) - logger.debug("Didn't find connection %s in connection map %s." % (connection, self.connection_to_participant)) - return None - - def get_experiment(self, connection): - if connection in self.connection_to_participant: - experiment_pk = self.connection_to_participant[connection][1] - return Experiment.objects.get(pk=experiment_pk) - else: - return None - - def get_participant_experiment_tuple(self, connection): - if connection in self.connection_to_participant: - return self.connection_to_participant[connection] - else: - return None - - def add_participant(self, auth_token, connection, participant_experiment_relationship): - participant_tuple = (participant_experiment_relationship.participant.pk, participant_experiment_relationship.experiment.pk) - if participant_tuple in self.participant_to_connection: - logger.debug("participant already has a connection, removing previous mappings.") - self.remove_participant(self.participant_to_connection[participant_tuple]) - - self.connection_to_participant[connection] = participant_tuple - self.participant_to_connection[participant_tuple] = connection - - def remove_participant(self, connection): - try: - participant_tuple = self.connection_to_participant[connection] - del self.participant_to_connection[participant_tuple] - del self.connection_to_participant[connection] - except KeyError as k: - logger.warning("caught key error %s while trying to remove participant connection %s" % (connection, k) ) - - ''' - Generator function that yields (participant_group_relationship_id, connection) tuples - for the given group - ''' - def connections(self, group): - experiment = group.experiment - for participant_group_relationship in group.participant_group_relationships.all(): - ''' only return currently connected connections in this group ''' - participant = participant_group_relationship.participant - participant_tuple = (participant.pk, experiment.pk) - if participant_tuple in self.participant_to_connection: - yield (participant_group_relationship.pk, self.participant_to_connection[participant_tuple]) - - def all_participants(self, connection, experiment): - if connection in self.connection_to_experimenter: - (experimenter_pk, experiment_pk) = self.connection_to_experimenter[connection] - if experiment.pk == experiment_pk: - for group in experiment.groups.all(): - for participant_group_pk, connection in self.connections(group): - yield (participant_group_pk, connection) - else: - logger.warning("Experimenter %s tried to refresh experiment %s" % - (experimenter_pk, experiment)) - else: - logger.warning("No experimenter available for connection %s" % - connection) - ''' - experimenter functions - ''' - def send_refresh(self, connection, experiment, experimenter_id=None): - for (participant_group_pk, connection) in self.all_participants(connection, experiment): - logger.debug("sending refresh to %s, %s" % (participant_group_pk, - connection)) - connection.send(ConnectionManager.refresh_json) - - def send_goto(self, connection, experiment, url): - notified_participants = [] - json = simplejson.dumps({'message_type': 'goto', 'url': url}) - for (participant_group_pk, connection) in self.all_participants(connection, experiment): - connection.send(json) - notified_participants.append(participant_group_pk) - return notified_participants - - - def send_to_experimenter(self, experimenter_tuple, json): - (experimenter_pk, experiment_pk) = experimenter_tuple - logger.debug("sending %s to experimenter %s" % (json, experimenter_tuple)) - if experimenter_tuple in self.experimenter_to_connection: - connection = self.experimenter_to_connection[experimenter_tuple] - logger.debug("sending to connection %s" % connection) - connection.send(json) - else: - logger.debug("no experimenter found with pk %s" % experimenter_pk) - logger.debug("all experimenters: %s" % self.experimenter_to_connection) - - def send_to_group(self, group, json): - for participant_group_pk, connection in self.connections(group): - connection.send(json) - experiment = group.experiment - experimenter = experiment.experimenter - self.send_to_experimenter((experimenter.pk, experiment.pk), json) - -# replace with namedtuple -class Struct: - def __init__(self, **attributes): - self.__dict__.update(attributes) - -def to_event(message): - return Struct(**message) - -# connection manager for experimenters + participants -connection_manager = ConnectionManager() -# FIXME: move to a core tornado module? -class ExperimenterHandler(SocketConnection): - # FIXME: add authentication - def on_open(self, *args, **kwargs): - try: - extra = kwargs['extra'] - logger.debug('%s received extra: %s' % (self, extra)) - experimenter_id = extra - except Experimenter.DoesNotExist: - logger.warning("Tried to establish connection but there isn't any experimenter with id %s" % experimenter_id) - - def on_message(self, message): - event = to_event(message) - logger.debug("%s received message %s" % (self, message)) - if event.message_type == 'connect': - connection_manager.add_experimenter(self, event.experimenter_id, event.experiment_id) - elif event.message_type == 'refresh': - experiment_id = event.experiment_id - experimenter_id = event.experimenter_id - experiment = Experiment.objects.get(pk=experiment_id) - connection_manager.send_refresh(self, experiment, experimenter_id) - self.send(info_json("Refreshed all participants")) - elif event.message_type == 'goto': - experiment_id = event.experiment_id - experiment = Experiment.objects.get(pk=experiment_id) - url = event.message - notified_participants = connection_manager.send_goto(self, experiment, url) - self.send(info_json("Sent goto:%s to all participants" % url)) - logger.debug("sending all connected participants %s to %s" % (notified_participants, url)) - - def on_close(self): - connection_manager.remove_experimenter(self) - -class ParticipantHandler(SocketConnection): - # FIXME: on_open authenticates or prepares the session - def on_open(self, *args, **kwargs): - # FIXME: verify user auth tokens - extra = kwargs['extra'] - #(auth_token, dot, participant_group_relationship_id) = extra.partition('.') - #logger.debug("auth token: %s, id %s" % (auth_token, participant_group_relationship_id)) - relationship_id = extra - try: - participant_experiment_relationship = ParticipantExperimentRelationship.objects.select_related(depth=1).get(pk=relationship_id) - connection_manager.add_participant(extra, self, participant_experiment_relationship) - participant_group_rel = connection_manager.get_participant_group_relationship(self) - if participant_group_rel is not None: - group = participant_group_rel.group - message = "Participant %s (%s) connected." % (participant_group_rel.participant_number, group) - connection_manager.send_to_group(group, - simplejson.dumps({ - 'message' : message, - 'message_type': 'info', - })) - else: - experimenter_tuple = (participant_experiment_relationship.experiment.experimenter.pk, - participant_experiment_relationship.experiment.pk) - connection_manager.send_to_experimenter(experimenter_tuple, - simplejson.dumps({ - 'message': "Participant %s connected to experiment." % participant_experiment_relationship, - 'message_type': 'info', - })) - except KeyError as e: - logger.debug("no participant group relationship id %s" % e) - except ParticipantExperimentRelationship.DoesNotExist as e: - logger.debug("no participant experiment relationship with id %s (%s)" % (relationship_id, e)) - - def on_message(self, message, *args, **kwargs): - logger.debug("received message %s from handler %s" % (message, self)) - event = to_event(message) - # could handle connection here or in on_open, revisit - if 'connect' in event.message_type: - return - elif event.message_type == 'submit': - (participant_pk, experiment_pk) = connection_manager.get_participant_experiment_tuple(self) - experiment = Experiment.objects.get(pk=experiment_pk) - # sanity check, make sure this is a data round. - if experiment.is_data_round_in_progress: - experimenter_tuple = (experiment.experimenter.pk, experiment.pk) - event.participant_pk = participant_pk - pgr_pk = event.participant_group_relationship_id - participant_group_relationship = ParticipantGroupRelationship.objects.get(pk=pgr_pk) - prdv = experiment.current_round_data.participant_data_values.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 - json = simplejson.dumps(event.__dict__) - logger.debug("json is: %s" % json) - connection_manager.send_to_experimenter(experimenter_tuple, json) - if experiment.all_participants_have_submitted: - connection_manager.send_to_experimenter( - experimenter_tuple, - info_json('All participants have submitted a decision.')) - else: - logger.debug("No data round in progress, received late submit event: %s" % event) - - elif event.message_type == 'chat': - participant_group_relationship = connection_manager.get_participant_group_relationship(self) - current_round_data = participant_group_relationship.group.experiment.current_round_data - chat_message = ChatMessage.objects.create(participant_group_relationship=participant_group_relationship, - message=event.message, - round_data=current_round_data - ) - chat_json = simplejson.dumps({ - "pk": chat_message.pk, - 'round_data_pk': current_round_data.pk, - 'participant': unicode(participant_group_relationship.participant), - "date_created": chat_message.date_created.strftime("%H:%M:%S"), - "message" : unicode(chat_message), - "message_type": 'chat', - }) - connection_manager.send_to_group(participant_group_relationship.group, chat_json) - - def on_close(self): - logger.debug("closing %s" % self) - connection_manager.remove_participant(self) - -def main(argv=None): - if argv is None: - argv = sys.argv - participantRouter = get_router(ParticipantHandler, resource="participant", extra_re=r'\d+', extra_sep='/') - # router w/ auth hash.. - #participantRouter = tornadio.get_router(ChatHandler, resource="chat", extra_re=r'[\w._=]+', extra_sep='/') - experimenterRouter = get_router(ExperimenterHandler, resource="experimenter", extra_re=r'\d+', extra_sep='/') - #configure the Tornado application - # currently only allow one command-line argument, the port to run on. - port = int(argv[1]) if (len(argv) > 1) else 8888 - - application = tornado.web.Application( - [participantRouter.route(), experimenterRouter.route(), ], - flash_policy_port=8043, - flash_policy_file='/etc/nginx/flashpolicy.xml', - socket_io_port=port, - # only needed for standalone testing -# static_path=os.path.join(os.path.dirname(__file__), "static"), - ) - return server.SocketServer(application) - -if __name__ == "__main__": - sys.exit(main()) diff -r 7c8575d6c02e -r b575d301bf6e vcweb/vcwebio.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vcweb/vcwebio.py Wed May 04 14:14:50 2011 -0700 @@ -0,0 +1,310 @@ +#!/usr/bin/env python +import tornado.web +from tornadio import SocketConnection, get_router, server +import os +import sys +import logging +import simplejson + +sys.path.append(os.path.abspath('..')) +os.environ['DJANGO_SETTINGS_MODULE'] = 'vcweb.settings' + +from vcweb.core.models import ParticipantExperimentRelationship, ParticipantGroupRelationship, ChatMessage, Experimenter, Experiment +from vcweb import settings + +logger = logging.getLogger('tornadio.vcweb') + +def info_json(message): + return simplejson.dumps({'message_type': 'info', 'message': message}) + +def goto_json(url): + return simplejson.dumps({'message_type': 'goto', 'url': url}) + +def chat_json(chat_message): + return simplejson.dumps({ + "pk": chat_message.pk, + "date_created": chat_message.date_created.strftime("%H:%M:%S"), + "message" : unicode(chat_message), + "message_type": 'chat', + }) + +class ConnectionManager: + ''' + Manages socket.io connections to tornadio. + ''' + # bidi maps for (participant.pk, experiment.pk) -> connection + connection_to_participant = {} + participant_to_connection = {} + # bidi maps for (experimenter.pk, experiment.pk) -> connection + connection_to_experimenter = {} + experimenter_to_connection = {} + refresh_json = simplejson.dumps({ 'message_type': 'refresh' }) + + def add_experimenter(self, connection, incoming_experimenter_pk, incoming_experiment_pk): + experimenter_pk = int(incoming_experimenter_pk) + experiment_id = int(incoming_experiment_pk) + experimenter_tuple = (experimenter_pk, experiment_id) + logger.debug("registering experimenter %s with connection %s" % (experimenter_pk, connection)) + if connection in self.connection_to_experimenter: + self.remove_experimenter(connection) + self.connection_to_experimenter[connection] = experimenter_tuple + self.experimenter_to_connection[experimenter_tuple] = connection + + def remove_experimenter(self, connection): + if connection in self.connection_to_experimenter: + experimenter_tuple = self.connection_to_experimenter[connection] + logger.debug("removing experimenter %s" % experimenter_tuple[0]) + del self.connection_to_experimenter[connection] + if experimenter_tuple in self.experimenter_to_connection: + del self.experimenter_to_connection[experimenter_tuple] + + def get_participant_group_relationship(self, connection): + if connection in self.connection_to_participant: + (participant_pk, experiment_pk) = self.connection_to_participant[connection] + logger.debug("Looking for ParticipantGroupRelationship with tuple (%s, %s)" % + (participant_pk, experiment_pk)) + return ParticipantGroupRelationship.objects.get(participant__pk=participant_pk, group__experiment__pk = experiment_pk) + logger.debug("Didn't find connection %s in connection map %s." % (connection, self.connection_to_participant)) + return None + + def get_experiment(self, connection): + if connection in self.connection_to_participant: + experiment_pk = self.connection_to_participant[connection][1] + return Experiment.objects.get(pk=experiment_pk) + else: + return None + + def get_participant_experiment_tuple(self, connection): + if connection in self.connection_to_participant: + return self.connection_to_participant[connection] + else: + return None + + def add_participant(self, auth_token, connection, participant_experiment_relationship): + participant_tuple = (participant_experiment_relationship.participant.pk, participant_experiment_relationship.experiment.pk) + if participant_tuple in self.participant_to_connection: + logger.debug("participant already has a connection, removing previous mappings.") + self.remove_participant(self.participant_to_connection[participant_tuple]) + + self.connection_to_participant[connection] = participant_tuple + self.participant_to_connection[participant_tuple] = connection + + def remove_participant(self, connection): + try: + participant_tuple = self.connection_to_participant[connection] + del self.participant_to_connection[participant_tuple] + del self.connection_to_participant[connection] + except KeyError as k: + logger.warning("caught key error %s while trying to remove participant connection %s" % (connection, k) ) + + ''' + Generator function that yields (participant_group_relationship_id, connection) tuples + for the given group + ''' + def connections(self, group): + experiment = group.experiment + for participant_group_relationship in group.participant_group_relationships.all(): + ''' only return currently connected connections in this group ''' + participant = participant_group_relationship.participant + participant_tuple = (participant.pk, experiment.pk) + if participant_tuple in self.participant_to_connection: + yield (participant_group_relationship.pk, self.participant_to_connection[participant_tuple]) + + def all_participants(self, connection, experiment): + if connection in self.connection_to_experimenter: + (experimenter_pk, experiment_pk) = self.connection_to_experimenter[connection] + if experiment.pk == experiment_pk: + for group in experiment.groups.all(): + for participant_group_pk, connection in self.connections(group): + yield (participant_group_pk, connection) + else: + logger.warning("Experimenter %s tried to refresh experiment %s" % + (experimenter_pk, experiment)) + else: + logger.warning("No experimenter available for connection %s" % + connection) + ''' + experimenter functions + ''' + def send_refresh(self, connection, experiment, experimenter_id=None): + for (participant_group_pk, connection) in self.all_participants(connection, experiment): + logger.debug("sending refresh to %s, %s" % (participant_group_pk, + connection)) + connection.send(ConnectionManager.refresh_json) + + def send_goto(self, connection, experiment, url): + notified_participants = [] + json = simplejson.dumps({'message_type': 'goto', 'url': url}) + for (participant_group_pk, connection) in self.all_participants(connection, experiment): + connection.send(json) + notified_participants.append(participant_group_pk) + return notified_participants + + + def send_to_experimenter(self, experimenter_tuple, json): + (experimenter_pk, experiment_pk) = experimenter_tuple + logger.debug("sending %s to experimenter %s" % (json, experimenter_tuple)) + if experimenter_tuple in self.experimenter_to_connection: + connection = self.experimenter_to_connection[experimenter_tuple] + logger.debug("sending to connection %s" % connection) + connection.send(json) + else: + logger.debug("no experimenter found with pk %s" % experimenter_pk) + logger.debug("all experimenters: %s" % self.experimenter_to_connection) + + def send_to_group(self, group, json): + for participant_group_pk, connection in self.connections(group): + connection.send(json) + experiment = group.experiment + experimenter = experiment.experimenter + self.send_to_experimenter((experimenter.pk, experiment.pk), json) + +# replace with namedtuple +class Struct: + def __init__(self, **attributes): + self.__dict__.update(attributes) + +def to_event(message): + return Struct(**message) + +# connection manager for experimenters + participants +connection_manager = ConnectionManager() +# FIXME: move to a core tornado module? +class ExperimenterHandler(SocketConnection): + # FIXME: add authentication + def on_open(self, *args, **kwargs): + try: + extra = kwargs['extra'] + logger.debug('%s received extra: %s' % (self, extra)) + experimenter_id = extra + except Experimenter.DoesNotExist: + logger.warning("Tried to establish connection but there isn't any experimenter with id %s" % experimenter_id) + + def on_message(self, message): + event = to_event(message) + logger.debug("%s received message %s" % (self, message)) + if event.message_type == 'connect': + connection_manager.add_experimenter(self, event.experimenter_id, event.experiment_id) + elif event.message_type == 'refresh': + experiment_id = event.experiment_id + experimenter_id = event.experimenter_id + experiment = Experiment.objects.get(pk=experiment_id) + connection_manager.send_refresh(self, experiment, experimenter_id) + self.send(info_json("Refreshed all participants")) + elif event.message_type == 'goto': + experiment_id = event.experiment_id + experiment = Experiment.objects.get(pk=experiment_id) + url = event.message + notified_participants = connection_manager.send_goto(self, experiment, url) + self.send(info_json("Sent goto:%s to all participants" % url)) + logger.debug("sending all connected participants %s to %s" % (notified_participants, url)) + + def on_close(self): + connection_manager.remove_experimenter(self) + +class ParticipantHandler(SocketConnection): + # FIXME: on_open authenticates or prepares the session + def on_open(self, *args, **kwargs): + # FIXME: verify user auth tokens + extra = kwargs['extra'] + #(auth_token, dot, participant_group_relationship_id) = extra.partition('.') + #logger.debug("auth token: %s, id %s" % (auth_token, participant_group_relationship_id)) + relationship_id = extra + try: + participant_experiment_relationship = ParticipantExperimentRelationship.objects.select_related(depth=1).get(pk=relationship_id) + connection_manager.add_participant(extra, self, participant_experiment_relationship) + participant_group_rel = connection_manager.get_participant_group_relationship(self) + if participant_group_rel is not None: + group = participant_group_rel.group + message = "Participant %s (%s) connected." % (participant_group_rel.participant_number, group) + connection_manager.send_to_group(group, + simplejson.dumps({ + 'message' : message, + 'message_type': 'info', + })) + else: + experimenter_tuple = (participant_experiment_relationship.experiment.experimenter.pk, + participant_experiment_relationship.experiment.pk) + connection_manager.send_to_experimenter(experimenter_tuple, + simplejson.dumps({ + 'message': "Participant %s connected to experiment." % participant_experiment_relationship, + 'message_type': 'info', + })) + except KeyError as e: + logger.debug("no participant group relationship id %s" % e) + except ParticipantExperimentRelationship.DoesNotExist as e: + logger.debug("no participant experiment relationship with id %s (%s)" % (relationship_id, e)) + + def on_message(self, message, *args, **kwargs): + logger.debug("received message %s from handler %s" % (message, self)) + event = to_event(message) + # could handle connection here or in on_open, revisit + if 'connect' in event.message_type: + return + elif event.message_type == 'submit': + (participant_pk, experiment_pk) = connection_manager.get_participant_experiment_tuple(self) + experiment = Experiment.objects.get(pk=experiment_pk) + # sanity check, make sure this is a data round. + if experiment.is_data_round_in_progress: + experimenter_tuple = (experiment.experimenter.pk, experiment.pk) + event.participant_pk = participant_pk + pgr_pk = event.participant_group_relationship_id + participant_group_relationship = ParticipantGroupRelationship.objects.get(pk=pgr_pk) + prdv = experiment.current_round_data.participant_data_values.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 + json = simplejson.dumps(event.__dict__) + logger.debug("json is: %s" % json) + connection_manager.send_to_experimenter(experimenter_tuple, json) + if experiment.all_participants_have_submitted: + connection_manager.send_to_experimenter( + experimenter_tuple, + info_json('All participants have submitted a decision.')) + else: + logger.debug("No data round in progress, received late submit event: %s" % event) + + elif event.message_type == 'chat': + participant_group_relationship = connection_manager.get_participant_group_relationship(self) + current_round_data = participant_group_relationship.group.experiment.current_round_data + chat_message = ChatMessage.objects.create(participant_group_relationship=participant_group_relationship, + message=event.message, + round_data=current_round_data + ) + chat_json = simplejson.dumps({ + "pk": chat_message.pk, + 'round_data_pk': current_round_data.pk, + 'participant': unicode(participant_group_relationship.participant), + "date_created": chat_message.date_created.strftime("%H:%M:%S"), + "message" : unicode(chat_message), + "message_type": 'chat', + }) + connection_manager.send_to_group(participant_group_relationship.group, chat_json) + + def on_close(self): + logger.debug("closing %s" % self) + connection_manager.remove_participant(self) + +def main(argv=None): + if argv is None: + argv = sys.argv + participantRouter = get_router(ParticipantHandler, resource="participant", extra_re=r'\d+', extra_sep='/') + # router w/ auth hash.. + #participantRouter = tornadio.get_router(ChatHandler, resource="chat", extra_re=r'[\w._=]+', extra_sep='/') + experimenterRouter = get_router(ExperimenterHandler, resource="experimenter", extra_re=r'\d+', extra_sep='/') + #configure the Tornado application + # currently only allow one command-line argument, the port to run on. + port = int(argv[1]) if (len(argv) > 1) else settings.SOCKET_IO_PORT + + application = tornado.web.Application( + [participantRouter.route(), experimenterRouter.route(), ], + flash_policy_port=8043, + flash_policy_file='/etc/nginx/flashpolicy.xml', + socket_io_port=port, + # only needed for standalone testing +# static_path=os.path.join(os.path.dirname(__file__), "static"), + ) + return server.SocketServer(application) + +if __name__ == "__main__": + sys.exit(main()) |
From: <vir...@li...> - 2011-05-04 20:20:31
|
Subject: hg.virtualcommons 356 details: http://virtualcommons.hg.sourceforge.net:8000/hgroot/virtualcommons/virtualcommons/hgrepo/v/vi/virtualcommons/virtualcommons/rev/7c8575d6c02e changeset: 356:7c8575d6c02e user: Allen Lee <all...@as...> date: Wed May 04 13:20:25 2011 -0700 description: minor UI tweaks diffstat: vcweb/core/templates/registration/register.html | 11 +++-------- vcweb/static/css/style.css | 27 +++++++++++++-------------- 2 files changed, 16 insertions(+), 22 deletions(-) diffs (81 lines): diff -r 6f6fc0b794a5 -r 7c8575d6c02e vcweb/core/templates/registration/register.html --- a/vcweb/core/templates/registration/register.html Thu Apr 28 12:46:14 2011 -0700 +++ b/vcweb/core/templates/registration/register.html Wed May 04 13:20:25 2011 -0700 @@ -16,11 +16,6 @@ equalTo: "Please make sure your passwords match." } }); - $('[title]').qtip({ - position: { corner: {target: 'topRight', tooltip: 'bottomMiddle'}}, - style: { name: 'cream', tip: 'bottomMiddle'}, - }); - $('input:visible, textarea:visible').each(function(i, val) { var labelTitle = $(val).prev().attr("title"); if (! labelTitle) { @@ -40,12 +35,12 @@ {% block title %}Virtual Commons Web Experiment Registration{% endblock %} -{% block content %} +{% block page %} <form id='registrationForm' action='' method='post'> <h3>New User</h3> <p> -Returning users can <a href='{% url core:login %}'>login here</a> or <a href='{% url password-reset %}'>retrieve your password</a>. +Already have an account? You can <a href='{% url core:login %}'>login here</a> or <a href='{% url password-reset %}'>retrieve your password</a>. </p> {% include "includes/form-as-div.html" %} @@ -56,5 +51,5 @@ </form> -{% endblock content %} +{% endblock %} diff -r 6f6fc0b794a5 -r 7c8575d6c02e vcweb/static/css/style.css --- a/vcweb/static/css/style.css Thu Apr 28 12:46:14 2011 -0700 +++ b/vcweb/static/css/style.css Wed May 04 13:20:25 2011 -0700 @@ -24,20 +24,6 @@ h3 { font-size: 1.2em; } h4 { font-size: 1.0em; } h5 { font-size: 0.9em; } -input.error { - padding: 0; - margin: 0; - border: solid red; -} -label.error { - background: url('../images/unchecked.gif') no-repeat left center #FBE3E4; - line-height: normal; - font-size: .8em; - margin:0.3em; - padding:0.3em; - padding-left: 1.1em; - margin-left: 0.3em; -} span.label { float: left; text-align: right; @@ -142,6 +128,19 @@ .field > input[type='password'] { width: 15em; } +input.error { + margin: 0.5em 0 0.5em 0; + padding: 1px 0px 1px 0px; + border: 1px solid red; +} +label.error { + background: url('../images/unchecked.gif') no-repeat left center #FBE3E4; + font-size: .8em; + margin:0.3em; + padding:0.3em; + padding-left: 1.1em; + margin-left: 0.3em; +} #experimentData a { text-decoration: none; } |
From: <vir...@li...> - 2011-04-28 19:46:12
|
Subject: hg.virtualcommons 355 details: http://virtualcommons.hg.sourceforge.net:8000/hgroot/virtualcommons/virtualcommons/hgrepo/v/vi/virtualcommons/virtualcommons/rev/6f6fc0b794a5 changeset: 355:6f6fc0b794a5 user: Allen Lee <all...@as...> date: Thu Apr 28 12:46:14 2011 -0700 description: removing duplicate images, adding Expires headers to static resources in vcweb apache config diffstat: vcweb/static/css/guarantee/style.css | 20 ++++++++++---------- vcweb/static/images/guarantee/img01.gif | vcweb/static/images/guarantee/img02.gif | vcweb/static/images/guarantee/img03.gif | vcweb/static/images/guarantee/img04.gif | vcweb/static/images/guarantee/img05.gif | vcweb/static/images/guarantee/img06.gif | vcweb/static/images/guarantee/img07.gif | vcweb/static/images/guarantee/img08.gif | vcweb/vcweb.apache.vhost | 5 +++++ 10 files changed, 15 insertions(+), 10 deletions(-) diffs (124 lines): diff -r c2aa99a324f0 -r 6f6fc0b794a5 vcweb/static/css/guarantee/style.css --- a/vcweb/static/css/guarantee/style.css Wed Apr 27 14:36:43 2011 -0700 +++ b/vcweb/static/css/guarantee/style.css Thu Apr 28 12:46:14 2011 -0700 @@ -8,7 +8,7 @@ body { margin: 0; padding: 0; - background: #FFFFFF url(/static/images/guarantee/img01.gif) repeat-x left top; + background: #FFFFFF url(images/img01.gif) repeat-x left top; color: #8A8A8A; } @@ -50,7 +50,7 @@ #menu { float: left; height: 36px; - background: url(/static/images/guarantee/img02.gif) no-repeat left top; + background: url(images/img02.gif) no-repeat left top; } #menu ul { @@ -71,7 +71,7 @@ width: 140px; height: 22px; padding: 10px 0px 0px 0px; - background: url(/static/images/guarantee/img04.gif) no-repeat left top; + background: url(images/img04.gif) no-repeat left top; text-decoration: none; text-align: center; font-family: Helvetica, sans-serif; @@ -84,7 +84,7 @@ } #menu .active a { - background: url(/static/images/guarantee/img03.gif) no-repeat left top; + background: url(images/img03.gif) no-repeat left top; color: #FFFFF0; } @@ -219,7 +219,7 @@ height: 32px; margin-left: 2px; padding: 4px 30px 2px 15px; - background: url(/static/images/guarantee/img05.gif) repeat-x left top; + background: url(images/img05.gif) repeat-x left top; font-family: Arial, Helvetica, sans-serif; font-weight: normal; font-size: 1em; @@ -243,7 +243,7 @@ height: 18px; margin: 0px; padding: 3px 0px 0px 40px; - background: url(/static/images/guarantee/img06.gif) no-repeat left top; + background: url(images/img06.gif) no-repeat left top; text-decoration: none; font-family: Arial, Helvetica, sans-serif; font-size: 1em; @@ -258,7 +258,7 @@ height: 18px; margin: 0px; padding: 3px 0px 0px 40px; - background: url(/static/images/guarantee/img07.gif) no-repeat left top; + background: url(images/img07.gif) no-repeat left top; text-decoration: none; font-family: Arial, Helvetica, sans-serif; font-size: .9em; @@ -296,7 +296,7 @@ margin: 0; padding: 0.50em 0.3em; border-bottom: 0.06em solid #E9E8DD; - background: url(/static/images/guarantee/img08.gif) no-repeat left 1.13em; + background: url(images/img08.gif) no-repeat left 1.13em; } #sidebar li li a { @@ -318,7 +318,7 @@ height: 1.88em; margin: 0 0 0.63em 0; padding: 0.38em 0 0.14em 0.88em; - background: url(/static/images/guarantee/img05.gif) repeat-x left top; + background: url(images/img05.gif) repeat-x left top; text-transform: capitalize; font-size: 1.5em; font-weight: normal; @@ -400,7 +400,7 @@ height: 100px; margin: 0 auto; padding: 0; - background: url(/static/images/guarantee/img02.gif) repeat-x left top; + background: url(images/img02.gif) repeat-x left top; } #footer-bgcontent { diff -r c2aa99a324f0 -r 6f6fc0b794a5 vcweb/static/images/guarantee/img01.gif Binary file vcweb/static/images/guarantee/img01.gif has changed diff -r c2aa99a324f0 -r 6f6fc0b794a5 vcweb/static/images/guarantee/img02.gif Binary file vcweb/static/images/guarantee/img02.gif has changed diff -r c2aa99a324f0 -r 6f6fc0b794a5 vcweb/static/images/guarantee/img03.gif Binary file vcweb/static/images/guarantee/img03.gif has changed diff -r c2aa99a324f0 -r 6f6fc0b794a5 vcweb/static/images/guarantee/img04.gif Binary file vcweb/static/images/guarantee/img04.gif has changed diff -r c2aa99a324f0 -r 6f6fc0b794a5 vcweb/static/images/guarantee/img05.gif Binary file vcweb/static/images/guarantee/img05.gif has changed diff -r c2aa99a324f0 -r 6f6fc0b794a5 vcweb/static/images/guarantee/img06.gif Binary file vcweb/static/images/guarantee/img06.gif has changed diff -r c2aa99a324f0 -r 6f6fc0b794a5 vcweb/static/images/guarantee/img07.gif Binary file vcweb/static/images/guarantee/img07.gif has changed diff -r c2aa99a324f0 -r 6f6fc0b794a5 vcweb/static/images/guarantee/img08.gif Binary file vcweb/static/images/guarantee/img08.gif has changed diff -r c2aa99a324f0 -r 6f6fc0b794a5 vcweb/vcweb.apache.vhost --- a/vcweb/vcweb.apache.vhost Wed Apr 27 14:36:43 2011 -0700 +++ b/vcweb/vcweb.apache.vhost Thu Apr 28 12:46:14 2011 -0700 @@ -6,6 +6,11 @@ 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 |
From: <vir...@li...> - 2011-04-27 21:36:41
|
Subject: hg.virtualcommons 354 details: http://virtualcommons.hg.sourceforge.net:8000/hgroot/virtualcommons/virtualcommons/hgrepo/v/vi/virtualcommons/virtualcommons/rev/c2aa99a324f0 changeset: 354:c2aa99a324f0 user: Allen Lee <all...@as...> date: Wed Apr 27 14:36:43 2011 -0700 description: cleaning up tornadio script a bit more, checking experimenter tuple before attempting to delete a possibly removed experimenter. diffstat: vcweb/vcweb-tornadio.py | 25 +++++++++++++------------ vcweb/vcweb.apache.vhost | 1 + 2 files changed, 14 insertions(+), 12 deletions(-) diffs (83 lines): diff -r 7cc738a5b2ca -r c2aa99a324f0 vcweb/vcweb-tornadio.py --- a/vcweb/vcweb-tornadio.py Fri Apr 22 23:48:13 2011 -0700 +++ b/vcweb/vcweb-tornadio.py Wed Apr 27 14:36:43 2011 -0700 @@ -49,18 +49,20 @@ def add_experimenter(self, connection, incoming_experimenter_pk, incoming_experiment_pk): experimenter_pk = int(incoming_experimenter_pk) experiment_id = int(incoming_experiment_pk) + experimenter_tuple = (experimenter_pk, experiment_id) logger.debug("registering experimenter %s with connection %s" % (experimenter_pk, connection)) if connection in self.connection_to_experimenter: self.remove_experimenter(connection) - self.connection_to_experimenter[connection] = (experimenter_pk, experiment_id) - self.experimenter_to_connection[(experimenter_pk, experiment_id)] = connection + self.connection_to_experimenter[connection] = experimenter_tuple + self.experimenter_to_connection[experimenter_tuple] = connection def remove_experimenter(self, connection): if connection in self.connection_to_experimenter: - (experimenter_pk, experiment_id) = self.connection_to_experimenter[connection] - logger.debug("removing experimenter %s" % experimenter_pk) + experimenter_tuple = self.connection_to_experimenter[connection] + logger.debug("removing experimenter %s" % experimenter_tuple[0]) del self.connection_to_experimenter[connection] - del self.experimenter_to_connection[(experimenter_pk, experiment_id)] + if experimenter_tuple in self.experimenter_to_connection: + del self.experimenter_to_connection[experimenter_tuple] def get_participant_group_relationship(self, connection): if connection in self.connection_to_participant: @@ -85,22 +87,21 @@ return None def add_participant(self, auth_token, connection, participant_experiment_relationship): - participant_tuple = (participant_experiment_relationship.participant.pk, - participant_experiment_relationship.experiment.pk) + participant_tuple = (participant_experiment_relationship.participant.pk, participant_experiment_relationship.experiment.pk) if participant_tuple in self.participant_to_connection: logger.debug("participant already has a connection, removing previous mappings.") - self.remove(self.participant_to_connection[participant_tuple]) + self.remove_participant(self.participant_to_connection[participant_tuple]) self.connection_to_participant[connection] = participant_tuple self.participant_to_connection[participant_tuple] = connection - def remove(self, connection): + def remove_participant(self, connection): try: participant_tuple = self.connection_to_participant[connection] del self.participant_to_connection[participant_tuple] del self.connection_to_participant[connection] except KeyError as k: - logger.warning("caught key error %s while trying to remove connection %s" % (connection, k) ) + logger.warning("caught key error %s while trying to remove participant connection %s" % (connection, k) ) ''' Generator function that yields (participant_group_relationship_id, connection) tuples @@ -216,7 +217,7 @@ #logger.debug("auth token: %s, id %s" % (auth_token, participant_group_relationship_id)) relationship_id = extra try: - participant_experiment_relationship = ParticipantExperimentRelationship.objects.get(pk=relationship_id) + participant_experiment_relationship = ParticipantExperimentRelationship.objects.select_related(depth=1).get(pk=relationship_id) connection_manager.add_participant(extra, self, participant_experiment_relationship) participant_group_rel = connection_manager.get_participant_group_relationship(self) if participant_group_rel is not None: @@ -288,7 +289,7 @@ def on_close(self): logger.debug("closing %s" % self) - connection_manager.remove(self) + connection_manager.remove_participant(self) def main(argv=None): if argv is None: diff -r 7cc738a5b2ca -r c2aa99a324f0 vcweb/vcweb.apache.vhost --- a/vcweb/vcweb.apache.vhost Fri Apr 22 23:48:13 2011 -0700 +++ b/vcweb/vcweb.apache.vhost Wed Apr 27 14:36:43 2011 -0700 @@ -1,4 +1,5 @@ WSGISocketPrefix run/wsgi +WSGIPythonHome /opt/virtualenvs/vcweb <VirtualHost *:80> ServerAdmin all...@as... DocumentRoot /var/www/vcweb |
From: <vir...@li...> - 2011-04-23 06:46:19
|
Subject: hg.virtualcommons 353 details: http://virtualcommons.hg.sourceforge.net:8000/hgroot/virtualcommons/virtualcommons/hgrepo/v/vi/virtualcommons/virtualcommons/rev/7cc738a5b2ca changeset: 353:7cc738a5b2ca user: Allen Lee <all...@as...> date: Fri Apr 22 23:48:13 2011 -0700 description: missing semicolon from WEB_SOCKET_SWF_LOCATION, hopefully that fixes the websocket issues on vcweb.asu.edu diffstat: vcweb/core/templates/includes/jquery.confirm.html | 4 ++-- vcweb/core/templates/includes/jquery.forms.html | 2 +- vcweb/core/templates/includes/socket.io.html | 4 ++-- vcweb/core/templates/includes/tablesorter.html | 4 ++-- vcweb/static/css/tablesorter/style.css | 6 +++--- 5 files changed, 10 insertions(+), 10 deletions(-) diffs (59 lines): diff -r 083387d50167 -r 7cc738a5b2ca vcweb/core/templates/includes/jquery.confirm.html --- a/vcweb/core/templates/includes/jquery.confirm.html Fri Apr 22 22:39:03 2011 -0700 +++ b/vcweb/core/templates/includes/jquery.confirm.html Fri Apr 22 23:48:13 2011 -0700 @@ -1,2 +1,2 @@ -<link href="/static/css/jquery.fastconfirm.css" rel="stylesheet" type="text/css" media="screen" /> -<script type="text/javascript" src="/static/js/jquery.fastconfirm.min.js"></script> +<link href="{{STATIC_URL}}css/jquery.fastconfirm.css" rel="stylesheet" type="text/css" media="screen" /> +<script type="text/javascript" src="{{STATIC_URL}}js/jquery.fastconfirm.min.js"></script> diff -r 083387d50167 -r 7cc738a5b2ca vcweb/core/templates/includes/jquery.forms.html --- a/vcweb/core/templates/includes/jquery.forms.html Fri Apr 22 22:39:03 2011 -0700 +++ b/vcweb/core/templates/includes/jquery.forms.html Fri Apr 22 23:48:13 2011 -0700 @@ -1,1 +1,1 @@ -<script type='text/javascript' src='/static/js/jquery.validate.min.js'></script> +<script type='text/javascript' src='{{STATIC_URL}}js/jquery.validate.min.js'></script> diff -r 083387d50167 -r 7cc738a5b2ca vcweb/core/templates/includes/socket.io.html --- a/vcweb/core/templates/includes/socket.io.html Fri Apr 22 22:39:03 2011 -0700 +++ b/vcweb/core/templates/includes/socket.io.html Fri Apr 22 23:48:13 2011 -0700 @@ -1,6 +1,6 @@ -<script type="text/javascript" src="/static/js/socket.io.min.js"></script> +<script type="text/javascript" src="{{STATIC_URL}}js/socket.io.min.js"></script> <script type="text/javascript"> - WEB_SOCKET_SWF_LOCATION="/static/flash/WebSocketMain.swf" + WEB_SOCKET_SWF_LOCATION="{{STATIC_URL}}flash/WebSocketMain.swf"; </script> <script type="text/javascript"> diff -r 083387d50167 -r 7cc738a5b2ca vcweb/core/templates/includes/tablesorter.html --- a/vcweb/core/templates/includes/tablesorter.html Fri Apr 22 22:39:03 2011 -0700 +++ b/vcweb/core/templates/includes/tablesorter.html Fri Apr 22 23:48:13 2011 -0700 @@ -1,2 +1,2 @@ -<link href="/static/css/tablesorter/style.css" rel="stylesheet" type="text/css" media="screen" /> -<script type="text/javascript" src="/static/js/jquery.tablesorter.min.js"></script> +<link href="{{STATIC_URL}}css/tablesorter/style.css" rel="stylesheet" type="text/css" media="screen" /> +<script type="text/javascript" src="{{STATIC_URL}}js/jquery.tablesorter.min.js"></script> diff -r 083387d50167 -r 7cc738a5b2ca vcweb/static/css/tablesorter/style.css --- a/vcweb/static/css/tablesorter/style.css Fri Apr 22 22:39:03 2011 -0700 +++ b/vcweb/static/css/tablesorter/style.css Fri Apr 22 23:48:13 2011 -0700 @@ -14,7 +14,7 @@ padding: 6px; } table.tablesorter thead tr .header { - background-image: url(/static/css/tablesorter/bg.gif); + background-image: url(bg.gif); background-repeat: no-repeat; background-position: center right; cursor: pointer; @@ -31,10 +31,10 @@ background-color:#F0F0F6; } table.tablesorter thead tr .headerSortUp { - background-image: url(/static/css/tablesorter/asc.gif); + background-image: url(asc.gif); } table.tablesorter thead tr .headerSortDown { - background-image: url(/static/css/tablesorter/desc.gif); + background-image: url(desc.gif); } table.tablesorter thead tr .headerSortDown, table.tablesorter thead tr .headerSortUp { background-color: #8dbdd8; |
From: <vir...@li...> - 2011-04-23 05:37:10
|
Subject: hg.virtualcommons 352 details: http://virtualcommons.hg.sourceforge.net:8000/hgroot/virtualcommons/virtualcommons/hgrepo/v/vi/virtualcommons/virtualcommons/rev/083387d50167 changeset: 352:083387d50167 user: Allen Lee <all...@as...> date: Fri Apr 22 22:39:03 2011 -0700 description: re-adding explicit transition link diffstat: vcweb/core/templates/experimenter/monitor.html | 6 ++---- 1 files changed, 2 insertions(+), 4 deletions(-) diffs (26 lines): diff -r 41e7cacd8680 -r 083387d50167 vcweb/core/templates/experimenter/monitor.html --- a/vcweb/core/templates/experimenter/monitor.html Fri Apr 22 22:32:41 2011 -0700 +++ b/vcweb/core/templates/experimenter/monitor.html Fri Apr 22 22:39:03 2011 -0700 @@ -84,7 +84,7 @@ s.send(createRefreshEvent()); return false; }); - $('#gotoUrl').click(function(evt) { + $('#transitionAllParticipants').click(function(evt) { console.log("sending goto event"); s.send(createGotoEvent()); return false; @@ -120,12 +120,10 @@ <span class='vcweb-icon ui-icon icon-left' style='background:url({{STATIC_URL}}images/famfamfam/arrow_refresh.png);'></span> refresh all participants</span> </li> - {% comment %} - <li><span id='gotoUrl' title='Moves all connected participants from waiting page to active page.' class='clickable' > + <li><span id='transitionAllParticipants' title='Moves all connected participants from waiting page to active page.' class='clickable' > <span class='vcweb-icon ui-icon icon-left' style='background:url({{STATIC_URL}}images/famfamfam/arrow_right.png);'></span> transition all participants to next round</span> </li> - {% endcomment %} <li> <a href='download/csv'> <span class='vcweb-icon ui-icon icon-left' style='margin: 8px 0.15em 0px 0px; background:url({{STATIC_URL}}images/download-icon.png);'></span> |
From: <vir...@li...> - 2011-04-23 05:30:51
|
Subject: hg.virtualcommons 351 details: http://virtualcommons.hg.sourceforge.net:8000/hgroot/virtualcommons/virtualcommons/hgrepo/v/vi/virtualcommons/virtualcommons/rev/41e7cacd8680 changeset: 351:41e7cacd8680 user: Allen Lee <all...@as...> date: Fri Apr 22 22:32:41 2011 -0700 description: fixing broken reference to participant.get_group. Should add some view tests soon. diffstat: vcweb/core/models.py | 19 ++++++++----------- vcweb/forestry/views.py | 2 +- 2 files changed, 9 insertions(+), 12 deletions(-) diffs (71 lines): diff -r 95bf12aed901 -r 41e7cacd8680 vcweb/core/models.py --- a/vcweb/core/models.py Tue Apr 19 23:41:44 2011 -0700 +++ b/vcweb/core/models.py Fri Apr 22 22:32:41 2011 -0700 @@ -1100,7 +1100,7 @@ return self.experiments_with_status(Experiment.COMPLETED) def get_participant_experiment_relationship(self, experiment): - return ParticipantExperimentRelationship.objects.get(participant=self, experiment=experiment) + return ParticipantExperimentRelationship.objects.select_related(depth=1).get(participant=self, experiment=experiment) def get_participant_group_relationship(self, experiment): return ParticipantGroupRelationship.objects.get_participant_group(self, experiment) @@ -1111,10 +1111,10 @@ class Meta: ordering = ['user'] -""" -Many-to-many relationship entity storing a participant and the experiment they are participating in. -""" class ParticipantExperimentRelationship(models.Model): + """ + Many-to-many relationship entity storing a participant and the experiment they are participating in. + """ participant = models.ForeignKey(Participant, related_name='experiment_relationships') participant_identifier = models.CharField(max_length=32) sequential_participant_identifier = models.PositiveIntegerField() @@ -1127,9 +1127,11 @@ super(ParticipantExperimentRelationship, self).__init__(*args, **kwargs) self.generate_identifier() - """ generates a unique identifier for the given participant and experiment stored in this relationship """ def generate_identifier(self): - """ set participant_identifier if it hasn't been set already. """ + """ + generates a unique identifier for the given participant and experiment stored in this relationship. + a no-op if participant_identifier is already set. + """ if not self.participant_identifier: sha1 = hashlib.sha1() sha1.update("%s%i%s" % (self.participant.user.email, self.experiment.pk, self.date_created)) @@ -1137,7 +1139,6 @@ self.sequential_participant_identifier = ParticipantExperimentRelationship.objects.filter(experiment=self.experiment).count() + 1 return self.participant_identifier - def __unicode__(self): return u"Experiment {0} - participant {1} (created {2})".format(self.experiment, self.participant, self.date_created) @@ -1146,10 +1147,6 @@ def by_experiment(self, experiment): return self.select_related(depth=1).filter(group__experiment=experiment) - def get_group(self, experiment, participant): - participant_group = self.get_participant_group(participant, experiment) - return participant_group.group if participant_group else None - def get_participant_group(self, participant, experiment): try: return self.select_related(depth=1).get(group__experiment=experiment, participant=participant) diff -r 95bf12aed901 -r 41e7cacd8680 vcweb/forestry/views.py --- a/vcweb/forestry/views.py Tue Apr 19 23:41:44 2011 -0700 +++ b/vcweb/forestry/views.py Fri Apr 22 22:32:41 2011 -0700 @@ -203,7 +203,7 @@ harvest_decision = get_harvest_decision(participant_group_relationship) if form.is_valid(): resources_harvested = form.cleaned_data['harvest_decision'] - resource_level = get_resource_level(participant.get_group(experiment)) + resource_level = get_resource_level(participant_group_relationship.group) max_harvest_decision = get_max_harvest_decision(resource_level.value) if resources_harvested <= max_harvest_decision: set_harvest_decision(participant_group_relationship=participant_group_relationship, value=resources_harvested) |
From: <vir...@li...> - 2011-04-20 06:40:38
|
Subject: hg.virtualcommons 350 details: http://virtualcommons.hg.sourceforge.net:8000/hgroot/virtualcommons/virtualcommons/hgrepo/v/vi/virtualcommons/virtualcommons/rev/95bf12aed901 changeset: 350:95bf12aed901 user: Allen Lee <all...@as...> date: Tue Apr 19 23:41:44 2011 -0700 description: fixing caching for syncdb, adding refresh keyword to method invocation to let the cache know whether or not it should re-invoke the cached method + tests. diffstat: vcweb/core/__init__.py | 19 +++++++++++-------- vcweb/core/models.py | 1 + vcweb/fabfile.py | 4 +++- vcweb/forestry/models.py | 22 +++++++++++----------- vcweb/forestry/tests.py | 36 +++++++++++++++++++++++++----------- 5 files changed, 51 insertions(+), 31 deletions(-) diffs (172 lines): diff -r ddbe220918d4 -r 95bf12aed901 vcweb/core/__init__.py --- a/vcweb/core/__init__.py Tue Apr 19 14:21:08 2011 -0700 +++ b/vcweb/core/__init__.py Tue Apr 19 23:41:44 2011 -0700 @@ -1,11 +1,14 @@ -# XXX: only works on no-arg functions that return instances of models that will never change (data parameters, -# experiment metadata, etc.) -class cacheable(object): +class simplecache(object): + """ + only works on no-arg functions that return instances of models that will never change (data parameters, + experiment metadata, etc.) + """ def __init__(self, func): - self.cached_object = func() - #self.key = id(self.model_object) - #cacheable.orm_cache[self.key] = self.model_object + # invoking the func at init time causes syncdb to croak + self.cached_object = None + self.func = func - def __call__(self): + def __call__(self, refresh=False): + if self.cached_object is None or refresh: + self.cached_object = self.func() return self.cached_object - #return cacheable.orm_cache[self.key] diff -r ddbe220918d4 -r 95bf12aed901 vcweb/core/models.py --- a/vcweb/core/models.py Tue Apr 19 14:21:08 2011 -0700 +++ b/vcweb/core/models.py Tue Apr 19 23:41:44 2011 -0700 @@ -1081,6 +1081,7 @@ class Meta: ordering = [ 'round_data', 'group', 'parameter' ] + class Participant(CommonsUser): can_receive_invitations = models.BooleanField(default=False) groups = models.ManyToManyField(Group, through='ParticipantGroupRelationship', related_name='participants') diff -r ddbe220918d4 -r 95bf12aed901 vcweb/fabfile.py --- a/vcweb/fabfile.py Tue Apr 19 14:21:08 2011 -0700 +++ b/vcweb/fabfile.py Tue Apr 19 23:41:44 2011 -0700 @@ -32,7 +32,9 @@ syncdb_commands = ['(test -f vcweb.db && rm -f vcweb.db) || true', '%(python)s manage.py syncdb --noinput' % env, '%(python)s manage.py loaddata test_users_participants' % env, - '%(python)s manage.py loaddata forestry_test_data' % env] + '%(python)s manage.py loaddata forestry_test_data' % env, + '%(python)s manage.py loaddata slovakia' % env, + ] def shell(): local("{python} manage.py shell".format(python=env.python), capture=False) diff -r ddbe220918d4 -r 95bf12aed901 vcweb/forestry/models.py --- a/vcweb/forestry/models.py Tue Apr 19 14:21:08 2011 -0700 +++ b/vcweb/forestry/models.py Tue Apr 19 23:41:44 2011 -0700 @@ -1,6 +1,6 @@ from django.dispatch import receiver from vcweb.core.models import (ExperimentMetadata, Parameter, ParticipantGroupRelationship, ParticipantRoundDataValue,) -from vcweb.core import signals, cacheable +from vcweb.core import signals, simplecache from celery.decorators import task import logging logger = logging.getLogger(__name__) @@ -58,30 +58,30 @@ else: return 0 -@cacheable -def get_forestry_experiment_metadata(): +@simplecache +def get_forestry_experiment_metadata(refresh=False): return ExperimentMetadata.objects.get(namespace='forestry') -@cacheable -def get_resource_level_parameter(): +@simplecache +def get_resource_level_parameter(refresh=False): return Parameter.objects.get(name='resource_level', scope=Parameter.GROUP_SCOPE, experiment_metadata=get_forestry_experiment_metadata()) -@cacheable -def get_regrowth_parameter(): +@simplecache +def get_regrowth_parameter(refresh=False): return Parameter.objects.get(name='group_regrowth', scope=Parameter.GROUP_SCOPE, experiment_metadata=get_forestry_experiment_metadata()) -@cacheable -def get_group_harvest_parameter(): +@simplecache +def get_group_harvest_parameter(refresh=False): return Parameter.objects.get(name='group_harvest', scope=Parameter.GROUP_SCOPE, experiment_metadata=get_forestry_experiment_metadata()) -@cacheable -def get_harvest_decision_parameter(): +@simplecache +def get_harvest_decision_parameter(refresh=False): return Parameter.objects.get(name='harvest_decision', scope=Parameter.PARTICIPANT_SCOPE, experiment_metadata=get_forestry_experiment_metadata()) diff -r ddbe220918d4 -r 95bf12aed901 vcweb/forestry/tests.py --- a/vcweb/forestry/tests.py Tue Apr 19 14:21:08 2011 -0700 +++ b/vcweb/forestry/tests.py Tue Apr 19 23:41:44 2011 -0700 @@ -1,8 +1,13 @@ -from vcweb.core.models import RoundConfiguration, Parameter, ParticipantRoundDataValue, GroupRoundDataValue, ParticipantExperimentRelationship, ParticipantGroupRelationship +from vcweb.core.models import (RoundConfiguration, Parameter, + ParticipantRoundDataValue, GroupRoundDataValue, + ParticipantExperimentRelationship, ParticipantGroupRelationship) from vcweb.core.tests import BaseVcwebTest -from vcweb.forestry.models import round_setup, round_teardown, get_resource_level, get_harvest_decision_parameter, get_harvest_decisions, forestry_sender +from vcweb.forestry.models import (get_group_harvest_parameter, + get_regrowth_parameter, round_setup, round_teardown, get_resource_level, + set_resource_level, set_harvest_decision, get_harvest_decision_parameter, + get_harvest_decisions, forestry_sender, get_forestry_experiment_metadata, + get_resource_level_parameter) import logging - logger = logging.getLogger(__name__) class ForestryRoundSignalTest(BaseVcwebTest): @@ -91,7 +96,6 @@ class ForestryParametersTest(BaseVcwebTest): def test_get_set_harvest_decisions(self): - from vcweb.forestry.models import get_harvest_decisions, get_harvest_decision_parameter, set_harvest_decision e = self.advance_to_data_round() # generate harvest decisions current_round_data = e.current_round_data @@ -120,23 +124,33 @@ self.assertEqual(hd.value, 5) - def test_cacheable(self): - from vcweb.forestry.models import (get_group_harvest_parameter, get_regrowth_parameter, - get_forestry_experiment_metadata, get_resource_level_parameter) + def test_simple_cache_parameters(self): def verify_cached_data(func): self.assertEqual(func(), func()) self.assertEqual(id(func()), id(func())) - caching_funcs = (get_harvest_decision_parameter, get_group_harvest_parameter, get_regrowth_parameter, get_resource_level_parameter, get_forestry_experiment_metadata) - for index, func in enumerate(caching_funcs): - verify_cached_data(func) for i in range(0, 25): for func in caching_funcs: verify_cached_data(func) + def test_simple_cache_parameter_refresh(self): + def verify_refreshed_data(func): + self.assertEqual(func(), func()) + a = func() + b = func(refresh=True) + self.assertNotEqual(id(a), id(b)) + self.assertEqual(a, b) + + caching_funcs = (get_harvest_decision_parameter, get_group_harvest_parameter, get_regrowth_parameter, + get_resource_level_parameter, get_forestry_experiment_metadata) + for i in range(0, 25): + for func in caching_funcs: + verify_refreshed_data(func) + + + def test_get_set_resource_level(self): - from vcweb.forestry.models import get_resource_level, set_resource_level e = self.advance_to_data_round() for group in e.groups.all(): |
From: <vir...@li...> - 2011-04-19 21:20:19
|
Subject: hg.virtualcommons 349 details: http://virtualcommons.hg.sourceforge.net:8000/hgroot/virtualcommons/virtualcommons/hgrepo/v/vi/virtualcommons/virtualcommons/rev/ddbe220918d4 changeset: 349:ddbe220918d4 user: Allen Lee <all...@as...> date: Tue Apr 19 14:21:08 2011 -0700 description: simple implementation of caching for parameters/experiment metadata. need to make sure this doesn't come back and bite. diffstat: vcweb/core/__init__.py | 15 ++++++++------- vcweb/core/models.py | 26 +++++++++----------------- vcweb/core/tests.py | 43 ++++++++++++++++++++----------------------- vcweb/fabfile.py | 3 +-- vcweb/forestry/tests.py | 19 ++++++++++++------- 5 files changed, 50 insertions(+), 56 deletions(-) diffs (206 lines): diff -r 2ee0cd6dc43d -r ddbe220918d4 vcweb/core/__init__.py --- a/vcweb/core/__init__.py Tue Apr 19 12:51:39 2011 -0700 +++ b/vcweb/core/__init__.py Tue Apr 19 14:21:08 2011 -0700 @@ -1,10 +1,11 @@ -# FIXME: make sure this is appropriate +# XXX: only works on no-arg functions that return instances of models that will never change (data parameters, +# experiment metadata, etc.) class cacheable(object): - orm_cache = {} def __init__(self, func): - model_object = func() - self.key = id(model_object) - cacheable.orm_cache[self.key] = model_object + self.cached_object = func() + #self.key = id(self.model_object) + #cacheable.orm_cache[self.key] = self.model_object - def __call__(self, *args): - return cacheable.orm_cache[self.key] + def __call__(self): + return self.cached_object + #return cacheable.orm_cache[self.key] diff -r 2ee0cd6dc43d -r ddbe220918d4 vcweb/core/models.py --- a/vcweb/core/models.py Tue Apr 19 12:51:39 2011 -0700 +++ b/vcweb/core/models.py Tue Apr 19 14:21:08 2011 -0700 @@ -311,7 +311,7 @@ @property def playable_round_data(self): - return self.round_data.filter(round_configuration__round_type__in=RoundConfiguration.PLAYABLE_ROUND_CONFIGURATIONS) + return self.round_data.select_related(depth=1).filter(round_configuration__round_type__in=RoundConfiguration.PLAYABLE_ROUND_CONFIGURATIONS) @property def all_quiz_questions(self): @@ -1085,7 +1085,6 @@ can_receive_invitations = models.BooleanField(default=False) groups = models.ManyToManyField(Group, through='ParticipantGroupRelationship', related_name='participants') experiments = models.ManyToManyField(Experiment, through='ParticipantExperimentRelationship', related_name='participants') -# authentication_token = models.CharField(max_length=64, null=True, blank=True) @property def active_experiments(self): @@ -1105,12 +1104,6 @@ def get_participant_group_relationship(self, experiment): return ParticipantGroupRelationship.objects.get_participant_group(self, experiment) - def get_participant_number(self, experiment): - return ParticipantGroupRelationship.objects.get_participant_number(experiment, self) - - def get_group(self, experiment): - return ParticipantGroupRelationship.objects.get_group(experiment, self) - def experiments_with_status(self, status=Experiment.ACTIVE): return self.experiment_relationships.filter(experiment__status=status) @@ -1149,26 +1142,25 @@ class ParticipantGroupRelationshipManager(models.Manager): + def by_experiment(self, experiment): + return self.select_related(depth=1).filter(group__experiment=experiment) + def get_group(self, experiment, participant): participant_group = self.get_participant_group(participant, experiment) return participant_group.group if participant_group else None def get_participant_group(self, participant, experiment): try: - return self.select_related(depth=2).get(group__experiment=experiment, participant=participant) + return self.select_related(depth=1).get(group__experiment=experiment, participant=participant) except ParticipantGroupRelationship.DoesNotExist: logger.warning("Participant %s does not belong to a group in %s" % (participant, experiment)) return None - def get_participant_number(self, experiment, participant): - participant_group = self.get_participant_group(participant, experiment) - return participant_group.participant_number if participant_group else None - -""" -Many-to-many relationship entity storing a participant, group, their participant number in that group, the -round in which they joined the group, and the datetime that they joined the group. -""" class ParticipantGroupRelationship(models.Model): + """ + Many-to-many relationship entity storing a participant, group, their participant number in that group, the + round in which they joined the group, and the datetime that they joined the group. + """ participant_number = models.PositiveIntegerField() participant = models.ForeignKey(Participant, related_name='participant_group_relationships') group = models.ForeignKey(Group, related_name = 'participant_group_relationships') diff -r 2ee0cd6dc43d -r ddbe220918d4 vcweb/core/tests.py --- a/vcweb/core/tests.py Tue Apr 19 12:51:39 2011 -0700 +++ b/vcweb/core/tests.py Tue Apr 19 14:21:08 2011 -0700 @@ -1,8 +1,9 @@ from django.test import TestCase from vcweb.core import signals -from vcweb.core.models import Experiment, Experimenter, ExperimentConfiguration, \ - Participant, ParticipantExperimentRelationship, Group, ExperimentMetadata, \ - RoundConfiguration, Parameter, RoundParameterValue, GroupActivityLog +from vcweb.core.models import (Experiment, Experimenter, ExperimentConfiguration, + Participant, ParticipantExperimentRelationship, ParticipantGroupRelationship, Group, + ExperimentMetadata, RoundConfiguration, Parameter, RoundParameterValue, + GroupActivityLog) import logging logger = logging.getLogger(__name__) @@ -132,15 +133,22 @@ self.experiment.start_round(sender=self) self.assertTrue(self.experiment.is_active) - def test_allocate_groups(self): - self.experiment.allocate_groups(randomize=False) - self.assertEqual(self.experiment.groups.count(), 2, "should be 2 groups after non-randomized allocation") - for p in self.participants: - participant_number = p.get_participant_number(self.experiment) - group = p.get_group(self.experiment) - self.assertFalse(participant_number <= 0 or participant_number > group.max_size) - self.assertEqual(participant_number % group.max_size, p.id % group.max_size) - logger.debug("randomized participant number %i (id: %i)" % (participant_number, p.pk)) + def test_group_allocation(self): + experiment = self.experiment + experiment.allocate_groups(randomize=False) + self.assertEqual(experiment.groups.count(), 2, "there should be 2 groups after non-randomized allocation") + self.assertEqual(sum(map(lambda group:group.participants.count(), experiment.groups.all())), 10) + + def test_participant_numbering(self): + experiment = self.experiment + experiment.allocate_groups(randomize=False) + for pgr in ParticipantGroupRelationship.objects.by_experiment(experiment): + participant_number = pgr.participant_number + group = pgr.group + self.assertTrue(0 < participant_number <= group.max_size) + # FIXME: this relies on the fact that non-randomized group allocation will match the auto increment pk + # generation for the participants. Remove? + self.assertEqual(participant_number % group.max_size, pgr.participant.pk % group.max_size) def test_next_round(self): experiment = self.experiment @@ -151,8 +159,6 @@ round_number += 1 experiment.advance_to_next_round() self.assertTrue(experiment.current_round_sequence_number == round_number) - logger.debug("experiment successfully advanced to next round: %s" % - experiment.current_round) def test_increment_elapsed_time(self): experiment = self.experiment @@ -165,15 +171,6 @@ self.assertEqual(experiment.current_round_elapsed_time, current_round_elapsed_time + 1) self.assertEqual(experiment.total_elapsed_time, total_elapsed_time + 1) - - def test_get_participant_number(self): - self.experiment.allocate_groups() - self.assertEqual(self.experiment.groups.count(), 2, "Should have two groups after allocation") - for p in self.participants: - participant_number = p.get_participant_number(self.experiment) - self.assertTrue(participant_number > 0, 'participant number should be greater than 0') - logger.debug("participant number %i (id: %i)" % (participant_number, p.pk)) - class GroupTest(BaseVcwebTest): def test_set_data_value_activity_log(self): e = self.advance_to_data_round() diff -r 2ee0cd6dc43d -r ddbe220918d4 vcweb/fabfile.py --- a/vcweb/fabfile.py Tue Apr 19 12:51:39 2011 -0700 +++ b/vcweb/fabfile.py Tue Apr 19 14:21:08 2011 -0700 @@ -83,8 +83,7 @@ runs tests on this local codebase, not the deployed codebase ''' with cd(env.project_path): - with hide('stdout'): - _virtualenv('%(python)s manage.py test %(apps)s' % env) + _virtualenv('%(python)s manage.py test %(apps)s' % env) def tornado(ip="149.169.203.115", port=8888): local("{python} vcweb-tornado.py {port}".format(python=env.python, **locals()), capture=False) diff -r 2ee0cd6dc43d -r ddbe220918d4 vcweb/forestry/tests.py --- a/vcweb/forestry/tests.py Tue Apr 19 12:51:39 2011 -0700 +++ b/vcweb/forestry/tests.py Tue Apr 19 14:21:08 2011 -0700 @@ -121,14 +121,19 @@ def test_cacheable(self): - from vcweb.forestry.models import (get_group_harvest_parameter, get_regrowth_parameter, get_forestry_experiment_metadata, get_resource_level_parameter, cacheable) - self.assertEqual(get_harvest_decision_parameter(), get_harvest_decision_parameter()) - self.assertEqual(get_group_harvest_parameter(), get_group_harvest_parameter()) - self.assertEqual(get_regrowth_parameter(), get_regrowth_parameter()) - self.assertEqual(get_forestry_experiment_metadata(), get_forestry_experiment_metadata()) - self.assertEqual(get_resource_level_parameter(), get_resource_level_parameter()) - self.assertEqual(len(cacheable.orm_cache), 5) + from vcweb.forestry.models import (get_group_harvest_parameter, get_regrowth_parameter, + get_forestry_experiment_metadata, get_resource_level_parameter) + def verify_cached_data(func): + self.assertEqual(func(), func()) + self.assertEqual(id(func()), id(func())) + caching_funcs = (get_harvest_decision_parameter, get_group_harvest_parameter, get_regrowth_parameter, + get_resource_level_parameter, get_forestry_experiment_metadata) + for index, func in enumerate(caching_funcs): + verify_cached_data(func) + for i in range(0, 25): + for func in caching_funcs: + verify_cached_data(func) def test_get_set_resource_level(self): from vcweb.forestry.models import get_resource_level, set_resource_level |
From: <vir...@li...> - 2011-04-19 19:50:41
|
Subject: hg.virtualcommons 348 details: http://virtualcommons.hg.sourceforge.net:8000/hgroot/virtualcommons/virtualcommons/hgrepo/v/vi/virtualcommons/virtualcommons/rev/2ee0cd6dc43d changeset: 348:2ee0cd6dc43d user: Allen Lee <all...@as...> date: Tue Apr 19 12:51:39 2011 -0700 description: adding simple caching decorator for parameters (the actual parameters very rarely change) diffstat: vcweb/core/__init__.py | 10 +++ vcweb/core/models.py | 44 +++++++++----- vcweb/core/tests.py | 138 ++++++++++++++++++++++------------------------ vcweb/core/views.py | 4 +- vcweb/forestry/models.py | 30 ++++++---- vcweb/forestry/tests.py | 92 ++++++++++++++++-------------- vcweb/forestry/views.py | 5 +- 7 files changed, 177 insertions(+), 146 deletions(-) diffs (762 lines): diff -r 1a81a16fe890 -r 2ee0cd6dc43d vcweb/core/__init__.py --- a/vcweb/core/__init__.py Mon Apr 18 16:08:14 2011 -0700 +++ b/vcweb/core/__init__.py Tue Apr 19 12:51:39 2011 -0700 @@ -0,0 +1,10 @@ +# FIXME: make sure this is appropriate +class cacheable(object): + orm_cache = {} + def __init__(self, func): + model_object = func() + self.key = id(model_object) + cacheable.orm_cache[self.key] = model_object + + def __call__(self, *args): + return cacheable.orm_cache[self.key] diff -r 1a81a16fe890 -r 2ee0cd6dc43d vcweb/core/models.py --- a/vcweb/core/models.py Mon Apr 18 16:08:14 2011 -0700 +++ b/vcweb/core/models.py Tue Apr 19 12:51:39 2011 -0700 @@ -698,6 +698,21 @@ def get_by_natural_key(self, key): return self.get(name=key) + ''' + name_cache = {} + def get(self, *args, **kwargs): + if 'name' in kwargs: + # check cache + name = kwargs['name'] + if name in self.name_cache: + return self.name_cache[name] + parameter = super(ParameterManager, self).get(*args, **kwargs) + self.name_cache[name] = parameter + return parameter + else: + return super(ParameterManager, self).get(*args, **kwargs) + ''' + class Parameter(models.Model): PARAMETER_TYPES = (('int', 'Integer value'), ('string', 'String value'), @@ -1084,20 +1099,6 @@ def completed_experiments(self): return self.experiments_with_status(Experiment.COMPLETED) - def set_data_value(self, experiment=None, parameter=None, value=None): - if experiment and parameter and value is not None: - # FIXME: shift to ParticipantGroupRelationship as data arbiter - current_round_data = experiment.current_round_data - participant_group_relationship = ParticipantGroupRelationship.objects.get(group__experiment=experiment, participant=self) - participant_data_value, created = current_round_data.participant_data_values.get_or_create(parameter=parameter, - participant_group_relationship=participant_group_relationship) - participant_data_value.value = value - # FIXME: parameterize / make explicit? - participant_data_value.submitted = True - participant_data_value.save() - else: - logger.warning("Unable to set data value %s on experiment %s for %s" % (value, experiment, parameter)) - def get_participant_experiment_relationship(self, experiment): return ParticipantExperimentRelationship.objects.get(participant=self, experiment=experiment) @@ -1154,7 +1155,7 @@ def get_participant_group(self, participant, experiment): try: - return self.get(group__experiment=experiment, participant=participant) + return self.select_related(depth=2).get(group__experiment=experiment, participant=participant) except ParticipantGroupRelationship.DoesNotExist: logger.warning("Participant %s does not belong to a group in %s" % (participant, experiment)) return None @@ -1185,6 +1186,19 @@ def group_number(self): return self.group.number + def set_data_value(self, parameter=None, value=None): + current_round_data = self.current_round_data + if parameter is not None and value is not None: + # FIXME: shift to ParticipantGroupRelationship as data arbiter? + participant_data_value, created = current_round_data.participant_data_values.get_or_create(parameter=parameter, participant_group_relationship=self) + participant_data_value.value = value + # FIXME: parameterize / make explicit? + participant_data_value.submitted = True + participant_data_value.save() + else: + logger.warning("Unable to set data value %s on round data %s for %s" % (value, current_round_data, parameter)) + + def __unicode__(self): return u"{0}: #{1} (in {2})".format(self.participant, self.participant_number, self.group) diff -r 1a81a16fe890 -r 2ee0cd6dc43d vcweb/core/tests.py --- a/vcweb/core/tests.py Mon Apr 18 16:08:14 2011 -0700 +++ b/vcweb/core/tests.py Tue Apr 19 12:51:39 2011 -0700 @@ -72,7 +72,7 @@ q = connection.SimpleQueue("chat") for test_string in ('testing', '1-2-3', 'good gravy'): q.put(test_string) - self.failUnlessEqual(test_string, q.get().body) + self.assertEqual(test_string, q.get().body) def test_publish(self): pass @@ -89,7 +89,7 @@ 'abcdefghijklmnopqrstuvwxyz1234567890/abcdefghijklmnopqrstuvwxyz1234567890', ) for namespace in valid_namespaces: - self.failUnless(self.namespace_regex.match(namespace)) + self.assertTrue(self.namespace_regex.match(namespace)) em = self.create_experiment_metadata(namespace) em.save() @@ -100,84 +100,78 @@ '/!@') for namespace in invalid_namespaces: em = self.create_experiment_metadata(namespace) - self.failUnlessRaises(ValidationError, em.full_clean) - self.failIf(self.namespace_regex.match(namespace)) + self.assertRaises(ValidationError, em.full_clean) + self.assertFalse(self.namespace_regex.match(namespace)) def test_unicode(self): em = self.create_experiment_metadata('test_unicode_namespace') em.save() - self.failUnless(em.pk and (em.pk > 0), 'test unicode namespace experiment metadata record should have valid id now') - self.failUnless(em.__unicode__()) - self.failUnlessRaises(ValueError, em.__unicode__().index, '{') - logger.debug("unicode is %s" % em.__unicode__()) + self.assertTrue(em.pk and (em.pk > 0), 'test unicode namespace experiment metadata record should have valid id now') + self.assertTrue(unicode(em)) + #self.assertRaises(ValueError, unicode(em).index, '{') class ExperimentConfigurationTest(BaseVcwebTest): - def test_final_sequence_number(self): e = self.experiment ec = e.experiment_configuration - self.failUnlessEqual(ec.final_sequence_number, ec.last_round_sequence_number) + self.assertEqual(ec.final_sequence_number, ec.last_round_sequence_number) class ExperimentTest(BaseVcwebTest): - def round_started_test_handler(self, experiment=None, time=None, round_configuration=None, **kwargs): - logger.debug("invoking round started test handler with args experiment_id:%i time:%s round_configuration_id:%s" + logger.debug("invoking round started test handler with args experiment:%s time:%s round_configuration_id:%s" % (experiment, time, round_configuration)) - self.failUnlessEqual(experiment, self.experiment) - self.failUnlessEqual(round_configuration, self.experiment.current_round) - self.failUnless(time, "time should be set") - raise Exception + self.assertEqual(experiment, self.experiment) + self.assertEqual(round_configuration, self.experiment.current_round) + self.assertTrue(time, "time should be set") + raise AssertionError def test_start_round(self): signals.round_started.connect(self.round_started_test_handler, sender=self) - try: + with self.assertRaises(AssertionError): self.experiment.start_round(sender=self) - self.fail("Should have raised an exception.") - except Exception, e: - logger.debug("expected exception raised: %s" % e) - self.failUnless(self.experiment.is_active) + self.assertTrue(self.experiment.is_active) def test_allocate_groups(self): self.experiment.allocate_groups(randomize=False) - self.failUnlessEqual(self.experiment.groups.count(), 2, "should be 2 groups after non-randomized allocation") + self.assertEqual(self.experiment.groups.count(), 2, "should be 2 groups after non-randomized allocation") for p in self.participants: participant_number = p.get_participant_number(self.experiment) group = p.get_group(self.experiment) - self.failIf(participant_number <= 0 or participant_number > group.max_size) - self.failUnlessEqual(participant_number % group.max_size, p.id % group.max_size) + self.assertFalse(participant_number <= 0 or participant_number > group.max_size) + self.assertEqual(participant_number % group.max_size, p.id % group.max_size) logger.debug("randomized participant number %i (id: %i)" % (participant_number, p.pk)) def test_next_round(self): experiment = self.experiment round_number = experiment.current_round_sequence_number - self.failUnless(round_number >= 0) - self.failUnless(experiment.has_next_round) + self.assertTrue(round_number >= 0) + self.assertTrue(experiment.has_next_round) while (experiment.has_next_round): round_number += 1 experiment.advance_to_next_round() - self.failUnless(experiment.current_round_sequence_number == round_number) + self.assertTrue(experiment.current_round_sequence_number == round_number) logger.debug("experiment successfully advanced to next round: %s" % experiment.current_round) def test_increment_elapsed_time(self): experiment = self.experiment current_round_elapsed_time = experiment.current_round_elapsed_time - self.failUnless(current_round_elapsed_time == 0) + self.assertTrue(current_round_elapsed_time == 0) total_elapsed_time = experiment.total_elapsed_time - self.failUnless(total_elapsed_time == 0) + self.assertTrue(total_elapsed_time == 0) Experiment.objects.increment_elapsed_time(status=experiment.status) experiment = self.load_experiment() - self.failUnlessEqual(experiment.current_round_elapsed_time, current_round_elapsed_time + 1) - self.failUnlessEqual(experiment.total_elapsed_time, total_elapsed_time + 1) + self.assertEqual(experiment.current_round_elapsed_time, current_round_elapsed_time + 1) + self.assertEqual(experiment.total_elapsed_time, total_elapsed_time + 1) def test_get_participant_number(self): self.experiment.allocate_groups() - self.failUnlessEqual(self.experiment.groups.count(), 2, "Should have two groups after allocation") + self.assertEqual(self.experiment.groups.count(), 2, "Should have two groups after allocation") for p in self.participants: participant_number = p.get_participant_number(self.experiment) - self.failUnless(participant_number > 0, 'participant number should be greater than 0') + self.assertTrue(participant_number > 0, 'participant number should be greater than 0') logger.debug("participant number %i (id: %i)" % (participant_number, p.pk)) class GroupTest(BaseVcwebTest): @@ -191,8 +185,8 @@ # this way since typical usage would do a lookup by name. g.set_data_value(parameter=data_value.parameter, value=test_data_value) activity_log_counter += 1 - self.failUnlessEqual(activity_log_counter, GroupActivityLog.objects.filter(group=g).count()) - self.failUnlessEqual(g.get_scalar_data_value(parameter=data_value.parameter), test_data_value) + self.assertEqual(activity_log_counter, GroupActivityLog.objects.filter(group=g).count()) + 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') @@ -203,14 +197,14 @@ if first_pass: for g in e.groups.all(): g.set_data_value(parameter=parameter, value=test_data_value) - self.failUnlessEqual(g.get_data_value(parameter=parameter).value, test_data_value) - self.failUnlessEqual(g.get_scalar_data_value(parameter=parameter), test_data_value) + self.assertEqual(g.get_data_value(parameter=parameter).value, test_data_value) + self.assertEqual(g.get_scalar_data_value(parameter=parameter), test_data_value) g.transfer_to_next_round(parameter) first_pass = False else: for g in e.groups.all(): - self.failUnlessEqual(g.get_data_value(parameter=parameter).value, test_data_value) - self.failUnlessEqual(g.get_scalar_data_value(parameter=parameter), test_data_value) + self.assertEqual(g.get_data_value(parameter=parameter).value, test_data_value) + self.assertEqual(g.get_scalar_data_value(parameter=parameter), test_data_value) g.transfer_to_next_round(parameter) e.advance_to_next_round() @@ -221,27 +215,27 @@ # instructions round for g in e.groups.all(): g.initialize_data_parameters() - self.failUnlessEqual(e.current_round_data.group_data_values.count(), 0) - self.failUnlessEqual(e.current_round_data.participant_data_values.count(), 0) + self.assertEqual(e.current_round_data.group_data_values.count(), 0) + self.assertEqual(e.current_round_data.participant_data_values.count(), 0) # quiz round e.advance_to_next_round() e.start_round() for g in e.groups.all(): g.initialize_data_parameters() # FIXME: (changed to practice round for demo purposes) - #self.failUnlessEqual(e.current_round_data.group_data_values.count(), 0) - #self.failUnlessEqual(e.current_round_data.participant_data_values.count(), 0) + #self.assertEqual(e.current_round_data.group_data_values.count(), 0) + #self.assertEqual(e.current_round_data.participant_data_values.count(), 0) # first practice round e.advance_to_next_round() e.start_round() for g in e.groups.all(): for i in xrange(10): - self.failUnlessEqual(e.current_round_data.group_data_values.count(), 2) + self.assertEqual(e.current_round_data.group_data_values.count(), 2) # multiple invocations to initialize_data_parameters should be harmless. g.initialize_data_parameters() - self.failUnlessEqual(e.current_round_data.group_data_values.count(), 2) + self.assertEqual(e.current_round_data.group_data_values.count(), 2) g.initialize_data_parameters() - self.failUnlessEqual(e.current_round_data.group_data_values.count(), 2) + self.assertEqual(e.current_round_data.group_data_values.count(), 2) g.initialize_data_parameters() # first chat round (practice) e.end_round() @@ -249,8 +243,8 @@ e.start_round() for g in e.groups.all(): g.initialize_data_parameters() - self.failUnlessEqual(e.current_round_data.group_data_values.count(), 2) - self.failUnlessEqual(e.current_round_data.participant_data_values.count(), 0) + self.assertEqual(e.current_round_data.group_data_values.count(), 2) + self.assertEqual(e.current_round_data.participant_data_values.count(), 0) # second practice round @@ -264,8 +258,8 @@ g.add_participant(p) count += 1 self.assertTrue(g.participants) - self.failUnlessEqual(g.participants.count(), count, "group.participants size should be %i" % count) - self.failUnlessEqual(g.size, count, "group size should be %i" % count) + self.assertEqual(g.participants.count(), count, "group.participants size should be %i" % count) + self.assertEqual(g.size, count, "group size should be %i" % count) class ParticipantExperimentRelationshipTest(BaseVcwebTest): @@ -276,27 +270,27 @@ for p in self.participants: per = ParticipantExperimentRelationship.objects.create(participant=p, experiment=e, created_by=self.experimenter.user) - self.failUnless(per.id > 0) + self.assertTrue(per.id > 0) logger.debug("Participant identifier is %s - sequential id is %i" % (per.participant_identifier, per.sequential_participant_identifier)) - self.failUnless(per.participant_identifier) - self.failUnless(per.sequential_participant_identifier > 0) + self.assertTrue(per.participant_identifier) + self.assertTrue(per.sequential_participant_identifier > 0) - self.failUnlessEqual(e.participants.count(), self.participants.count()) + self.assertEqual(e.participants.count(), self.participants.count()) class RoundConfigurationTest(BaseVcwebTest): def test_round_configuration_enums(self): - self.failUnlessEqual(len(RoundConfiguration.ROUND_TYPES), len(RoundConfiguration.ROUND_TYPES_DICT)) - self.failUnlessEqual(RoundConfiguration.PRACTICE, 'PRACTICE') - self.failUnlessEqual(RoundConfiguration.REGULAR, 'REGULAR') + 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.failUnlessEqual(len(choices), len(RoundConfiguration.ROUND_TYPES_DICT)) + self.assertEqual(len(choices), len(RoundConfiguration.ROUND_TYPES_DICT)) for pair in choices: - self.failUnless(pair[0] in RoundConfiguration.ROUND_TYPES_DICT.keys()) - self.failUnless(pair[0] in RoundConfiguration.ROUND_TYPES) - self.failIf(pair[1].isupper()) + 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_get_set_parameter(self): e = self.experiment @@ -304,26 +298,26 @@ round_configuration = e.current_round name = 'initial.resource_level' round_configuration.set_parameter(name=name, value=501) - self.failUnlessEqual(round_configuration.get_parameter_value(name), 501) - self.failUnlessEqual(round_configuration.get_parameter(name).value, round_configuration.get_parameter_value(name)) + self.assertEqual(round_configuration.get_parameter_value(name), 501) + self.assertEqual(round_configuration.get_parameter(name).value, round_configuration.get_parameter_value(name)) 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) rp = RoundParameterValue.objects.create(parameter=p, round_configuration=e.current_round, value='14') - self.failUnlessEqual(14, rp.int_value) + self.assertEqual(14, rp.int_value) def test_round_parameters(self): e = self.experiment p = Parameter.objects.create(scope='round', name='test_round_parameter', type='int', creator=e.experimenter, experiment_metadata=e.experiment_metadata) - self.failUnless(p.pk > 0) - self.failUnlessEqual(p.value_field_name, 'int_value') + self.assertTrue(p.pk > 0) + self.assertEqual(p.value_field_name, 'int_value') for val in (14, '14', 14.0, '14.0'): rp = RoundParameterValue.objects.create(parameter=p, round_configuration=e.current_round, value=val) - self.failUnless(rp.pk > 0) - self.failUnlessEqual(rp.value, 14) + self.assertTrue(rp.pk > 0) + self.assertEqual(rp.value, 14) ''' The type field in Parameter generates the value_field_name property by concatenating the name of the type with _value. @@ -332,10 +326,10 @@ for type in ('int', 'float', 'string', 'boolean'): p = Parameter.objects.create(scope='round', name="test_nonunique_round_parameter_%s" % type, type=type, creator=e.experimenter, experiment_metadata=e.experiment_metadata) - self.failUnless(p.pk > 0) - self.failUnlessEqual(p.value_field_name, '%s_value' % type) + self.assertTrue(p.pk > 0) + self.assertEqual(p.value_field_name, '%s_value' % type) rp = RoundParameterValue.objects.create(parameter=p, round_configuration=e.current_round, value=sample_values_for_type[type]) - self.failUnlessEqual(rp.value, sample_values_for_type[type]) + self.assertEqual(rp.value, sample_values_for_type[type]) def test_get_templates(self): @@ -344,4 +338,4 @@ logger.debug("inspecting round type: %s with data %s" % (round_type, data)) rc = self.create_new_round_configuration(round_type=round_type) e.current_round_sequence_number = rc.sequence_number - self.failUnlessEqual(e.current_round_template, "%s/%s" % (e.namespace, data[1]), 'should have returned template for ' + data[0]) + self.assertEqual(e.current_round_template, "%s/%s" % (e.namespace, data[1]), 'should have returned template for ' + data[0]) diff -r 1a81a16fe890 -r 2ee0cd6dc43d vcweb/core/views.py --- a/vcweb/core/views.py Mon Apr 18 16:08:14 2011 -0700 +++ b/vcweb/core/views.py Tue Apr 19 12:51:39 2011 -0700 @@ -178,7 +178,7 @@ class ExperimenterSingleExperimentMixin(SingleExperimentMixin, ExperimenterMixin): def check_user(self, user, experiment): - if self.request.user.experimenter.pk == experiment.experimenter.pk: + if self.request.user.experimenter == experiment.experimenter: return experiment raise PermissionDenied("You do not have access to %s" % experiment) @@ -327,7 +327,7 @@ experiment = Experiment.objects.get(pk=pk) # TODO: provide experimenter access to other users besides the creator of the # experiment? - if experimenter.pk == experiment.experimenter.pk: + if experimenter == experiment.experimenter: experiment_func = getattr(experiment, experiment_action.replace('-', '_'), None) if experiment_func: # pass params? start_round() takes a sender for instance.. diff -r 1a81a16fe890 -r 2ee0cd6dc43d vcweb/forestry/models.py --- a/vcweb/forestry/models.py Mon Apr 18 16:08:14 2011 -0700 +++ b/vcweb/forestry/models.py Tue Apr 19 12:51:39 2011 -0700 @@ -1,6 +1,6 @@ from django.dispatch import receiver from vcweb.core.models import (ExperimentMetadata, Parameter, ParticipantGroupRelationship, ParticipantRoundDataValue,) -from vcweb.core import signals +from vcweb.core import signals, cacheable from celery.decorators import task import logging logger = logging.getLogger(__name__) @@ -11,12 +11,12 @@ check all forestry experiments. ''' - -# returns GroupRoundDataValue. def get_resource_level(group=None, round_data=None): + ''' returns the group resource level data parameter ''' return group.get_data_value(parameter=get_resource_level_parameter(), round_data=round_data) def get_group_harvest(group, round_data=None): + ''' returns the collective group harvest data parameter ''' return group.get_data_value(parameter=get_group_harvest_parameter(), round_data=round_data) def get_regrowth(group, round_data=None): @@ -58,32 +58,36 @@ else: return 0 +@cacheable def get_forestry_experiment_metadata(): return ExperimentMetadata.objects.get(namespace='forestry') +@cacheable def get_resource_level_parameter(): return Parameter.objects.get(name='resource_level', scope=Parameter.GROUP_SCOPE, experiment_metadata=get_forestry_experiment_metadata()) +@cacheable def get_regrowth_parameter(): return Parameter.objects.get(name='group_regrowth', scope=Parameter.GROUP_SCOPE, experiment_metadata=get_forestry_experiment_metadata()) +@cacheable def get_group_harvest_parameter(): return Parameter.objects.get(name='group_harvest', scope=Parameter.GROUP_SCOPE, experiment_metadata=get_forestry_experiment_metadata()) +@cacheable def get_harvest_decision_parameter(): - return Parameter.objects.get( - name='harvest_decision', + return Parameter.objects.get(name='harvest_decision', scope=Parameter.PARTICIPANT_SCOPE, experiment_metadata=get_forestry_experiment_metadata()) -def set_harvest_decision(participant=None, experiment=None, value=None): - participant.set_data_value(experiment=experiment, parameter=get_harvest_decision_parameter(), value=value) +def set_harvest_decision(participant_group_relationship=None, value=None): + participant_group_relationship.set_data_value(parameter=get_harvest_decision_parameter(), value=value) def set_resource_level(group=None, value=None): group.set_data_value(parameter=get_resource_level_parameter(), value=value) @@ -110,14 +114,16 @@ harvest decision parameters ''' if round_configuration.get_parameter_value('reset.resource_level', default=False): + initial_resource_level = round_configuration.get_parameter_value('initial.resource_level', default=100) for group in experiment.groups.all(): - ''' set resource level to default ''' - set_resource_level(group, round_configuration.get_parameter_value('initial.resource_level')) - ''' initialize all participant data values ''' + ''' set resource level to initial default ''' + group.log("Setting resource level to initial value [%s]" % initial_resource_level) + set_resource_level(group, initial_resource_level) + ''' initialize participant data values ''' current_round_data = experiment.current_round_data harvest_decision_parameter = get_harvest_decision_parameter() - for p in ParticipantGroupRelationship.objects.filter(group__experiment=experiment): - harvest_decision, created = current_round_data.participant_data_values.get_or_create(participant_group_relationship=p, parameter=harvest_decision_parameter) + for pgr in ParticipantGroupRelationship.objects.filter(group__experiment=experiment): + harvest_decision, created = current_round_data.participant_data_values.get_or_create(participant_group_relationship=pgr, parameter=harvest_decision_parameter) logger.debug("%s harvest decision %s" % ("created" if created else "retrieved", harvest_decision)) @task diff -r 1a81a16fe890 -r 2ee0cd6dc43d vcweb/forestry/tests.py --- a/vcweb/forestry/tests.py Mon Apr 18 16:08:14 2011 -0700 +++ b/vcweb/forestry/tests.py Tue Apr 19 12:51:39 2011 -0700 @@ -8,7 +8,7 @@ class ForestryRoundSignalTest(BaseVcwebTest): def verify_resource_level(self, group, value=100): - self.failUnlessEqual(get_resource_level(group).value, value) + self.assertEqual(get_resource_level(group).value, value) def test_round_ended_signal(self): e = self.test_round_started_signal() @@ -36,7 +36,7 @@ for group in e.groups.all(): ds = get_harvest_decisions(group) self.verify_resource_level(group) - self.failUnlessEqual(len(ds), group.participants.count()) + self.assertEqual(len(ds), group.participants.count()) for p in group.participants.all(): pgr = ParticipantGroupRelationship.objects.get(group=group, participant=p) pdv = ParticipantRoundDataValue.objects.get( @@ -44,8 +44,8 @@ participant_group_relationship=pgr, round_data=current_round_data ) - self.failUnless(pdv.pk > 0) - self.failIf(pdv.value) + self.assertTrue(pdv.pk > 0) + self.assertFalse(pdv.value) pdv.value = group.number % 5 pdv.save() @@ -60,13 +60,13 @@ return after_regrowth for group in e.groups.all(): - self.failUnlessEqual(get_resource_level(group).value, + self.assertEqual(get_resource_level(group).value, expected_resource_level(group)) e.advance_to_next_round() for group in e.groups.all(): resource_level = get_resource_level(group) - self.failUnlessEqual(resource_level.value, expected_resource_level(group)) + self.assertEqual(resource_level.value, expected_resource_level(group)) def test_round_ended(self): e = self.test_round_setup() @@ -78,11 +78,11 @@ e = self.experiment rc = self.create_new_round_configuration(round_type=RoundConfiguration.QUIZ, template_name='quiz_23.html') e.current_round_sequence_number = rc.sequence_number - self.failUnlessEqual(e.current_round_template, 'forestry/quiz_23.html', 'should return specified quiz_template') + self.assertEqual(e.current_round_template, 'forestry/quiz_23.html', 'should return specified quiz_template') rc = self.create_new_round_configuration(round_type=RoundConfiguration.QUIZ) e.current_round_sequence_number = rc.sequence_number - self.failUnlessEqual(e.current_round_template, 'forestry/quiz.html', 'should return default quiz.html') + self.assertEqual(e.current_round_template, 'forestry/quiz.html', 'should return default quiz.html') ''' @@ -98,28 +98,37 @@ harvest_decision_parameter = get_harvest_decision_parameter() for group in e.groups.all(): ds = get_harvest_decisions(group) - self.failIf(ds, 'there should not be any harvest decisions.') + self.assertFalse(ds, 'there should not be any harvest decisions.') for p in group.participants.all(): pgr = ParticipantGroupRelationship.objects.get(participant=p, group=group) pdv = current_round_data.participant_data_values.create( participant_group_relationship=pgr, parameter=harvest_decision_parameter) - self.failUnless(pdv.pk > 0) - self.failIf(pdv.value) + self.assertTrue(pdv.pk > 0) + self.assertFalse(pdv.value) pdv.value = 3 pdv.save() ds = get_harvest_decisions(group) - self.failUnless(ds) + self.assertTrue(ds) for hd in ds.all(): - self.failUnlessEqual(hd.value, 3) + self.assertEqual(hd.value, 3) - for p in group.participants.all(): - set_harvest_decision(participant=p, experiment=e, value=5) + for pgr in ParticipantGroupRelationship.objects.filter(group=group): + set_harvest_decision(participant_group_relationship=pgr, value=5) for hd in ds.all(): - self.failUnlessEqual(hd.value, 5) + self.assertEqual(hd.value, 5) + def test_cacheable(self): + from vcweb.forestry.models import (get_group_harvest_parameter, get_regrowth_parameter, get_forestry_experiment_metadata, get_resource_level_parameter, cacheable) + self.assertEqual(get_harvest_decision_parameter(), get_harvest_decision_parameter()) + self.assertEqual(get_group_harvest_parameter(), get_group_harvest_parameter()) + self.assertEqual(get_regrowth_parameter(), get_regrowth_parameter()) + self.assertEqual(get_forestry_experiment_metadata(), get_forestry_experiment_metadata()) + self.assertEqual(get_resource_level_parameter(), get_resource_level_parameter()) + self.assertEqual(len(cacheable.orm_cache), 5) + def test_get_set_resource_level(self): from vcweb.forestry.models import get_resource_level, set_resource_level @@ -127,71 +136,70 @@ for group in e.groups.all(): resource_level = get_resource_level(group) - self.failUnless(resource_level.pk > 0) - self.failIf(resource_level.value) + self.assertTrue(resource_level.pk > 0) + self.assertFalse(resource_level.value) resource_level.value = 3 resource_level.save() for group in e.groups.all(): resource_level = get_resource_level(group) - self.failUnlessEqual(resource_level.value, 3) + self.assertEqual(resource_level.value, 3) for group in e.groups.all(): set_resource_level(group, 100) - self.failUnlessEqual(get_resource_level(group).value, 100) + self.assertEqual(get_resource_level(group).value, 100) for group in e.groups.all(): resource_level = get_resource_level(group) - self.failUnlessEqual(resource_level.value, 100) + self.assertEqual(resource_level.value, 100) def test_group_round_data(self): data_round_number = 1 current_round_data = None for e in self.all_data_rounds(): - self.failIfEqual(current_round_data, e.current_round_data) + self.assertNotEqual(current_round_data, e.current_round_data) current_round_data = e.current_round_data for data_value in current_round_data.group_data_values.filter(parameter__name='resource_level'): # test string conversion logger.debug("current round data: pk:%s value:%s unicode:%s" % (data_value.pk, data_value.value, data_value)) - self.failUnless(data_value.pk > 0) - self.failIf(data_value.value) + self.assertTrue(data_value.pk > 0) + self.assertFalse(data_value.value) data_value.value = 100 data_value.save() - self.failUnlessEqual(100, data_value.value) - self.failUnlessEqual('resource_level', data_value.parameter.name) + self.assertEqual(100, data_value.value) + self.assertEqual('resource_level', data_value.parameter.name) data_value.value = 50 data_value.save() - self.failUnlessEqual(50, data_value.value) + self.assertEqual(50, data_value.value) - self.failUnlessEqual(e.current_round_data.group_data_values.count(), GroupRoundDataValue.objects.filter(experiment=e, round_data=current_round_data).count()) - self.failUnlessEqual(e.parameters(scope=Parameter.GROUP_SCOPE).count(), 3) + self.assertEqual(e.current_round_data.group_data_values.count(), GroupRoundDataValue.objects.filter(experiment=e, round_data=current_round_data).count()) + self.assertEqual(e.parameters(scope=Parameter.GROUP_SCOPE).count(), 3) data_round_number += 1 def test_data_parameters(self): e = self.experiment # FIXME: horrible tests, improve - self.failUnlessEqual(6, e.parameters().count()) + self.assertEqual(6, e.parameters().count()) for data_param in e.parameters(scope=Parameter.GROUP_SCOPE).all(): logger.debug("inspecting data param %s" % data_param) - self.failUnlessEqual(data_param.type, 'int', 'Currently all group data parameters for the forestry experiment are ints.') + self.assertEqual(data_param.type, 'int', 'Currently all group data parameters for the forestry experiment are ints.') def create_participant_data_values(self): e = self.experiment e.activate() - rc = e.current_round current_round_data = e.current_round_data for data_param in e.parameters(scope=Parameter.PARTICIPANT_SCOPE).all(): for p in self.participants: pexpr = ParticipantExperimentRelationship.objects.get(participant=p, experiment=e) pgroupr = ParticipantGroupRelationship.objects.get(group__experiment=e, participant=p) - dv = current_round_data.participant_data_values.create(participant_group_relationship=pgroupr, parameter=data_param, value=pexpr.sequential_participant_identifier * 2) + current_round_data.participant_data_values.create(participant_group_relationship=pgroupr, parameter=data_param, value=pexpr.sequential_participant_identifier * 2) return e def test_data_values(self): e = self.create_participant_data_values() num_participant_parameters = e.parameters(scope=Parameter.PARTICIPANT_SCOPE).count() - self.failUnlessEqual(e.participants.count() * num_participant_parameters, ParticipantRoundDataValue.objects.filter(experiment=e).count(), + self.assertEqual(e.participants.count() * num_participant_parameters, ParticipantRoundDataValue.objects.filter(experiment=e).count(), 'There should be %s participants * %s total data parameters = %s' % (e.participants.count(), num_participant_parameters, e.participants.count() * num_participant_parameters)) def test_data_value_conversion(self): @@ -199,17 +207,17 @@ current_round_data = e.current_round_data for p in self.participants: participant_data_values = current_round_data.participant_data_values.filter(participant_group_relationship__participant=p) - self.failUnlessEqual(participant_data_values.count(), 1) + self.assertEqual(participant_data_values.count(), 1) pexpr = p.get_participant_experiment_relationship(e) logger.debug("relationship %s" % pexpr) for dv in participant_data_values.all(): logger.debug("verifying data value %s" % dv) - self.failUnlessEqual(pexpr.sequential_participant_identifier * 2, dv.value) - self.failUnless(dv.value) - self.failUnlessEqual(dv.int_value, pexpr.sequential_participant_identifier * 2) - self.failIf(dv.string_value) - self.failIf(dv.boolean_value) - self.failIf(dv.float_value) + self.assertEqual(pexpr.sequential_participant_identifier * 2, dv.value) + self.assertTrue(dv.value) + self.assertEqual(dv.int_value, pexpr.sequential_participant_identifier * 2) + self.assertFalse(dv.string_value) + self.assertFalse(dv.boolean_value) + self.assertFalse(dv.float_value) e.advance_to_next_round() current_round_data = e.current_round_data - self.failUnlessEqual(0, ParticipantRoundDataValue.objects.filter(round_data=current_round_data).count()) + self.assertEqual(0, ParticipantRoundDataValue.objects.filter(round_data=current_round_data).count()) diff -r 1a81a16fe890 -r 2ee0cd6dc43d vcweb/forestry/views.py --- a/vcweb/forestry/views.py Mon Apr 18 16:08:14 2011 -0700 +++ b/vcweb/forestry/views.py Tue Apr 19 12:51:39 2011 -0700 @@ -69,7 +69,6 @@ experiment = group.experiment participant_history = [] for round_data in experiment.playable_round_data: - logger.debug("Round %s" % round_data) data = ParticipantRoundData() data.round_configuration = round_data.round_configuration data.individual_harvest = get_harvest_decision(participant_group_relationship, round_data=round_data) @@ -89,7 +88,7 @@ participant_history.append(data) if experiment.is_round_in_progress: last_round_data = participant_history[-1] - if experiment.current_round.pk == last_round_data.round_configuration.pk: + if experiment.current_round == last_round_data.round_configuration: last_round_data.round_in_progress = True return participant_history @@ -207,7 +206,7 @@ resource_level = get_resource_level(participant.get_group(experiment)) max_harvest_decision = get_max_harvest_decision(resource_level.value) if resources_harvested <= max_harvest_decision: - set_harvest_decision(participant=participant, experiment=experiment, value=resources_harvested) + set_harvest_decision(participant_group_relationship=participant_group_relationship, value=resources_harvested) return redirect('forestry:wait', experiment_id=experiment.pk) else: raise forms.ValidationError("invalid harvest decision %s > max %s" % (harvest_decision, max_harvest_decision)) |
From: <vir...@li...> - 2011-04-18 23:07:42
|
Subject: hg.virtualcommons 347 details: http://virtualcommons.hg.sourceforge.net:8000/hgroot/virtualcommons/virtualcommons/hgrepo/v/vi/virtualcommons/virtualcommons/rev/1a81a16fe890 changeset: 347:1a81a16fe890 user: Allen Lee <all...@as...> date: Mon Apr 18 16:08:14 2011 -0700 description: adding collectstatic to fabric script and updating favicon/robots.txt diffstat: vcweb/fabfile.py | 6 +++++- vcweb/static/favicon.ico | vcweb/static/robots.txt | 4 ++++ vcweb/vcweb.apache.vhost | 4 +++- 4 files changed, 12 insertions(+), 2 deletions(-) diffs (41 lines): diff -r 8a96adf2c60b -r 1a81a16fe890 vcweb/fabfile.py --- a/vcweb/fabfile.py Mon Apr 18 15:51:59 2011 -0700 +++ b/vcweb/fabfile.py Mon Apr 18 16:08:14 2011 -0700 @@ -144,8 +144,12 @@ sudo('hg pull && hg up', user=env.deploy_user, pty=True) if confirm("syncdb?"): syncdb() + from vcweb import settings + env.static_root = settings.STATIC_ROOT + _virtualenv('%(python)s manage.py collectstatic' % env) sudo_chain('chmod -R ug+rw .', + 'find %(static_root)s -type d -exec chmod a+x {} \;' % env, 'find . -type d -exec chmod ug+x {} \;', - 'chown -R %(deploy_user)s:%(deploy_group)s .' % env, + 'chown -R %(deploy_user)s:%(deploy_group)s . %(static_root)s' % env, _restart_command(), pty=True) diff -r 8a96adf2c60b -r 1a81a16fe890 vcweb/static/favicon.ico Binary file vcweb/static/favicon.ico has changed diff -r 8a96adf2c60b -r 1a81a16fe890 vcweb/static/robots.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vcweb/static/robots.txt Mon Apr 18 16:08:14 2011 -0700 @@ -0,0 +1,4 @@ +User-Agent: * +Disallow: /experiment/ +Disallow: /forestry/ +Disallow: /accounts/ diff -r 8a96adf2c60b -r 1a81a16fe890 vcweb/vcweb.apache.vhost --- a/vcweb/vcweb.apache.vhost Mon Apr 18 15:51:59 2011 -0700 +++ b/vcweb/vcweb.apache.vhost Mon Apr 18 16:08:14 2011 -0700 @@ -4,7 +4,9 @@ DocumentRoot /var/www/vcweb ServerName vcweb.asu.edu - Alias /static "/var/www/vcweb/static" + Alias /static /var/www/vcweb/static + 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 |
From: <vir...@li...> - 2011-04-18 22:51:14
|
Subject: hg.virtualcommons 346 details: http://virtualcommons.hg.sourceforge.net:8000/hgroot/virtualcommons/virtualcommons/hgrepo/v/vi/virtualcommons/virtualcommons/rev/8a96adf2c60b changeset: 346:8a96adf2c60b user: Allen Lee <all...@as...> date: Mon Apr 18 15:51:59 2011 -0700 description: placing logfiles in logs directory and adding tooltips to experiment monitor for consistency. diffstat: .hgignore | 1 + vcweb/core/templates/experimenter/monitor.html | 2 +- vcweb/core/templates/participant/base.html | 7 ++- vcweb/core/templates/participant/dashboard.html | 35 ++++++----------- vcweb/settings.py | 10 ++++- vcweb/static/js/common.js | 16 +++++-- 6 files changed, 39 insertions(+), 32 deletions(-) diffs (167 lines): diff -r 12fa43dbafb1 -r 8a96adf2c60b .hgignore --- a/.hgignore Mon Apr 18 15:32:59 2011 -0700 +++ b/.hgignore Mon Apr 18 15:51:59 2011 -0700 @@ -9,3 +9,4 @@ *.log .idea build +logs diff -r 12fa43dbafb1 -r 8a96adf2c60b vcweb/core/templates/experimenter/monitor.html --- a/vcweb/core/templates/experimenter/monitor.html Mon Apr 18 15:32:59 2011 -0700 +++ b/vcweb/core/templates/experimenter/monitor.html Mon Apr 18 15:51:59 2011 -0700 @@ -69,7 +69,7 @@ addExperimentMessage(json.message); break; case 'chat': - addChatMessage('chat-div-' + json.round_data_pk, json, json.date_created + " " + json.participant); + addChatMessage('chat-div-' + json.round_data_pk, json, json.date_created + " " + json.participant, qtipOptions); break; case 'submit': $('#participant_data_value_' + json.participant_data_value_pk).html(json.message).effect("highlight", {}, 5000); diff -r 12fa43dbafb1 -r 8a96adf2c60b vcweb/core/templates/participant/base.html --- a/vcweb/core/templates/participant/base.html Mon Apr 18 15:32:59 2011 -0700 +++ b/vcweb/core/templates/participant/base.html Mon Apr 18 15:51:59 2011 -0700 @@ -7,15 +7,18 @@ {% include "includes/participant.events.html" %} {% include "includes/socket.io.html" %} <script type='text/javascript'> + var qtipOptions = {position: { corner: {target: 'topMiddle', tooltip: 'bottomMiddle'}}, style: { name: 'green', tip: 'bottomMiddle'} }; connect(window.location.hostname, 8888, 'participant/{{participant_experiment_relationship.pk}}'); + $(function() { + $('[title]').qtip(qtipOptions); + }); +</script> </script> {% endblock %} {% endblock %} - {% block title %} Virtual Commons Web Participant Interface {% endblock %} - {% block header %} {% include "includes/participant-nav-menu.html" %} {% endblock %} diff -r 12fa43dbafb1 -r 8a96adf2c60b vcweb/core/templates/participant/dashboard.html --- a/vcweb/core/templates/participant/dashboard.html Mon Apr 18 15:32:59 2011 -0700 +++ b/vcweb/core/templates/participant/dashboard.html Mon Apr 18 15:51:59 2011 -0700 @@ -1,38 +1,29 @@ {% extends "participant/base.html" %} - {% block participant_socket_io %} {% endblock %} {% block head %} {{block.super}} -<script type='text/javascript'> - $(function() { - $('[title]').qtip({position: { corner: {target: 'topMiddle', tooltip: 'bottomMiddle'}}, style: { name: 'green', tip: 'bottomMiddle'} }); - }); -</script> {% endblock %} - {% block title %} Virtual Commons Web Participant Dashboard {% endblock %} - {% block page %} <div class='info infoIcon ui-corner-all'> Welcome back, {{request.user.participant}}. Experiments you're participating in are listed below. </div> - <div id='experiments'> -{% for experiment_metadata, experiment_status_dict in experiments.items %} -<h3> {{ experiment_metadata.title }} </h3> -{% for experiment_status, experiments in experiment_status_dict.items %} -{% if experiments %} -<h4>{{experiments.0.get_status_display}}</h4> -{% for experiment in experiments %} -<div style='padding: 10px;' class='ui-state-highlight'> - <a title='This experiment is being run by {{experiment.experimenter}}' href='{{ experiment.participant_url }}'><span class='icon-left ui-icon {{experiment_status|lower}}'></span>{{ experiment.status_line }}, started {{experiment.current_round_start_time}}</a> -</div> -{% endfor %} -{% endif %} -{% endfor %} -{% endfor %} + {% for experiment_metadata, experiment_status_dict in experiments.items %} + <h3> {{ experiment_metadata.title }} </h3> + {% for experiment_status, experiments in experiment_status_dict.items %} + {% if experiments %} + <h4>{{experiments.0.get_status_display}}</h4> + {% for experiment in experiments %} + <div style='padding: 10px;' class='ui-state-highlight'> + <a title='This experiment is being run by {{experiment.experimenter}}' href='{{ experiment.participant_url }}'><span class='icon-left ui-icon {{experiment_status|lower}}'></span>{{ experiment.status_line }}, started {{experiment.current_round_start_time}}</a> + </div> + {% endfor %} + {% endif %} + {% endfor %} + {% endfor %} </div> {% endblock page %} diff -r 12fa43dbafb1 -r 8a96adf2c60b vcweb/settings.py --- a/vcweb/settings.py Mon Apr 18 15:32:59 2011 -0700 +++ b/vcweb/settings.py Mon Apr 18 15:51:59 2011 -0700 @@ -1,7 +1,13 @@ # Django settings for vcweb project. +import os from os import path import logging +LOG_DIRECTORY = 'logs' +try: + os.makedirs(LOG_DIRECTORY) +except OSError: + pass LOG_FILENAME = 'vcweb.log' TORNADIO_LOG_FILENAME = 'tornadio.log' LOGGING = { @@ -32,13 +38,13 @@ 'level': 'DEBUG', 'class':'logging.handlers.RotatingFileHandler', 'formatter': 'medium', - 'filename': LOG_FILENAME, + 'filename': path.join(LOG_DIRECTORY, LOG_FILENAME), }, 'tornadio-file': { 'level': 'DEBUG', 'class':'logging.handlers.RotatingFileHandler', 'formatter': 'medium', - 'filename': TORNADIO_LOG_FILENAME, + 'filename': path.join(LOG_DIRECTORY, TORNADIO_LOG_FILENAME), }, }, 'loggers': { diff -r 12fa43dbafb1 -r 8a96adf2c60b vcweb/static/js/common.js --- a/vcweb/static/js/common.js Mon Apr 18 15:32:59 2011 -0700 +++ b/vcweb/static/js/common.js Mon Apr 18 15:51:59 2011 -0700 @@ -1,5 +1,3 @@ -/* SlimConsoleDummy.min.js from https://github.com/andyet/ConsoleDummy.js */ -/*(function(b){function c(){}for(var d=["error","info","log","warn"],a;a=d.pop();)b[a]=b[a]||c})(window.console=window.console={});*/ if (!window.console) console = {}; console.log = console.log || function(){}; console.warn = console.warn || function(){}; @@ -8,14 +6,22 @@ function scrollToBottom(element) { element.scrollTop = element.scrollHeight; } -function addChatMessage(elementId, json, title) { +function addChatMessage(elementId, json, title, qtipOptions) { if (! title) { title = json.date_created; } + if (! qtipOptions) { + qtipOptions = {position: { corner: {target: 'topMiddle', tooltip: 'bottomMiddle'}}, style: { name: 'green', tip: 'bottomMiddle'} }; + } $('#' + elementId).append( $("<div class='ui-state-highlight' style='line-height: 1.5em;'/>") - .append($("<a class='dark-yellow-highlight' />").attr("name", json.pk).attr("title", title) - .text(json.date_created)) + .append( + $("<a class='dark-yellow-highlight' />") + .attr("name", json.pk) + .attr("title", title) + .text(json.date_created) + .qtip(qtipOptions) + ) .append(" | ") .append(json.message)); scrollToBottom(document.getElementById(elementId)); |