示例#1
0
    def validate(self):

        config_schema = schema.Schema({
            'name': str,
            'app_sequence': list,
            'participation_fee': object,
            'real_world_currency_per_point': object,
            'num_demo_participants': int,
            'doc': str,
            object: object,
        })

        try:
            config_schema.validate(self)
        except schema.SchemaError as e:
            raise ValueError('settings.SESSION_CONFIGS: {}'.format(e))

        validate_identifier(
            self['name'],
            identifier_description='settings.SESSION_CONFIG name'
        )

        app_sequence = self['app_sequence']
        if len(app_sequence) != len(set(app_sequence)):
            msg = (
                'settings.SESSION_CONFIGS: '
                'app_sequence of "{}" '
                'must not contain duplicate elements. '
                'If you want multiple rounds, '
                'you should set Constants.num_rounds.')
            raise ValueError(msg.format(self['name']))

        if len(app_sequence) == 0:
            raise ValueError(
                'settings.SESSION_CONFIGS: Need at least one subsession.')

        self.setdefault('display_name', self['name'])
        self.setdefault('doc', '')

        # TODO: fixed_pay is deprecated as of 2015-05-07,
        # in favor of participation_fee. make this required at some point.
        if (('participation_fee' not in self) and
                ('fixed_pay' in self)):
            warn_msg = (
                "'fixed_pay' is deprecated; "
                "you should rename it to 'participation_fee'.")
            warnings.warn(warn_msg, OtreeDeprecationWarning)

            self['participation_fee'] = self['fixed_pay']

        self['participation_fee'] = RealWorldCurrency(
            self['participation_fee'])

        # normalize to decimal so we can do multiplications, etc
        # quantize because the original value may be a float,
        # which when converted to Decimal may have some 'decimal junk'
        # like 0.010000000000000000208166817...
        self['real_world_currency_per_point'] = Decimal(
            self['real_world_currency_per_point']
        ).quantize(Decimal('0.00001'))
示例#2
0
 def load_participant_labels_to_db(self):
     if self.has_participant_labels():
         encodings = ['ascii', 'utf-8', 'utf-16']
         for e in encodings:
             try:
                 plabel_path = self.participant_label_file
                 with codecs.open(plabel_path, "r", encoding=e) as f:
                     seen = set()
                     labels = []
                     for line in f:
                         label = line.strip()
                         if not label:
                             continue
                         label = validate_identifier(
                             line.strip(),
                             identifier_description='participant label'
                         )
                         if label not in seen:
                             labels.append(label)
                             seen.add(label)
             except UnicodeDecodeError:
                 continue
             except OSError as err:
                 # this code is equivalent to "except FileNotFoundError:"
                 # but works in py2 and py3
                 if err.errno == errno.ENOENT:
                     msg = (
                         'settings.ROOMS: The room "{}" references '
                         ' nonexistent participant_label_file "{}".'
                     )
                     raise IOError(
                         msg.format(self.name, self.participant_label_file))
                 raise err
             else:
                 with global_lock():
                     # before I used select_for_update to prevent race
                     # conditions. But the queryset was not evaluated
                     # so it did not hit the DB. maybe simpler to use an
                     # explicit lock
                     ExpectedRoomParticipant.objects.select_for_update()
                     ExpectedRoomParticipant.objects.filter(
                         room_name=self.name).delete()
                     ExpectedRoomParticipant.objects.bulk_create(
                         ExpectedRoomParticipant(
                             room_name=self.name,
                             participant_label=participant_label
                         ) for participant_label in labels
                     )
                 self._participant_labels_loaded = True
                 return
         raise Exception(
             'settings.ROOMS: participant_label_file "{}" '
             'not encoded correctly.'.format(self.participant_label_file)
         )
     raise Exception('no guestlist')
示例#3
0
    def __init__(self, config_dict):
        self.participant_label_file = config_dict.get('participant_label_file')

        self.name = validate_identifier(
            config_dict['name'],
            identifier_description='settings.ROOMS room name')
        self.display_name = config_dict['display_name']
        # secure URLs are complicated, don't use them by default
        self.use_secure_urls = config_dict['use_secure_urls']
        self.pin_code = config_dict.get('pin_code')
        self._participant_labels_loaded = False
        if self.use_secure_urls and not self.participant_label_file:
            raise ValueError(
                'Room "{}": you must either set "participant_label_file", '
                'or set "use_secure_urls": False'.format(self.name)
            )