python-podcast-feed-generator/app/forms.py
2021-01-01 18:47:48 +01:00

139 lines
6.4 KiB
Python

#!/usr/bin/env python3
'''
python-podcast-feed-generator provides a simple web interface to feedgen
app/forms.py defines the forms
Copyright (C) 2020 Demetris Karayiannis <dkarayiannis.eu/p/contact>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
'''
from flask_wtf import FlaskForm
from wtforms import (StringField, PasswordField, BooleanField, SubmitField,
TextAreaField, FormField)
from wtforms.fields.html5 import DateField, TimeField
from wtforms.validators import (DataRequired, Email, Length, URL,
ValidationError, Optional, EqualTo)
from app.models import Podcast, Episode, User
class LoginForm(FlaskForm):
username = StringField('Username', validators=[DataRequired()])
password = PasswordField('Password', validators=[DataRequired()])
remember_me = BooleanField('Keep me logged in')
submit = SubmitField('Log In')
class RegistrationForm(FlaskForm):
# We don't do any uniqueness here because we do not serve this page at all
# if one user already exists.
username = StringField('Username', validators=[DataRequired(),
Length(min=3, max=64)])
password = PasswordField('Password', validators=[DataRequired(),
Length(min=8, max=256)])
password_2 = PasswordField('Confirm Password', validators=[DataRequired(),
Length(min=8, max=256),
EqualTo('password')])
submit = SubmitField('Register')
class EditPodcastForm(FlaskForm):
'''
This form is used to Add or Update Podcast information
db_idx is used to hold the Podcast.id passed by edit_podcast() and use it
to compare with the duplicate title entry found by validate_title()
'''
# TODO: Add same validations to models.py
db_idx = StringField('ID')
title = StringField('Title',
validators=[DataRequired(), Length(min=2, max=256)]
)
subtitle = TextAreaField('Subtitle',
validators=[DataRequired(),
Length(min=2, max=2048)]
)
author_name = StringField('Author Name',
validators=[DataRequired(),
Length(min=2, max=256)]
)
author_email = StringField('Author E-mail',
validators=[DataRequired(), Email(),
Length(min=4, max=256)]
)
link = StringField('Website URL', validators=[DataRequired(), URL(),
Length(min=4, max=256)])
logo = StringField('Logo URL', validators=[DataRequired(), URL,
Length(min=4, max=512)])
language = StringField('Language Code', validators=[DataRequired(),
Length(min=2, max=6)])
submit = SubmitField('Submit')
def validate_title(self, title):
'''
Check whether a podcast with the same title is already in the DB.
All other fields for a Podcast do not have to be unique.
TODO: Add logic to skip this test when editing existing podcast AND
the new title = old title
'''
title_match = Podcast.query.filter_by(title=title.data).first()
if title_match:
if title_match.id == self.db_idx.data:
pass
else:
raise ValidationError(f"A podcast with this title already "
f"exists. Please choose a different "
f"title.")
class DateTimeForm(FlaskForm):
date = DateField('Publication Date', format="%Y-%m-%d",
validators=[Optional()])
time = TimeField('Publication Time', format='%H:%M:%S',
render_kw={"step": "1"}, # This is done to get seconds
validators=[Optional(strip_whitespace=True)])
class EditEpisodeForm(FlaskForm):
'''
This form is used to Add or Update Episode information
db_idx is used to hold the Podcast.id passed by edit_podcast() and use it
to compare with the duplicate title entry found by validate_title()
'''
# TODO: Add same validations to models.py
db_idx = StringField('ID')
guid = StringField(f"Globally Unique ID, typically the episode page's "
f"canonical URL",
validators=[DataRequired(), Length(min=2, max=256)]
)
title = StringField('Title',
validators=[DataRequired(), Length(min=2, max=256)]
)
description = TextAreaField('Episode description or show notes',
validators=[DataRequired(),
Length(min=2, max=2048)]
)
# This returns a {'date': x, 'time': y, 'csrf_token': z}
# Flags are exposed per field: pubDate.time.flags
pubDate = FormField(DateTimeForm, f"Publication Date and Time in UTC")
# NOTE: Handling file uploads is out of scope at the moment
enc_url = StringField('Enclosure URL', validators=[DataRequired(), URL(),
Length(min=4, max=512)])
# TODO: Add button to get filesize with http request
enc_length = StringField('Enclosure Size',
validators=[Optional(strip_whitespace=True)])
# Define filetype validator
enc_type = StringField('Enclosure File Type',
validators=[DataRequired(),
Length(min=6, max=10)])
submit = SubmitField('Submit')