Skip to content

Commit 22df5dc

Browse files
committed
Socket working when creating new channel
1 parent 65182ff commit 22df5dc

28 files changed

+488
-0
lines changed

project2/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Project 2
2+
3+
Web Programming with Python and JavaScript
3.47 KB
Binary file not shown.
1.28 KB
Binary file not shown.
2.62 KB
Binary file not shown.

project2/application.py

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
import os
2+
3+
import json
4+
5+
from flask import Flask, session, render_template, request, session, jsonify
6+
from flask_session import Session
7+
from flask_socketio import SocketIO, emit
8+
from flask_sqlalchemy import SQLAlchemy
9+
10+
11+
from models import *
12+
13+
app = Flask(__name__)
14+
15+
database = SQLAlchemy()
16+
17+
# Check for environment variable
18+
if not os.getenv("DATABASE_URL"):
19+
raise RuntimeError("DATABASE_URL is not set")
20+
21+
app.config["SQLALCHEMY_DATABASE_URI"] = os.getenv("DATABASE_URL")
22+
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
23+
db.init_app(app)
24+
25+
app.config["SECRET_KEY"] = os.getenv("SECRET_KEY")
26+
socketio = SocketIO(app)
27+
28+
# Configure session to use filesystem
29+
app.config["SESSION_PERMANENT"] = False
30+
app.config["SESSION_TYPE"] = "filesystem"
31+
Session(app)
32+
33+
34+
@app.route("/")
35+
def index():
36+
if "user" not in session.keys() or session["user"] is None:
37+
return render_template("login.html")
38+
else:
39+
return render_template("index.html")
40+
41+
42+
@app.route("/login", methods=["GET", "POST"])
43+
def login():
44+
45+
if request.method == "POST":
46+
email = request.form.get("email")
47+
password = request.form.get("password")
48+
#Selec user
49+
u = User.query.filter_by(email=email).first()
50+
if u is None or u.password != password:
51+
return render_template("error.html", message="Username or password incorrect")
52+
else:
53+
session["user"] = u
54+
return render_template("index.html")
55+
56+
return render_template("login.html")
57+
58+
59+
@app.route("/logout")
60+
def logout():
61+
""" Logout the user and clean the cache session"""
62+
session["user"] = None
63+
return render_template("login.html")
64+
65+
66+
@app.route("/register", methods=["GET", "POST"])
67+
def register():
68+
if request.method == 'GET':
69+
return render_template("register.html")
70+
else:
71+
name = request.form.get("name")
72+
email = request.form.get("email")
73+
password = request.form.get("password")
74+
# Create new user
75+
u = User(name=name, email=email, password=password)
76+
77+
#Add new user in the database
78+
u.add_user()
79+
80+
return render_template("login.html")
81+
82+
83+
@socketio.on("create channel")
84+
def socket_create_channel(data):
85+
c = Channel(name=data['name'], user_id=session['user'].id)
86+
c = c.add_channel()
87+
data['id'] = c.id
88+
emit("channel created", data, broadcast=True)
89+
90+
91+
92+
@app.route("/create_channel", methods=["GET"])
93+
def create_channel():
94+
if request.method == "GET":
95+
return render_template("create_channel.html")
96+
97+
98+
@app.route("/join/<string:id>", methods=["GET"])
99+
def join(id):
100+
if request.method == "GET":
101+
c = Channel.query.get(id)
102+
c.add_user_in_channel(session['user'].id)
103+
104+
return render_template("messages.html", channel=c)
105+
106+
@app.route("/my_channels", methods=["GET"])
107+
def my_channels():
108+
my_channels = Channel.query.filter_by(user_id=session["user"].id).all()
109+
return render_template("my_channels.html", my_channels=my_channels)
110+
111+
112+
@app.route("/others_channels", methods=["GET"])
113+
def others_channels():
114+
channels = User_has_channel.query.filter_by(user_id=session["user"].id)
115+
my_channels = []
116+
for channel in channels:
117+
c = Channel.query.filter_by(id=channel.channel_id).first()
118+
my_channels.append(c)
119+
120+
others_channels = Channel.query.all()
121+
122+
123+
for channel in my_channels:
124+
if channel in others_channels:
125+
others_channels.remove(channel)
126+
return render_template("others_channels.html", others_channels=others_channels)

project2/create.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import os
2+
3+
from flask import Flask, render_template, request
4+
from models import *
5+
6+
app = Flask(__name__)
7+
app.config["SQLALCHEMY_DATABASE_URI"] = os.getenv("DATABASE_URL")
8+
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
9+
db.init_app(app)
10+
11+
def main():
12+
db.create_all()
13+
14+
if __name__ == "__main__":
15+
with app.app_context():
16+
main()
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

project2/models.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import os
2+
3+
from flask import Flask
4+
from flask_sqlalchemy import SQLAlchemy
5+
6+
db = SQLAlchemy()
7+
8+
class Channel(db.Model):
9+
__tablename__ = "channels"
10+
id = db.Column(db.Integer, primary_key=True)
11+
name = db.Column(db.String, nullable=False)
12+
user_id = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=False)
13+
messages = db.relationship("Message", backref="channel", lazy=True)
14+
users = db.relationship("User_has_channel", backref="channel", lazy=True)
15+
16+
def add_channel(self):
17+
db.session.add(self)
18+
db.session.commit()
19+
return self
20+
21+
def add_user(self):
22+
u = User_has_channel(user_id=self.user_id, channel_id=self.id)
23+
db.session.add(u)
24+
db.session.commit()
25+
26+
def add_message(self, message, user_id):
27+
m = Message(message=message, channel_id=self.id, user_id=user_id)
28+
db.session.add(m)
29+
db.session.commit()
30+
31+
def add_user_in_channel(self, user_id):
32+
u = User_has_channel(user_id=user_id, channel_id=self.id)
33+
db.session.add(u)
34+
db.session.commit()
35+
36+
37+
class User(db.Model):
38+
__tablename__ = "users"
39+
id = db.Column(db.Integer, primary_key=True)
40+
name = db.Column(db.String, nullable=False)
41+
email = db.Column(db.String, nullable=False)
42+
password = db.Column(db.String, nullable=False)
43+
channels = db.relationship("User_has_channel", backref="user", lazy=True)
44+
45+
def add_user(self):
46+
db.session.add(self)
47+
db.session.commit()
48+
49+
50+
class User_has_channel(db.Model):
51+
__tablename__ = "users_has_channels"
52+
id = db.Column(db.Integer, primary_key=True)
53+
user_id = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=False)
54+
channel_id = db.Column(db.Integer, db.ForeignKey("channels.id"), nullable=False)
55+
56+
57+
class Message(db.Model):
58+
__tablename__ = "messages"
59+
id = db.Column(db.Integer, primary_key=True)
60+
user_id = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=False)
61+
channel_id = db.Column(db.Integer, db.ForeignKey("channels.id"), nullable=False)
62+
message = db.Column(db.String, nullable=False)

project2/requirements.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Flask
2+
Flask-SocketIO
3+
Flask
4+
Flask-Session
5+
psycopg2
6+
SQLAlchemy
7+
flask_sqlalchemy

project2/static/channel.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
document.addEventListener('DOMContentLoaded', () => {
2+
3+
// Connect to websocket
4+
var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port);
5+
6+
// When connected, configure buttons
7+
socket.on('connect', () => {
8+
9+
// Each button should emit a "submit vote" event
10+
document.querySelectorAll('button').forEach(button => {
11+
button.onclick = () => {
12+
const name = document.getElementById("channelName").value;
13+
alert("SOCKET TRIGGERED")
14+
var result = socket.emit('create channel', {'id': 0, 'name': name});
15+
16+
};
17+
});
18+
});
19+
20+
// When a new vote is announced, add to the unordered list
21+
socket.on('channel created', data => {
22+
alert("EMIT")
23+
// Find a <table> element with id="channels":
24+
var table = document.getElementById("channels");
25+
26+
// Create an empty <tr> element and add it to the 1st position of the table:
27+
var row = table.insertRow(-1);
28+
29+
// Insert new cells (<td> elements) at the 1st position of the "new" <tr> element:
30+
var cell1 = row.insertCell(0);
31+
32+
// Add some text to the new cell:
33+
cell1.innerHTML = data["name"];
34+
});
35+
});

project2/static/others_channels.js

Whitespace-only changes.

project2/static/subscribe.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
document.addEventListener('DOMContentLoaded', () => {
2+
3+
document.querySelectorAll('button').forEach(button => {
4+
button.onclick = () => {
5+
var channelName = document.querySelector('#channelName').value;
6+
socket.emit('create channel', {'channelName': channelName});
7+
};
8+
});
9+
10+
11+
});

project2/templates/error.html

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{% extends "layout.html" %}
2+
3+
{% block title %}
4+
Error
5+
{% endblock %}
6+
7+
{% block body %}
8+
<h1>Error</h1>
9+
10+
<div class="form-group">
11+
<h3> {{ message }} </h3>
12+
</div>
13+
14+
<div class="form-group">
15+
<a href="{{ url_for('index') }}">Return to index</a>
16+
</div>
17+
{% endblock %}

project2/templates/index.html

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{% extends "layout.html" %}
2+
3+
{% block title %}
4+
Index
5+
{% endblock %}
6+
7+
{% block body %}
8+
<h1>Index</h1>
9+
10+
11+
<div class="form-group">
12+
<a href="{{ url_for('my_channels') }}">My Channels</a>
13+
</div>
14+
15+
<div class="form-group">
16+
<a href="{{ url_for('others_channels') }}">Others Channels</a>
17+
</div>
18+
19+
<div class="form-group">
20+
<a href="{{ url_for('logout') }}">Log Out</a>
21+
</div>
22+
{% endblock %}

project2/templates/layout.html

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>{% block title %} {% endblock %}</title>
5+
<link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
6+
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js"></script>
7+
{% block head %} {% endblock %}
8+
</head>
9+
<body>
10+
<div class="container">
11+
{% block body %}
12+
{% endblock %}
13+
</div>
14+
15+
</body>
16+
</html>

project2/templates/login.html

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{% extends "layout.html" %}
2+
3+
{% block title %}
4+
Login
5+
{% endblock %}
6+
7+
{% block body %}
8+
<h1>Login</h1>
9+
<form action="{{ url_for('login') }}" method="post">
10+
<div class="form-group">
11+
<input class="form-control" type="name" name="email" placeholder="email">
12+
</div>
13+
<div class="form-group">
14+
<input class="form-control" type="password" name="password" placeholder="password">
15+
</div>
16+
17+
<div class="form-group">
18+
<button class="btn btn-primary">Login</button>
19+
</div>
20+
</form>
21+
22+
<div class="form-group">
23+
<label>Does not have an account? <a href="{{ url_for('register') }}">Sign Up Here</a></label>
24+
</div>
25+
26+
{% endblock %}

project2/templates/messages.html

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{% extends "layout.html" %}
2+
3+
4+
{% block title %}
5+
Channel {{channel.name}}
6+
{% endblock %}
7+
8+
{% block body %}
9+
10+
<form>
11+
<div class="form-group">
12+
<input id="channelName" class="form-control" type="name" name="name" placeholder="name">
13+
</div>
14+
15+
<div class="form-group">
16+
<button class="btn btn-primary">Send message</button>
17+
</div>
18+
</form>
19+
<h1>Messages</h1>
20+
21+
{% endblock %}

0 commit comments

Comments
 (0)