Browse Source

WEBUI: HTML5 datetime for all timeforms

refs #35
boyska 7 years ago
parent
commit
3718649cd3
4 changed files with 136 additions and 139 deletions
  1. 132 0
      larigira/timeform_base.py
  2. 0 75
      larigira/timeform_frequency.py
  3. 0 60
      larigira/timeform_single.py
  4. 4 4
      setup.py

+ 132 - 0
larigira/timeform_base.py

@@ -0,0 +1,132 @@
+from datetime import datetime
+from pytimeparse.timeparse import timeparse
+
+from flask_wtf import Form
+from wtforms import StringField, Field, validators, SubmitField, \
+        SelectMultipleField, ValidationError
+import wtforms.widgets
+
+
+class DateTimeInput(wtforms.widgets.Input):
+    input_type = 'datetime-local'
+
+
+class EasyDateTimeField(Field):
+    '''
+    a "fork" of DateTimeField which uses HTML5 datetime-local
+    The format is not customizable, because it is imposed by the HTML5 specification
+    '''
+    widget = DateTimeInput()
+
+    def __init__(self, label=None, validators=None, **kwargs):
+        super(EasyDateTimeField, self).__init__(label, validators, **kwargs)
+        self.format = '%Y-%m-%dT%H:%M:%S'
+
+    def _value(self):
+        if self.raw_data:
+            return ' '.join(self.raw_data)
+        else:
+            return self.data and self.data.strftime(self.format) or ''
+
+    def process_formdata(self, valuelist):
+        if valuelist:
+            date_str = ' '.join(valuelist)
+            try:
+                self.data = datetime.strptime(date_str, self.format)
+            except ValueError:
+                self.data = None
+                raise ValueError(self.gettext(
+                    'Not a valid datetime value <tt>{}</tt>').format(date_str))
+
+
+class SingleAlarmForm(Form):
+    nick = StringField('Alarm nick', validators=[validators.required()],
+                       description='A simple name to recognize this alarm')
+    dt = EasyDateTimeField('Date and time', validators=[validators.required()],
+                           description='Date to ring on, expressed as '
+                           '2000-12-31T13:42:00')
+    submit = SubmitField('Submit')
+
+    def populate_from_timespec(self, timespec):
+        if 'nick' in timespec:
+            self.nick.data = timespec['nick']
+        if 'timestamp' in timespec:
+            self.dt.data = datetime.fromtimestamp(timespec['timestamp'])
+
+
+def singlealarm_receive(form):
+    return {
+        'kind': 'single',
+        'nick': form.nick.data,
+        'timestamp': int(form.dt.data.strftime('%s'))
+    }
+
+
+class FrequencyAlarmForm(Form):
+    nick = StringField('Alarm nick', validators=[validators.required()],
+                       description='A simple name to recognize this alarm')
+    interval = StringField('Frequency',
+                           validators=[validators.required()],
+                           description='in seconds, or human-readable '
+                           '(like 9w3d12h)')
+    start = EasyDateTimeField('Start date and time',
+                              validators=[validators.optional()],
+                              description='Before this, no alarm will ring. '
+                              'Expressed as YYYY-MM-DDTHH:MM:SS. If omitted, '
+                              'the alarm will always ring')
+    end = EasyDateTimeField('End date and time',
+                            validators=[validators.optional()],
+                            description='After this, no alarm will ring. '
+                            'Expressed as YYYY-MM-DDTHH:MM:SS. If omitted, '
+                            'the alarm will always ring')
+    weekdays = SelectMultipleField('Days on which the alarm should be played',
+                                   choices=[('1', 'Monday'),
+                                            ('2', 'Tuesday'),
+                                            ('3', 'Wednesday'),
+                                            ('4', 'Thursday'),
+                                            ('5', 'Friday'),
+                                            ('6', 'Saturday'),
+                                            ('7', 'Sunday')],
+                                   default=list('1234567'),
+                                   validators=[validators.required()],
+                                   description='The alarm will ring only on '
+                                   'selected weekdays')
+    submit = SubmitField('Submit')
+
+    def populate_from_timespec(self, timespec):
+        if 'nick' in timespec:
+            self.nick.data = timespec['nick']
+        if 'start' in timespec:
+            self.start.data = datetime.fromtimestamp(timespec['start'])
+        if 'end' in timespec:
+            self.end.data = datetime.fromtimestamp(timespec['end'])
+        if 'weekdays' in timespec:
+            self.weekdays.data = timespec['weekdays']
+        else:
+            self.weekdays.data = list('1234567')
+        self.interval.data = timespec['interval']
+
+    def validate_interval(form, field):
+        try:
+            int(field.data)
+        except ValueError:
+            if timeparse(field.data) is None:
+                raise ValidationError("interval must either be a number "
+                                      "(in seconds) or a human-readable "
+                                      "string like '1h2m'  or '1d12h'")
+
+
+def frequencyalarm_receive(form):
+    obj = {
+        'kind': 'frequency',
+        'nick': form.nick.data,
+        'interval': form.interval.data,
+        'weekdays': form.weekdays.data,
+    }
+    if form.start.data:
+        obj['start'] = int(form.start.data.strftime('%s'))
+    else:
+        obj['start'] = 0
+    if form.end.data:
+        obj['end'] = int(form.end.data.strftime('%s'))
+    return obj

+ 0 - 75
larigira/timeform_frequency.py

@@ -1,75 +0,0 @@
-from datetime import datetime
-from pytimeparse.timeparse import timeparse
-from flask_wtf import Form
-from wtforms import StringField, DateTimeField, validators, \
-        SubmitField, ValidationError, SelectMultipleField
-
-
-class FrequencyAlarmForm(Form):
-    nick = StringField('Alarm nick', validators=[validators.required()],
-                       description='A simple name to recognize this alarm')
-    interval = StringField('Frequency',
-                           validators=[validators.required()],
-                           description='in seconds, or human-readable '
-                           '(like 9w3d12h)')
-    start = DateTimeField('Start date and time',
-                          validators=[validators.optional()],
-                          description='Date before which no alarm will ring, '
-                          'expressed as YYYY-MM-DD HH:MM:SS; if omitted, the '
-                          'alarm will always ring')
-    end = DateTimeField('End date and time',
-                        validators=[validators.optional()],
-                        description='Date after which no alarm will ring, '
-                        'expressed as YYYY-MM-DD HH:MM:SS; if omitted, the '
-                        'alarm will always ring')
-    weekdays = SelectMultipleField('Days on which the alarm should be played',
-                                   choices=[('1', 'Monday'),
-                                            ('2', 'Tuesday'),
-                                            ('3', 'Wednesday'),
-                                            ('4', 'Thursday'),
-                                            ('5', 'Friday'),
-                                            ('6', 'Saturday'),
-                                            ('7', 'Sunday')],
-                                   default=list('1234567'),
-                                   validators=[validators.required()],
-                                   description='The alarm will ring only on '
-                                   'selected weekdays')
-    submit = SubmitField('Submit')
-
-    def populate_from_timespec(self, timespec):
-        if 'nick' in timespec:
-            self.nick.data = timespec['nick']
-        if 'start' in timespec:
-            self.start.data = datetime.fromtimestamp(timespec['start'])
-        if 'end' in timespec:
-            self.end.data = datetime.fromtimestamp(timespec['end'])
-        if 'weekdays' in timespec:
-            self.weekdays.data = timespec['weekdays']
-        else:
-            self.weekdays.data = list('1234567')
-        self.interval.data = timespec['interval']
-
-    def validate_interval(form, field):
-        try:
-            int(field.data)
-        except ValueError:
-            if timeparse(field.data) is None:
-                raise ValidationError("interval must either be a number "
-                                      "(in seconds) or a human-readable "
-                                      "string like '1h2m'  or '1d12h'")
-
-
-def frequencyalarm_receive(form):
-    obj = {
-        'kind': 'frequency',
-        'nick': form.nick.data,
-        'interval': form.interval.data,
-        'weekdays': form.weekdays.data,
-    }
-    if form.start.data:
-        obj['start'] = int(form.start.data.strftime('%s'))
-    else:
-        obj['start'] = 0
-    if form.end.data:
-        obj['end'] = int(form.end.data.strftime('%s'))
-    return obj

+ 0 - 60
larigira/timeform_single.py

@@ -1,60 +0,0 @@
-from datetime import datetime
-
-from flask_wtf import Form
-from wtforms import StringField, Field, validators, SubmitField
-import wtforms.widgets
-
-
-class DateTimeInput(wtforms.widgets.Input):
-    input_type = 'datetime-local'
-
-
-class EasyDateTimeField(Field):
-    '''
-    a "fork" of DateTimeField which uses HTML5 datetime-local
-    The format is not customizable, because it is imposed by the HTML5 specification
-    '''
-    widget = DateTimeInput()
-
-    def __init__(self, label=None, validators=None, **kwargs):
-        super(EasyDateTimeField, self).__init__(label, validators, **kwargs)
-        self.format = '%Y-%m-%dT%H:%M:%S'
-
-    def _value(self):
-        if self.raw_data:
-            return ' '.join(self.raw_data)
-        else:
-            return self.data and self.data.strftime(self.format) or ''
-
-    def process_formdata(self, valuelist):
-        if valuelist:
-            date_str = ' '.join(valuelist)
-            try:
-                self.data = datetime.strptime(date_str, self.format)
-            except ValueError:
-                self.data = None
-                raise ValueError(self.gettext('Not a valid datetime value <tt>{}</tt>').format(date_str))
-
-
-
-class SingleAlarmForm(Form):
-    nick = StringField('Alarm nick', validators=[validators.required()],
-                       description='A simple name to recognize this alarm')
-    dt = EasyDateTimeField('Date and time', validators=[validators.required()],
-                       description='Date to ring on, expressed as '
-                       '2000-12-31T13:42:00')
-    submit = SubmitField('Submit')
-
-    def populate_from_timespec(self, timespec):
-        if 'nick' in timespec:
-            self.nick.data = timespec['nick']
-        if 'timestamp' in timespec:
-            self.dt.data = datetime.fromtimestamp(timespec['timestamp'])
-
-
-def singlealarm_receive(form):
-    return {
-        'kind': 'single',
-        'nick': form.nick.data,
-        'timestamp': int(form.dt.data.strftime('%s'))
-    }

+ 4 - 4
setup.py

@@ -68,12 +68,12 @@ setup(name='larigira',
               'single = larigira.timegen_every:SingleAlarm',
           ],
           'larigira.timeform_create': [
-              'single = larigira.timeform_single:SingleAlarmForm',
-              'frequency = larigira.timeform_frequency:FrequencyAlarmForm',
+              'single = larigira.timeform_base:SingleAlarmForm',
+              'frequency = larigira.timeform_base:FrequencyAlarmForm',
           ],
           'larigira.timeform_receive': [
-              'single = larigira.timeform_single:singlealarm_receive',
-              'frequency = larigira.timeform_frequency:frequencyalarm_receive',
+              'single = larigira.timeform_base:singlealarm_receive',
+              'frequency = larigira.timeform_base:frequencyalarm_receive',
           ],
           'larigira.audioform_create': [
               'static = larigira.audioform_static:StaticAudioForm',