def clean_key(self):
     """
     Checks if the key is in settings. Used to avoid abuse of the
     form by enabling disabled form fields via firebug or similiar.
     """
     key = self.cleaned_data['key']
     try:
         settings.__getattr__(key)
     except AttributeError:
         raise forms.ValidationError(_("This key does not exists in the original settings."))
     return key
 def test_index_view_staff(self):
     logged_in = self.client.login(username=self.staff['username'], password=self.staff['password'])
     self.assertTrue(logged_in)
     response = self.client.get('/')
     self.assertEqual(response.status_code, 200)
     self.assertTrue('dynamic_settings' in response.context)
     self.assertTrue('STATIC_URL' in response.context)
     self.assertTrue('settings_form_rendered' in response.context)
     #check against a couple random settings which should be present
     for setting_dict in response.context['dynamic_settings']:
         self.assertEqual(setting_dict['type'], type(dynamic_settings.__getattr__(setting_dict['key'])).__name__, msg=setting_dict['key'])
         self.assertEqual(setting_dict['in_db'], False, msg=setting_dict['key']) #should be False at this moment
         self.assertEqual(setting_dict['can_change'], dynamic_settings.can_change(setting_dict['key']), msg=setting_dict['key'])
     self.client.logout()
def dynamicsettings_set(request):
    """A view to handle the POST request to 
    set a setting in the database
    
    Params:
        - ``request``: a django http request object
        
    Returns:
        - a response as JSON including the following fields:
            - ``status``: "success" if the setting was saved in
               the database, "error" in other cases
            - on success:
                - ``value``: the new value of the setting (which is
                  saved in the database)
                - ``type``: the new type of the setting, can only differ
                   from the original type if it was ``NoneType``
            - on error:
                - ``message``: the message describing the error
                - ``form``: the validated form rendered in a template
                  (will show the error in the form)
    """
    if request.method=='POST':
        response_dict = {}
        settings_form = forms.SettingsForm(request.POST)
        if settings_form.is_valid():
            form_data = settings_form.cleaned_data
            changed = settings.set(form_data['key'], form_data['value'], form_data['type'])
            if changed is True:
                value = settings.__getattr__(form_data['key'])
                if isinstance(value, (list, tuple, dict)):
                    value = simplejson.dumps(value, indent=4)
                response_dict.update({
                    'status': 'success',
                    'value': value,
                    'type': form_data['type'],
                })
        else:
            form_dict = {'settings_form': settings_form}
            form_dict.update(csrf_processor(request))
            settings_form_rendered = template.loader.render_to_string('dynamicsettings/settings_form.html', form_dict)
            response_dict.update({
                'status': 'error',
                'message': settings_form.errors['__all__'],
                'form': settings_form_rendered
            })
        return http.HttpResponse(simplejson.dumps(response_dict, indent=4), mimetype="text/plain")
    return http.HttpResponseNotAllowed(['GET', 'PUT', 'DELETE', 'HEAD', 'TRACE', 'OPTIONS', 'CONNECT', 'PATCH'])
def dynamicsettings_reset(request):
    """A view to handle the POST request to 
    reset a setting in the database
    
    Params:
        - ``request``: a django http request object
        
    Returns:
        - a response as JSON including the following fields:
            - ``status``: "success" if the setting was reset in
               the database, "error" in other cases
            - on success:
                - ``value``: the original value of the setting (which is
                  not saved in the database)
                - ``type``: the original type of the setting
            - on error:
                - ``message``: the message describing the error
    """
    if request.method=='POST':
        key = request.POST.get('key', None)
        if key is None:
            response_dict = {
                'status': 'error',
                'message': _('No variable "key" in POST request.'),
            }
        else:
            reset_success = settings.reset(key)
            if reset_success is True:
                value = settings.__getattr__(key)
                if isinstance(value, (list, tuple, dict)):
                    value = simplejson.dumps(value, indent=4)
                response_dict = {
                    'status': 'success',
                    'value': value,
                    'type': type(settings.get(key)).__name__,
                }
            else:
                response_dict = {
                    'status': 'error',
                    'message': _('The setting "%s" is not saved in the database or can not be reseted.' % request.POST['key']),
                }
        return http.HttpResponse(simplejson.dumps(response_dict, indent=4), mimetype="text/plain")
    return http.HttpResponseNotAllowed(['GET', 'PUT', 'DELETE', 'HEAD', 'TRACE', 'OPTIONS', 'CONNECT', 'PATCH'])
 def clean(self):
     """
     a) Check if the setting was originally from the submitted type.
     Used to avoid abuse of the form by enabling disabled form 
     fields via firebug or similiar.
     b) Try to convert the value according to submitted type.
     Raises ValidiationError when type and value are not fitting
     each other (eg. value can;t be converted to type).
     c) check if the resulting value was actually changed  (and
     not yet in the database)
     """
     error_message_tmpl = 'A setting from type %s must be set to %s.'
     key = self.cleaned_data['key']
     value = self.cleaned_data['value']
     value_type = self.cleaned_data['type']
     if settings.can_change(key) is False:
         raise forms.ValidationError(_("This setting can not be changed."))
     #a)
     original_type = type(settings.__getattr__(key)).__name__
     if original_type!='NoneType' and value_type!=original_type:
         raise forms.ValidationError(_("You can not change the type of a setting which was not NoneType before."))
     #b)
     if value_type == 'NoneType':
         if value!='None':
             raise forms.ValidationError(_(error_message_tmpl % ('NoneType', '"None"')))
         self.cleaned_data['value'] = None
     elif value_type == 'bool':
         if value!='True' and value!='False':
             raise forms.ValidationError(_(error_message_tmpl % ('bool', '"True" or "False"')))
         if value!='True':
             self.cleaned_data['value'] = True
         elif value!='False':
             self.cleaned_data['value'] = False
     elif value_type == 'int':
         try:
             self.cleaned_data['value'] = int(value)
         except ValueError:
             raise forms.ValidationError(_(error_message_tmpl % ('int or long', 'a number')))
     elif value_type == 'int':
         try:
             self.cleaned_data['value'] = float(value)
         except ValueError:
             raise forms.ValidationError(_(error_message_tmpl % ('float', 'a number')))
     elif value_type == 'str':
         self.cleaned_data['value'] = value
     elif value_type == 'unicode':
         self.cleaned_data['value'] = unicode(value)
     elif value_type in ['tuple', 'list', 'dict']:
         try:
             self.cleaned_data['value'] = value = simplejson.loads(value)
         except ValueError:
             raise forms.ValidationError(_(error_message_tmpl % ('tuple, list or dict', 'a valid JSON string')))
         if value_type == 'tuple' and type(value).__name__!='tuple':
             try:
                 if type(value).__name__ == 'dict':
                     raise TypeError
                 self.cleaned_data['value'] = tuple(value)
             except (ValueError, TypeError):
                 raise forms.ValidationError(_(error_message_tmpl % ('tuple', 'a valid JSON string representing an Array (leading "["and traling "]")')))
         elif value_type == 'list' and type(value).__name__!='list':
             try:
                 if type(value).__name__ == 'dict':
                     raise TypeError
                 self.cleaned_data['value'] = list(value)
             except (ValueError, TypeError):
                 raise forms.ValidationError(_(error_message_tmpl % ('list', 'a valid JSON string representing an Array (leading "["and traling "]")')))
         elif value_type == 'dict' and type(value).__name__!='dict':
             try:
                 if type(value).__name__ == 'list':
                     raise TypeError
                 self.cleaned_data['value'] = dict(value)
             except (ValueError, TypeError):
                 raise forms.ValidationError(_(error_message_tmpl % ('dict', 'a valid JSON string representing an Object (leading "{"and traling "}")')))
     #c)
     value = self.cleaned_data['value']
     if not settings.is_in_db(key) and value==settings.__getattr__(key):
         raise forms.ValidationError(_('To save a setting in the database the value must have been changed from its original value.'))
     
     return self.cleaned_data