Skip to content

Commit fe0277d

Browse files
committed
add email support
v2.0
1 parent 0ba03ee commit fe0277d

27 files changed

+141
-272
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ __pycache__/
66
# C extensions
77
*.so
88

9+
# .idea
10+
*.idea
11+
.idea/
12+
913
# Distribution / packaging
1014
.Python
1115
build/

.idea/.gitignore

-3
This file was deleted.

.idea/flask-simple-form.iml

-13
This file was deleted.

.idea/inspectionProfiles/profiles_settings.xml

-6
This file was deleted.

.idea/libraries/R_User_Library.xml

-6
This file was deleted.

.idea/misc.xml

-7
This file was deleted.

.idea/modules.xml

-8
This file was deleted.

.idea/vcs.xml

-6
This file was deleted.

README.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ This is a simple flask register-form application designed to run in multiple way
55
* This app use _[MongoDB](https://www.mongodb.com/)_ as database supported by _[Flask-MongoAlchemy](https://pythonhosted.org/Flask-MongoAlchemy/)_ extension
66
=> So you have to install **MongoDB** database to run this locally
77

8-
* uses _[Flask-SocketIO](https://github.com/miguelgrinberg/Flask-SocketIO)_ along with _Ajax_ for real time update
8+
* uses _[Flask-SocketIO](https://github.com/miguelgrinberg/Flask-SocketIO)_ along with _[Ajax](https://en.wikipedia.org/wiki/Ajax_(programming)_ for real time update
99

10+
* you will get an email if you have registered
1011

1112
# Overview
1213
![index](/img/index.png)
1314
![registered](/img/registered.png)
15+
![email](/img/email.png)
1416

1517
# Running this app
1618

@@ -31,6 +33,7 @@ This app is designed to run in different ways:
3133
### running the app
3234

3335
* After installing, you need to set your application _environment variable_ by running `export FLASK_APP=app.py`
36+
* run `export MAIL_PASSWORD=<your-email-password>` to set your email password _environment variable_
3437
* run the server using the script file `run.sh` by typing `./run`
3538
* Access the running app in a browser at the URL written to the console (most likely http://0.0.0.0:5000)
3639

app/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
## This folder _contains the application files_

app/REAMDE.md

-1
This file was deleted.

app/__init__.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
from flask import Flask
22
from app.config import Config
33
from flask_mongoalchemy import MongoAlchemy
4-
4+
from flask_socketio import SocketIO
5+
from flask_mail import Mail
56

67
app = Flask(__name__)
78
app.config.from_object(Config)
89
db = MongoAlchemy(app)
9-
10+
socketio = SocketIO(app)
11+
mail = Mail(app)
1012

1113
from app import models, views

app/config.py

+7
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,10 @@ class Config(object):
99
SECRET_KEY = os.environ.get('SECRET_KEY') or 'secret'
1010
# sets MongoDB database
1111
MONGOALCHEMY_DATABASE = 'flask-simple-form'
12+
# send mail confi
13+
MAIL_SERVER = os.environ.get('MAIL_SERVER') or 'smtp.googlemail.com'
14+
MAIL_PORT = os.environ.get('MAIL_PORT') or 587 or 25 # 25 smtp port
15+
MAIL_USE_TLS = True
16+
MAIL_USERNAME = os.environ.get('MAIL_USERNAME') or '[email protected]'
17+
MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD') ## set it using export MAIL_PASSWORD=<your-email-password>
18+

app/mail.py

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from app import app, mail
2+
from flask_mail import Message
3+
from flask import render_template
4+
from threading import Thread
5+
6+
def send_email_helper(subject , sender, recipients, text_body, html_body):
7+
msg = Message(subject, sender=sender, recipients=recipients)
8+
msg.body = text_body
9+
msg.html = html_body
10+
Thread(target=send_sync_email, args=(app, msg)).start()
11+
12+
13+
def send_sync_email(app, msg):
14+
with app.app_context():
15+
mail.send(msg)
16+
17+
def send_mail(user):
18+
send_email_helper('[Flask-Simple-Form] Notification', sender=app.config['MAIL_USERNAME'], \
19+
recipients=[user.email], text_body = render_template('email/register_notification.txt', user=user),
20+
html_body = render_template('email/register_notification.html', user=user))

app/templates/email/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
## This folder contains email files
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
2+
3+
<div style=" background-color: #3b4b54; width : 100%;
4+
height: 100%;
5+
margin: 0 auto;
6+
font-size: 110%;
7+
color: #ffffff;
8+
font-family: sans-serif;">
9+
10+
<img style=" padding-top: 10%;
11+
display: block;
12+
margin: 0 auto;
13+
padding-bottom: 2em;
14+
max-width:200px;" src="https://raw.githubusercontent.com/AhmNouira/flask-simple-form/master/app/static/images/newapp-icon.png" alt="newapp" />
15+
16+
<div style="text-align: center;">
17+
<h2> Dear {{ user.first_name }}, {{user.last_name}} </h2>
18+
<h2>
19+
Thanks for registering to <a style="color: #00aed1; text-decoration:none;" href="https://github.com/AhmNouira/flask-simple-form" target=_blank> Flask-Simple-Form </a></h2>
20+
21+
<h2> See you later </h2>
22+
23+
<h2> ^^ The Blog Team ^^ </h2>
24+
<br>
25+
<br>
26+
</div>
27+
</div>
28+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Dear {{user.first_name }}, {{ user.last_name}}
2+
Thank you for your registering to our Flask-Simple-Form
3+
4+
Sincerely,
5+
6+
^^ Flask-Simple-Form Team ^^

app/time_socket.py

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
from app import socketio
2+
from flask_socketio import emit
3+
from datetime import datetime as dt
4+
5+
6+
thread = None
7+
time = {}
8+
9+
10+
def time_dict():
11+
global time
12+
time = {
13+
'day_name': str(dt.strftime(dt.now(), '%A')),
14+
'month': str(dt.strftime(dt.now(), '%B')),
15+
'day': str(dt.now().day),
16+
'year': str(dt.now().year),
17+
'hour': str(dt.now().hour),
18+
'minute': str(dt.strftime(dt.now(), '%M')),
19+
'second': str(dt.strftime(dt.now(), '%S')),
20+
'pm_am': str(dt.strftime(dt.now(), '%P'))
21+
}
22+
23+
24+
25+
26+
def background_thread():
27+
while True:
28+
29+
socketio.sleep(1)
30+
31+
time_dict()
32+
33+
"""
34+
On every seconds, the server send message to the client with updated time.
35+
First parameter of emit function tells which function to call on client side.
36+
37+
"""
38+
socketio.emit('my_response',
39+
{'data': 'Message from server', 'time': time},
40+
namespace='/test')
41+
42+
43+
@socketio.on('connect', namespace='/test')
44+
def test_connect():
45+
time_dict()
46+
global thread
47+
if thread is None:
48+
# Once any client is connected, the background_thread function starts in loop
49+
thread = socketio.start_background_task(target=background_thread)
50+
51+
socketio.emit('my_response',
52+
{'data': 'Message from server', 'time': time},
53+
namespace='/test')

app/views.py

+7-52
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,9 @@
1-
21
from flask import render_template, redirect, url_for
2+
from app import app
33
from app.forms import UserForm
44
from app.models import Users as User
5-
from datetime import datetime as dt
6-
from flask_socketio import SocketIO, emit
7-
from app import app
8-
socketio = SocketIO(app)
9-
thread = None
10-
time = {}
11-
12-
13-
def time_dict():
14-
global time
15-
time = {
16-
'day_name': str(dt.strftime(dt.now(), '%A')),
17-
'month': str(dt.strftime(dt.now(), '%B')),
18-
'day': str(dt.now().day),
19-
'year': str(dt.now().year),
20-
'hour': str(dt.now().hour),
21-
'minute': str(dt.strftime(dt.now(), '%M')),
22-
'second': str(dt.strftime(dt.now(), '%S')),
23-
'pm_am': str(dt.strftime(dt.now(), '%P'))
24-
}
25-
26-
27-
def background_thread():
28-
while True:
29-
30-
socketio.sleep(1)
31-
32-
time_dict()
33-
34-
"""
35-
On every seconds, the server send message to the client with updated time.
36-
First parameter of emit function tells which function to call on client side.
37-
38-
"""
39-
socketio.emit('my_response',
40-
{'data': 'Message from server', 'time': time},
41-
namespace='/test')
42-
5+
from app.mail import send_mail
6+
from app.time_socket import *
437

448
@app.route("/", methods=['GET', 'POST'])
459
def index():
@@ -57,6 +21,10 @@ def index():
5721
user.set_password(form.password.data)
5822
print("USER-->", user)
5923
user.save()
24+
send_to_user = User.query.filter(User.email == user.email).first()
25+
if send_to_user:
26+
send_mail(user)
27+
print ('SEND_TO-->', send_to_user.first_name + " " + send_to_user.last_name)
6028
return redirect(url_for('registered'))
6129
return render_template('index.html', form=form, time=time)
6230

@@ -66,16 +34,3 @@ def registered():
6634
time_dict()
6735

6836
return render_template('registered.html', time=time)
69-
70-
71-
@socketio.on('connect', namespace='/test')
72-
def test_connect():
73-
time_dict()
74-
global thread
75-
if thread is None:
76-
# Once any client is connected, the background_thread function starts in loop
77-
thread = socketio.start_background_task(target=background_thread)
78-
79-
socketio.emit('my_response',
80-
{'data': 'Message from server', 'time': time},
81-
namespace='/test')

img/email.png

68.8 KB
Loading

migrations/README

-1
This file was deleted.

migrations/alembic.ini

-45
This file was deleted.

0 commit comments

Comments
 (0)