Files
flask_url_shortener/tiny0/forms.py
T

109 lines
4.3 KiB
Python
Raw Normal View History

2020-07-18 13:10:03 +00:00
from flask_wtf import FlaskForm
2020-07-18 16:40:51 +00:00
from wtforms import StringField, SubmitField, ValidationError
2020-08-21 12:17:17 +03:00
from wtforms.validators import DataRequired, Length, Optional
from tiny0.config import WEBSITE_DOMAIN
2020-08-21 12:17:17 +03:00
from tiny0 import db
from tiny0.models import URL
2020-07-18 13:10:03 +00:00
2020-08-22 15:36:09 +03:00
# Validates a url
2020-07-18 16:40:51 +00:00
def validate_URL(form, field):
# Make sure the url is not too short or long
if len(field.data) < 4 or len(field.data) > 2000:
2020-07-19 22:14:49 +00:00
return
2020-07-18 13:10:03 +00:00
2020-07-18 16:40:51 +00:00
# If the url contains spaces or does not have any dots
2020-07-23 17:07:21 +00:00
if (" " in field.data) or not("." in field.data):
2020-07-18 16:40:51 +00:00
# Raise a ValidationError
raise ValidationError("Invalid URL")
2020-07-18 13:10:03 +00:00
2020-07-18 21:50:47 +00:00
# If the url starts with a dot after http:// or after https:// or just starts with a dot
2020-08-16 21:35:02 +03:00
if field.data.lower().startswith("http://.") or field.data.lower().startswith("https://.") or field.data.startswith("."):
2020-07-18 21:50:47 +00:00
# Raise a ValidationError
raise ValidationError("Invalid URL")
2020-07-18 21:50:47 +00:00
2020-07-23 16:57:16 +00:00
# If the url starts with a slash after http:// or after https:// or just starts with a slash
2020-08-16 21:35:02 +03:00
if field.data.lower().startswith("http:///") or field.data.lower().startswith("https:///") or field.data.startswith("/"):
2020-07-23 16:57:16 +00:00
# Raise a ValidationError
raise ValidationError("Invalid URL")
2020-07-18 21:50:47 +00:00
# If the url ends with a dot and it is the only dot
if field.data.endswith(".") and field.data.count(".") == 1:
# Raise a ValidationError
raise ValidationError("Invalid URL")
2020-07-18 21:50:47 +00:00
# If the url contains the websites domain
2020-08-16 21:35:02 +03:00
if WEBSITE_DOMAIN in field.data.lower():
2020-08-21 12:17:17 +03:00
# Raise a ValidationError
2020-08-19 16:31:22 +03:00
raise ValidationError("Invalid URL")
2020-07-18 16:40:51 +00:00
# If the URL does not start with http:// and https://
2020-08-16 21:35:02 +03:00
if not(field.data.lower().startswith("http://")) and not(field.data.lower().startswith("https://")):
# Add http:// to the beginning of the URL
field.data = "http://" + field.data
2020-07-18 16:40:51 +00:00
2020-08-21 12:17:17 +03:00
# Validates a token
def validate_token(form, field):
# Make sure the token is not too short or long
if len(field.data) < 6 or len(field.data) > 16:
return
# If the token is the same as a pages route
2020-08-24 15:25:42 +03:00
if field.data == "tracker" or field.data == "lookup" or field.data == "report" or field.data == "donate":
# Raise a ValidationError
raise ValidationError("Token already exists")
2020-08-21 12:17:17 +03:00
# For each character in the token
for char in field.data:
# If it is not a valid character
if not(char.isalpha()) and not(char.isdigit()) and not(char == "_") and not(char == '-'):
# Raise a ValidationError
raise ValidationError("Token contains invalid characters")
# If the token exists in the database
if db.session.query(db.session.query(URL).filter_by(token=field.data).exists()).scalar():
# Raise a ValidationError
raise ValidationError("Token already exists")
2020-08-22 15:36:09 +03:00
# Validates a short url
def validate_short_URL(form, field):
# Make sure the short url is not too short or long
if len(field.data) < (len(WEBSITE_DOMAIN) + 7) or len(field.data) > (len(WEBSITE_DOMAIN) + 25):
return
# If the start of the short url is not valid
if (not(field.data.lower().startswith(WEBSITE_DOMAIN + "/"))
and not(field.data.lower().startswith("http://" + WEBSITE_DOMAIN + "/"))
and not(field.data.lower().startswith("https://" + WEBSITE_DOMAIN + "/"))):
# Raise a ValidationError
raise ValidationError("Invalid short URL")
# Get the token of the short url
if field.data.lower().startswith(WEBSITE_DOMAIN + "/"):
token = field.data[len(WEBSITE_DOMAIN) + 1:]
elif field.data.lower().startswith("http://" + WEBSITE_DOMAIN + "/"):
token = field.data[len(WEBSITE_DOMAIN) + 8:]
elif field.data.lower().startswith("https://" + WEBSITE_DOMAIN + "/"):
token = field.data[len(WEBSITE_DOMAIN) + 9:]
# If the token of the short url does not exist in the database
if not db.session.query(db.session.query(URL).filter_by(token=token).exists()).scalar():
# Raise a ValidationError
raise ValidationError("That short URL does not exists")
# After all the validation is done set the forms url value as the token
field.data = token
2020-07-18 16:40:51 +00:00
class URLForm(FlaskForm):
2020-08-22 15:36:09 +03:00
url = StringField(validators=[DataRequired(), Length(min=4, max=2000, message="Invalid URL length"), validate_URL])
2020-07-18 16:40:51 +00:00
2020-08-21 12:17:17 +03:00
token = StringField(validators=[Optional(), Length(min=6, max=16, message="Invalid token length"), validate_token])
2020-07-18 23:39:18 +00:00
submit = SubmitField("Shorten")
2020-08-22 15:36:09 +03:00
class TrackerForm(FlaskForm):
url = StringField(validators=[DataRequired(), Length(min=len(WEBSITE_DOMAIN) + 7, max=len(WEBSITE_DOMAIN) + 25, message="Invalid short URL"), validate_short_URL])
submit = SubmitField("Track")