-
Notifications
You must be signed in to change notification settings - Fork 0
/
routes.py
179 lines (142 loc) · 6.21 KB
/
routes.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
from smtplib import SMTPRecipientsRefused
from flask import Blueprint, request, render_template, flash, redirect, url_for
from itsdangerous import BadSignature
from wtforms import ValidationError
from forms import RegisterForm, UnsubscribeForm, PreferencesForm, UpdateForm
import actions
import constants
import auth
api = Blueprint("api", __name__)
def homepage():
form = RegisterForm()
if request.method == "POST":
print(form.errors)
try:
_, duplicate_user = actions.register_new_user(form.email.data, form.postcode.data)
if duplicate_user:
flash(f" We seem to have you registered already, but we've resent your confirmation email!")
else:
flash(f"We've sent a confirmation email to {form.email.data}, please check your inbox!")
return redirect(url_for("api.registered"))
except SMTPRecipientsRefused:
if not form.email.data:
flash(f"Did you forget to enter an email?")
else:
flash(
f"We couldn't send an email to {form.email.data}, please check and try again!", category="warning"
)
except IndexError:
if not form.postcode.data:
flash(f"Did you forget to enter a location?")
else:
flash(f" We couldn't find a location for {form.postcode.data}, please check and try again!")
except:
flash(
"As of September 2021 Weather Window is no longer accepting new users. This is due to security changes from Google"
" which make it difficult for us to maintain the service 😭. Thank you for your interest 🙏 "
)
return render_template("register.html", title="Weather Window", form=form, GOOGLE_API_KEY=constants.GOOGLE_API_KEY)
@api.route("/", methods=["GET", "POST"])
def register():
return homepage()
@api.route("/registered", methods=["GET", "POST"])
def registered():
return homepage()
@api.route("/preferences/<token>", methods=["GET", "POST"])
def preferences(token, header="Update your preferences", subheader="Customize your weather window"):
email = auth.decode_token_to_email(token)
form = PreferencesForm()
if request.method == "POST":
try:
form.validate()
actions.update_preferences_for_user_from_form(email, form=form)
flash(
f"We've updated your preferences, thanks. You'll see this reflected in the next "
f"weather window we send you!"
)
return redirect(url_for("api.index"))
except ValidationError as error:
flash(error, category="error")
form.initialize_from_db(actions.add_or_return_user_preferences(email))
return render_template(
"confirm.html", title="Weather Window: Preferences", header=header, subheader=subheader, form=form
)
@api.route("/unsubscribe", methods=["GET", "POST"])
def unsubscribe_page():
form = UnsubscribeForm()
if request.method == "POST":
try:
email = form.email.data
actions.send_unsubscribe_email(email)
flash(f"Unsubscribe email sent to {email}")
except ValueError:
flash(f"We couldn't find that user, have you already unsubscribed?")
except:
flash(
"We're not able to automatically unsubscribe due to Google blocking our outgoing emails 😞. Please"
" email [email protected] if you'd like us to delete your data"
)
return render_template("unsubscribe.html", form=form)
@api.route("/changepreferences", methods=["GET", "POST"])
def preferences_page():
form = UpdateForm()
if request.method == "POST":
try:
email = form.email.data
try:
actions.send_update_preferences_email(email)
flash(f"We've sent a link to edit your preferences to {email}")
except:
flash("We're not able to update preferences due to Google blocking our outgoing emails 😭")
except ValueError:
flash(f"We couldn't find that user, have you already unsubscribed?")
return render_template("change_preferences.html", form=form)
@api.route("/")
def index():
return render_template("base.html")
@api.route("/ping")
def ping():
return "pong"
@api.route("/confirm/<token>", methods=["GET", "POST"])
def confirm_email(token):
email = auth.decode_token_to_email(token)
if email is None:
flash("This confirmation link is invalid or has expired", "danger")
redirect(url_for("api.index"))
else:
print(f"Email confirmed for user {email}")
user = actions.get_user(email)
if user is None:
flash("Uho, you were already unsubscribed! Please subscribe again")
actions.set_email_verified(user_row=user)
# TODO: we can do this async, move it to a cron job
try:
actions.send_tomorrow_window_to_user(user=user)
flash("Email confirmed, thanks! Check your calendar, you should have an invite for tomorrow!", "success")
except Exception as e:
print(f"New user invite failed - {e}")
flash("Email confirmed, thanks! We will send you a calendar invite for tomorrow shortly!", "success")
return redirect(
url_for(
"api.preferences",
token=token,
header="You're all set!",
subheader="We've confirmed your email and sent you an invite for tomorrow",
)
)
@api.route("/unsubscribe/<token>", methods=["GET", "POST"])
def unsubscribe(token):
try:
email = auth.decode_token_to_email(token)
if email is None:
flash("This unsubscribe link is invalid! Please try again", "danger")
else:
print(f"Unsubscribe confirmed for user {email}")
actions.delete_user(email)
flash("You've been unsubscribed. Starting tomorrow, you won't receive new invites.", "success")
except BadSignature:
print("Bad signature error")
return redirect(url_for("api.index"))
@api.route("/google79a68bb5bf16f86a.html")
def google_verification():
return render_template("google.html")