diff --git a/src/formconfig.py b/src/formconfig.py index 331c84c..251b3d8 100644 --- a/src/formconfig.py +++ b/src/formconfig.py @@ -14,9 +14,11 @@ class FormConfig: file. It holds information (title, users, the form definitions) on the form configuration being served by this instance of ScriptForm. """ - def __init__(self, title, forms, users={}, static_dir=None, custom_css=None): + def __init__(self, title, forms, users=None, static_dir=None, custom_css=None): self.title = title - self.users = users + self.users = {} + if users is not None: + self.users = users self.forms = forms self.static_dir = static_dir self.custom_css = custom_css diff --git a/src/formdefinition.py b/src/formdefinition.py index 61b63ff..c1ceaed 100644 --- a/src/formdefinition.py +++ b/src/formdefinition.py @@ -88,54 +88,54 @@ class FormDefinition: def validate_integer(self, field_def, form_values): value = form_values[field_def['name']] - _max = field_def.get('max', None) - _min = field_def.get('min', None) + maxval = field_def.get('max', None) + minval = field_def.get('min', None) try: value = int(value) except ValueError: raise ValidationError("Must be an integer number") - if _min is not None and value < int(_min): - raise ValidationError("Minimum value is {0}".format(_min)) - if _max is not None and value > int(_max): - raise ValidationError("Maximum value is {0}".format(_max)) + if minval is not None and value < int(minval): + raise ValidationError("Minimum value is {0}".format(minval)) + if maxval is not None and value > int(maxval): + raise ValidationError("Maximum value is {0}".format(maxval)) return int(value) def validate_float(self, field_def, form_values): value = form_values[field_def['name']] - _max = field_def.get('max', None) - _min = field_def.get('min', None) + maxval = field_def.get('max', None) + minval = field_def.get('min', None) try: value = float(value) except ValueError: raise ValidationError("Must be an real (float) number") - if _min is not None and value < float(_min): - raise ValidationError("Minimum value is {0}".format(_min)) - if _max is not None and value > float(_max): - raise ValidationError("Maximum value is {0}".format(_max)) + if minval is not None and value < float(minval): + raise ValidationError("Minimum value is {0}".format(minval)) + if maxval is not None and value > float(maxval): + raise ValidationError("Maximum value is {0}".format(maxval)) return float(value) def validate_date(self, field_def, form_values): value = form_values[field_def['name']] - _max = field_def.get('max', None) - _min = field_def.get('min', None) + maxval = field_def.get('max', None) + minval = field_def.get('min', None) try: value = datetime.datetime.strptime(value, '%Y-%m-%d').date() except ValueError: raise ValidationError("Invalid date, must be in form YYYY-MM-DD") - if _min is not None: - if value < datetime.datetime.strptime(_min, '%Y-%m-%d').date(): - raise ValidationError("Minimum value is {0}".format(_min)) - if _max is not None: - if value > datetime.datetime.strptime(_max, '%Y-%m-%d').date(): - raise ValidationError("Maximum value is {0}".format(_max)) + if minval is not None: + if value < datetime.datetime.strptime(minval, '%Y-%m-%d').date(): + raise ValidationError("Minimum value is {0}".format(minval)) + if maxval is not None: + if value > datetime.datetime.strptime(maxval, '%Y-%m-%d').date(): + raise ValidationError("Maximum value is {0}".format(maxval)) return value diff --git a/src/formrender.py b/src/formrender.py index 67b9c60..60cc8b9 100644 --- a/src/formrender.py +++ b/src/formrender.py @@ -1,13 +1,13 @@ html_field = u'''
  • {title}

    -

    {input} {errors}

    +

    {h_input} {errors}

  • ''' html_field_checkbox = u'''
  • -

    {input}

    {title}

    {errors}

    +

    {h_input}

    {title}

    {errors}

  • ''' @@ -15,12 +15,12 @@ html_field_checkbox = u''' class FormRender(): field_tpl = { "string": u'', - "number": u'', - "integer": u'', - "float": u'', + "number": u'', + "integer": u'', + "float": u'', "date": u'', "file": u'', - "password": u'', + "password": u'', "text": u'', "radio_option": u'{label}
    ', "select_option": u'', @@ -51,45 +51,63 @@ class FormRender(): return new_params - def r_field(self, type, **kwargs): + def r_field(self, field_type, **kwargs): params = self.cast_params(kwargs) - method_name = 'r_field_{0}'.format(type) + method_name = 'r_field_{0}'.format(field_type) method = getattr(self, method_name, None) return method(**params) - def r_field_string(self, name, value, size=50, required=False, classes=[], style=""): + def r_field_string(self, name, value, size=50, required=False, classes=None, style=""): + if classes is None: + classes = [] tpl = self.field_tpl['string'] return tpl.format(name=name, value=value, size=size, required=required, classes=classes, style=style) - def r_field_number(self, name, value, min=None, max=None, required=False, classes=[], style=""): + def r_field_number(self, name, value, minval=None, maxval=None, required=False, classes=None, style=""): + if classes is None: + classes = [] tpl = self.field_tpl['number'] - return tpl.format(name=name, value=value, min=min, max=max, required=required, classes=classes, style=style) + return tpl.format(name=name, value=value, minval=minval, maxval=maxval, required=required, classes=classes, style=style) - def r_field_integer(self, name, value, min=None, max=None, required=False, classes=[], style=""): + def r_field_integer(self, name, value, minval=None, maxval=None, required=False, classes=None, style=""): + if classes is None: + classes = [] tpl = self.field_tpl['integer'] - return tpl.format(name=name, value=value, min=min, max=max, required=required, classes=classes, style=style) + return tpl.format(name=name, value=value, minval=minval, maxval=maxval, required=required, classes=classes, style=style) - def r_field_float(self, name, value, min=None, max=None, required=False, classes=[], style=""): + def r_field_float(self, name, value, minval=None, maxval=None, required=False, classes=None, style=""): + if classes is None: + classes = [] tpl = self.field_tpl['integer'] - return tpl.format(name=name, value=value, min=min, max=max, required=required, classes=classes, style=style) + return tpl.format(name=name, value=value, minval=minval, maxval=maxval, required=required, classes=classes, style=style) - def r_field_date(self, name, value, required=False, classes=[], style=""): + def r_field_date(self, name, value, required=False, classes=None, style=""): + if classes is None: + classes = [] tpl = self.field_tpl['date'] return tpl.format(name=name, value=value, required=required, classes=classes, style=style) - def r_field_file(self, name, required=False, classes=[], style=""): + def r_field_file(self, name, required=False, classes=None, style=""): + if classes is None: + classes = [] tpl = self.field_tpl['file'] return tpl.format(name=name, required=required, classes=classes, style=style) - def r_field_password(self, name, value, min=None, required=False, classes=[], style=""): + def r_field_password(self, name, value, minval=None, required=False, classes=None, style=""): + if classes is None: + classes = [] tpl = self.field_tpl['password'] - return tpl.format(name=name, value=value, min=min, required=required, classes=classes, style=style) + return tpl.format(name=name, value=value, minval=minval, required=required, classes=classes, style=style) - def r_field_text(self, name, value, rows=4, cols=80, required=False, classes=[], style=""): + def r_field_text(self, name, value, rows=4, cols=80, required=False, classes=None, style=""): + if classes is None: + classes = [] tpl = self.field_tpl['text'] return tpl.format(name=name, value=value, rows=rows, cols=cols, required=required, classes=classes, style=style) - def r_field_radio(self, name, value, options, classes=[], style=""): + def r_field_radio(self, name, value, options, classes=None, style=""): + if classes is None: + classes = [] tpl_option = self.field_tpl['radio_option'] radio_elems = [] for o_value, o_label in options: @@ -100,10 +118,14 @@ class FormRender(): return u''.join(radio_elems) def r_field_checkbox(self, name, checked, classes='', style=""): + if classes is None: + classes = [] tpl = self.field_tpl['checkbox'] return tpl.format(name=name, checked=checked, classes=classes, style=style) - def r_field_select(self, name, value, options, classes=[], style=""): + def r_field_select(self, name, value, options, classes=None, style=""): + if classes is None: + classes = [] tpl_option = self.field_tpl['select_option'] select_elems = [] for o_value, o_label in options: @@ -115,13 +137,13 @@ class FormRender(): tpl = self.field_tpl['select'] return tpl.format(name=name, select_elems=''.join(select_elems), classes=classes, style=style) - def r_form_line(self, type, title, input, classes, errors): - if type == 'checkbox': + def r_form_line(self, field_type, title, h_input, classes, errors): + if field_type == 'checkbox': html = html_field_checkbox else: html = html_field return (html.format(classes=' '.join(classes), title=title, - input=input, + h_input=h_input, errors=u', '.join(errors))) diff --git a/src/webapp.py b/src/webapp.py index 1e6f661..ad11ce9 100644 --- a/src/webapp.py +++ b/src/webapp.py @@ -146,10 +146,11 @@ class WebAppHandler(BaseHTTPRequestHandler): requests. If no path is set, it dispatches to the 'index' or 'default' method. """ - def log_message(self, format, *args): + def log_message(self, fmt, *args): """Overrides BaseHTTPRequestHandler which logs to the console. We log to our log file instead""" - self.scriptform.log.info("{} {}".format(self.address_string(), args)) + fmt = "{} {}" + self.scriptform.log.info(fmt.format(self.address_string(), args)) def do_GET(self): self._call(*self._parse(self.path)) @@ -167,8 +168,8 @@ class WebAppHandler(BaseHTTPRequestHandler): qs = urlparse.parse_qs(url_comp.query) # Only return the first value of each query var. E.g. for # "?foo=1&foo=2" return '1'. - vars = dict([(k, v[0]) for k, v in qs.items()]) - return (path.strip('/'), vars) + var_values = dict([(k, v[0]) for k, v in qs.items()]) + return (path.strip('/'), var_values) def _call(self, path, params): """ @@ -236,7 +237,7 @@ class ScriptFormWebApp(WebAppHandler): authorized = False auth_header = self.headers.getheader("Authorization") if auth_header is not None: - auth_realm, auth_unpw = auth_header.split(' ', 1) + auth_unpw = auth_header.split(' ', 1)[1] username, password = base64.decodestring(auth_unpw).split(":") pw_hash = hashlib.sha256(password).hexdigest() # Validate the username and password @@ -287,10 +288,12 @@ class ScriptFormWebApp(WebAppHandler): self.end_headers() self.wfile.write(output.encode('utf8')) - def h_form(self, form_name, errors={}, **form_values): + def h_form(self, form_name, errors=None, **form_values): """ Render a form. """ + if errors is None: + errors = {} if not self.auth(): return @@ -318,10 +321,10 @@ class ScriptFormWebApp(WebAppHandler): params['size'] = field.get('size', '') if field['type'] in ('number', 'integer', 'float', 'password'): - params['min'] = field.get("min", '') + params['minval'] = field.get("min", '') if field['type'] in ('number', 'integer', 'float'): - params['max'] = field.get("max", '') + params['maxval'] = field.get("max", '') if field['type'] in ('text'): params['rows'] = field.get("rows", '') @@ -340,10 +343,10 @@ class ScriptFormWebApp(WebAppHandler): if field['name'] in form_values and form_values[field['name']] == 'on': params['checked'] = True - input = fr.r_field(field['type'], **params) + h_input = fr.r_field(field['type'], **params) return fr.r_form_line(field['type'], field['title'], - input, params['classes'], errors) + h_input, params['classes'], errors) # Make sure the user is allowed to access this form. form_def = form_config.get_form_def(form_name)