calendar-social/calsocial/forms.py

90 lines
2.9 KiB
Python

from flask_babelex import lazy_gettext as _
from flask_wtf import FlaskForm
import pytz
from wtforms import BooleanField, PasswordField, SelectField, StringField
from wtforms.ext.dateutil.fields import DateTimeField
from wtforms.validators import DataRequired, Email, ValidationError
from wtforms.widgets import TextArea
class RegistrationForm(FlaskForm):
username = StringField(_('Username'), validators=[DataRequired()])
email = StringField(_('Email address'), validators=[Email()])
password = PasswordField(_('Password'), validators=[DataRequired()])
password_retype = PasswordField(_('Password, once more'), validators=[DataRequired()])
def validate_password_retype(self, field):
if field.data != self.password.data:
raise ValidationError(_('The two passwords must match!'))
class TimezoneField(SelectField):
def __init__(self, *args, **kwargs):
kwargs.update({
'choices': [
(pytz.timezone(tz), tz.replace('_', ' '))
for tz in pytz.common_timezones
],
})
SelectField.__init__(self, *args, **kwargs)
def process_formdata(self, valuelist):
if not valuelist:
self.data = None
return
try:
self.data = pytz.timezone(valuelist[0])
except pytz.exceptions.UnknownTimeZoneError:
self.data = None
raise ValueError('Unknown time zone')
@staticmethod
def is_pytz_instance(value):
return value is pytz.UTC or isinstance(value, pytz.tzinfo.BaseTzInfo)
def process_data(self, value):
if value is None:
self.data = None
return
if self.is_pytz_instance(value):
self.data = value
return
try:
self.data = pytz.timezone(value)
except Exception as exc:
raise ValueError(f'Unknown time zone {value}')
def iter_choices(self):
for value, label in self.choices:
yield (value, label, value == self.data)
class EventForm(FlaskForm):
title = StringField(_('Title'), validators=[DataRequired()])
time_zone = TimezoneField(_('Time zone'), validators=[DataRequired()])
start_time = DateTimeField(_('Start time'), validators=[DataRequired()])
end_time = DateTimeField(_('End time'), validators=[DataRequired()])
all_day = BooleanField(_('All day'))
description = StringField(_('Description'), widget=TextArea())
def populate_obj(self, obj):
FlaskForm.populate_obj(self, obj)
timezone = self.time_zone.data
obj.time_zone = str(timezone)
obj.start_time = timezone.localize(self.start_time.data).astimezone(pytz.utc)
obj.end_time = timezone.localize(self.end_time.data).astimezone(pytz.utc)
def validate_end_time(self, field):
if field.data < self.start_time.data:
raise ValidationError(_('End time must be later than start time!'))