parent
9c84669749
commit
3718649cd3
4 changed files with 136 additions and 139 deletions
132
larigira/timeform_base.py
Normal file
132
larigira/timeform_base.py
Normal file
|
@ -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
|
|
@ -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
|
|
|
@ -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'))
|
|
||||||
}
|
|
8
setup.py
8
setup.py
|
@ -68,12 +68,12 @@ setup(name='larigira',
|
||||||
'single = larigira.timegen_every:SingleAlarm',
|
'single = larigira.timegen_every:SingleAlarm',
|
||||||
],
|
],
|
||||||
'larigira.timeform_create': [
|
'larigira.timeform_create': [
|
||||||
'single = larigira.timeform_single:SingleAlarmForm',
|
'single = larigira.timeform_base:SingleAlarmForm',
|
||||||
'frequency = larigira.timeform_frequency:FrequencyAlarmForm',
|
'frequency = larigira.timeform_base:FrequencyAlarmForm',
|
||||||
],
|
],
|
||||||
'larigira.timeform_receive': [
|
'larigira.timeform_receive': [
|
||||||
'single = larigira.timeform_single:singlealarm_receive',
|
'single = larigira.timeform_base:singlealarm_receive',
|
||||||
'frequency = larigira.timeform_frequency:frequencyalarm_receive',
|
'frequency = larigira.timeform_base:frequencyalarm_receive',
|
||||||
],
|
],
|
||||||
'larigira.audioform_create': [
|
'larigira.audioform_create': [
|
||||||
'static = larigira.audioform_static:StaticAudioForm',
|
'static = larigira.audioform_static:StaticAudioForm',
|
||||||
|
|
Loading…
Reference in a new issue