Skip to content
This repository has been archived by the owner on Aug 21, 2023. It is now read-only.

Backend3 #36

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 91 additions & 12 deletions web/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,24 @@
from flask import Flask, render_template, redirect, request, send_file, g, session #Main Flask
from flask_login import LoginManager, UserMixin, current_user, login_user, login_required, logout_user #To create the Login
from flask_sqlalchemy import SQLAlchemy #SQL Alchemy to create the database
import sys
from werkzeug.security import generate_password_hash, check_password_hash
from datetime import datetime
import time
import sys
#from .robotmodel.python_to_aduino import forward_kin_end, forward_kin_mid, coordinates_to_angles

#Creating the primary database
class User(UserMixin, db.Model): # A table to store users data
__tablename__ = 'User'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(200))
password = db.Column(db.String(200))
student = db.Column(db.Integer) #Equals 1 if this is a student, and 0 otherwise
logged_in = db.Column(db.Integer, default=0) #Equals 1 if logged in, and 0 if you are not logged in
in_cue = db.Column(db.Integer, default=0) #Equals 1 if user is waiting for access to the robot arm, and 0 if not
time = db.Column(db.DateTime, default=datetime.utcnow) #Records the time the user requests access to the robot arm controls
controller = db.Column(db.Integer, default=0) #Records if someone is using the control room

def __repr__(self):
return "<Username: {}>".format(self.username)

Expand All @@ -28,16 +37,32 @@ def __repr__(self):
"""
@app.route('/', methods=['GET', 'POST'])
def welcome():
if current_user is not None:
current_user.logged_in = 0 #update the database
current_user.controller = 0
db.session.commit()
logout_user() #If logged in, every time you go to the home page you will be automatically logged out
return render_template('index.html')

@app.route('/observe')
def observe():
if current_user is not None:
current_user.in_cue = 0 #update the database
current_user.controller = 0
db.session.commit()
return render_template('observe.html')

@app.route('/help')
def help():
return render_template("help.html")

@app.route('/logoutallusers')
def logoutallusers():
list_of_all_users = User.query.all()
for user in list_of_all_users:
user.controller = 0
db.session.commit()
return redirect('/')

@login.user_loader
def load_user(id):
Expand Down Expand Up @@ -67,8 +92,14 @@ def register():
error = 'Passwords do not match. Please, try again.'
return render_template('index.html', error_register=error)

# check if user is a student
if "@minerva.kgi.edu" in username:
is_student = 1
else:
is_student = 0

# store user information, with password hashed
new_user = User(username=username, password=generate_password_hash(password, method='sha256'))
new_user = User(username=username, password=generate_password_hash(password, method='sha256'), student=is_student)
db.session.add(new_user)
db.session.commit()
register_success_message = 'Registered successful. Please log in'
Expand All @@ -78,9 +109,10 @@ def register():


"""
This function is responsible for logging users in to their personal kanban board
This function validates users credentials, if the user is registered it redirects to the Kanban board
If the user is not registered it displays an error that the user is not registered
This function is responsible for logging users to the server.
This function validates user credentials.
If the user is registered it redirects to the observe page of the robotic arm.
If the user is not registered it displays an error that the user is not registered.
"""
@app.route('/login', methods=['GET', 'POST'])
def login():
Expand All @@ -94,6 +126,11 @@ def login():
error = 'The password or the username you entered is not correct!'
return render_template('index.html', message=error)
login_user(user)
user.controller = 0 # update the database
user.logged_in = 1
user.time = datetime.now()
user.in_cue = 1
db.session.commit()
return redirect('/waitroom')
# return render_template('main.html')
elif request.method == 'GET':
Expand All @@ -105,29 +142,51 @@ def login():
@app.route('/logout', methods=['GET', 'POST'])
@login_required
def logout():
user.logged_in = 0 #update the database
db.session.commit()
logout_user()
return redirect('login')

"""
This functions sends the user to waitroom after they have logged in
"""

@app.route('/waitroom', methods=["GET", "POST"])
@login_required
def waitroom():
g.user = current_user
return render_template("waitroom.html", myuser=current_user)
'''
This function retrieves a list of all users waiting to use the robot arm
Then it sorts it by who came first, and second by who is a student
'''
user_list = User.query.filter_by(logged_in=1).filter_by(in_cue=1).all() #returns the list of users waiting to use the robot
user_list.sort(key=lambda User: User.time) #sorts the list by who came first
user_list.sort(key=lambda User: User.student, reverse=True) #sorts the list by who is a student
#print(current_user, file=sys.stderr)
#print(user_list, file=sys.stderr)
#print(user_list.index(current_user)+1)
place_in_line = user_list.index(current_user)
return render_template("waitroom.html", cue_number=place_in_line)


"""
This is the primary function responsible for displaying the tasks
This function does not allow duplicate tasks to exist
This is the main room, where the user can observe the stream of the robot arm
This function requires the user to be logged in using his credentials or as guest
"""
@app.route('/main', methods=["GET", "POST"])
@login_required
def home():
g.user = current_user
return render_template("main.html", myuser=current_user)
list_of_all_users = User.query.all()
controllers = 0
for user in list_of_all_users:
controllers += user.controller

if controllers > 0:
error_message = "Someone is currently using the robot arm. Please wait your turn"
print(error_message, file=sys.stderr)
return render_template("index.html", message=error_message)
else:
current_user.controller = 1
g.user = current_user
return render_template("main.html", myuser=current_user)

@app.route('/main/send_angles', methods=["POST"])
@login_required
Expand Down Expand Up @@ -171,11 +230,31 @@ def process_coordinates():
'theta1': theta1, 'theta2': theta2, 'theta3': theta3}
return render_template("main.html", sent_back_coordinates=True, **content)

@app.route('/controlroom', methods=["GET"]) #This is a master controlroom that will show information about the users.
@login_required
def controlroom():
print(current_user, file=sys.stderr)
print(current_user.username, file=sys.stderr)
if current_user.username == '[email protected]' or \
'[email protected]' or \
'[email protected]' or \
'[email protected]' or \
'[email protected]' or \
'[email protected]' or \
'[email protected]':
current_user.controller = 0
list_of_all_users = User.query.all()
return render_template('controlroom.html', userlist=list_of_all_users)
else:
error_message = 'The control room is only for admin. Please log in'
return render_template('index.html', message=error_message)

# allows downloading the updated file using url '/download'
@app.route('/download')
def download():
path = "sources/command_info.txt"
return send_file(path, as_attachment=True)

#Running the application
if __name__ == "__main__":
app.run(debug=True)
Binary file modified web/primary.db
Binary file not shown.
69 changes: 69 additions & 0 deletions web/templates/controlroom.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Robot Arm Control Room</title>

<!-- <link rel="stylesheet" href="styles.css"> -->
<link rel="stylesheet" href="{{ url_for('static', filename='css/style_waitroom.css') }}">
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>
<link href="https://fonts.googleapis.com/css?family=Ubuntu&display=swap" rel="stylesheet">
<!-- <script src="jquery.js"></script> -->
</head>

<body>

<div class='head'>
<div class="leftside">
<a href="{{ url_for('observe') }}" style="text-decoration:none; color: white;"><h3>RoboArm: Waitroom</h3></a>
</div>
<div class="rightside">
<a href="{{ url_for('observe') }}" class="btn">Observe</a>
<a href="{{ url_for('logout') }}" class="btn">Log Out</a>


</div>
</div>

<div class="wrapper">
<!-- Top Container -->
<section class="top-container">
<header class="showcase">

<section class="top-container">

<table style="width:100%; align='center' ; display:inline-table">
<tr>
<th>ID</th>
<th>Username</th>
<th>Student</th>
<th>Logged In</th>
<th>Waiting to use Robot Arm</th>
<th>Time</th>
<th>In Cue</th>
<th>Controller</th>
{% for user in userlist %}
<tr>
<td>{{ user.id }}</td>
<td>{{ user.username }}</td>
<td>{{ user.student }}</td>
<td>{{ user.logged_in }}</td>
<td>{{ user.in_cue }}</td>
<td>{{ user.time }}</td>
<td>{{ user.in_cue }}</td>
<td>{{ user.controller }}</td>

</tr>
{% endfor %}
</table>

</header>
</section>
<div class="footer">&copy;Robot Arm Team 2020</div>


</body>

</html>
53 changes: 52 additions & 1 deletion web/templates/main.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,34 @@
<!-- <script src="jquery.js"></script> -->
</head>

<!-- To allow everyone to use the robot arm, every user will have 5 minutes -->
<!-- After 5 minutes, you will be redirected back to the observe page -->

<script>
window.setTimeout(function(){
window.location.href = "/observe";}, 300000);
</script>

<body>

<script>
var deadline = new Date();
deadline.setMinutes(deadline.getMinutes() + 5);
var x = setInterval(function() {
var now = new Date().getTime();
var t = deadline - now;
var hours = Math.floor((t%(1000 * 60 * 60 * 24))/(1000 * 60 * 60));
var minutes = (hours * 60 + Math.floor((t % (1000 * 60 * 60)) / (1000 * 60)));
var seconds = Math.floor(((t % (1000 * 60)) / 1000));
document.getElementById("timer").innerHTML = minutes + "m " + seconds + "s ";
if (t < 0) {
clearInterval(x);
document.getElementById("timer").innerHTML = "You will be redirected shortly";
}
}, 1000);
</script>


<main class="recording">
<div class="title small_logo">
<a href="{{ url_for('welcome') }}">
Expand Down Expand Up @@ -101,8 +128,11 @@ <h2 class="c_title">Control room</h2>
{% endif %}
<input type="submit" value="Submit" class="cf_submit">
</form>

<div class="c_howto">
<h3>Your Time Remaining is:</h3>
<h2 id="timer"> </h2>
<br>
<h4>How to</h4>
<p>You can input two types of information, but you can only input one at a time.</p>
<p>Your first option is sending the robot coordinates to which the head should move.</p>
Expand Down Expand Up @@ -146,6 +176,27 @@ <h1>Upload a .py file</h1>
});

</script>

<!-- The following script attempts to calculate the time remaining
for the user controlling the robot arm. This var will be used to
calculate the timer in the waitroom and redirect the next user
in the cue to this main room, and control the robot -->

<script>
window.onload {
var time_in_5m = new Date();
var time_in_5m.setMinutes(time_in_5m.getMinutes() + 5);
var x = setInterval(function() {
var now = new Date().getTime();
var t = deadline - now;
var minutes = Math((t % (1000 * 60 * 60)) / (1000 * 60));
if (t < 0) {t = 0;};
localStorage.setItem("time_remaining",minutes); }, 1000);
}

</script>


</body>

</html>
28 changes: 26 additions & 2 deletions web/templates/waitroom.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@
<!-- <script src="jquery.js"></script> -->
</head>

<!-- After 5 minutes, you will be redirected to the observe page -->

<script>
window.setTimeout(function(){
window.location.href = "/main";}, 300000*{{cue_number}} + 3000);
</script>


<body>
Expand All @@ -41,9 +47,9 @@ <h1>Welcome {{current_user.username}}!</h1>
<br>
<br>
<h3>Your Wait Time is:</h3>
<h2 id="demo"> </h2>
<h2 id="timer"> </h2>
<h3>Your Number in Queue is:</h3>
<h2>2nd</h2>
<h2> {{cue_number}} </h2>
</header>
<div class="top-box top-box-a">
<h4>RoboArm 1</h4>
Expand All @@ -59,6 +65,24 @@ <h4>RoboArm 2</h4>
<div class="footer">&copy;Robot Arm Team 2020</div>
<script src="{{ url_for('static', filename='js/jquery.js') }}"></script>

<script>
window.onload = alert(localStorage.getItem("time_remaining"));
var deadline = new Date();
deadline.setMinutes(deadline.getMinutes() + 5 * ({{ cue_number }}));
var x = setInterval(function() {
var now = new Date().getTime();
var t = deadline - now;
var hours = Math.floor((t%(1000 * 60 * 60 * 24))/(1000 * 60 * 60));
var minutes = (hours * 60 + Math.floor((t % (1000 * 60 * 60)) / (1000 * 60)));
var seconds = Math.floor(((t % (1000 * 60)) / 1000));
document.getElementById("timer").innerHTML = minutes + "m " + seconds + "s ";
if (t < 0) {
clearInterval(x);
document.getElementById("timer").innerHTML = "You will be redirected shortly";
}
}, 1000);
</script>




Expand Down