Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AutoMate #48

Open
wants to merge 6 commits into
base: main
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
28 changes: 28 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
.env

venv
__pycache__
319 changes: 319 additions & 0 deletions Backend/controllers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,319 @@
import os

import bcrypt
from dotenv import find_dotenv, load_dotenv
from flask import jsonify, request
from flask_jwt_extended import (
JWTManager,
create_access_token,
get_jwt_identity,
jwt_required,
)
from googlemaps import Client
from main import app, ma
from models import User, db

load_dotenv(dotenv_path=find_dotenv())

jwt = JWTManager(app)


salt = bcrypt.gensalt()

# Access the environment variables
secret_key = os.getenv("VITE_GOOGLE_MAPS_API_KEY")

gmaps = Client(key=secret_key)


# Auto generate Schema using models
class UserSchema(ma.SQLAlchemyAutoSchema):
class Meta:
model = User


matched_users = {}

# searching_users = {
# 1: {
# "currentloc": {"lat": 20.01840125104431, "lng": 72.8372607837342},
# "dest": "asc",
# },
# 9: {
# "currentloc": {"lat": 20.01840125104431, "lng": 72.8372607837342},
# "dest": "asc",
# },
# }

searching_users = {}


@app.post("/api/login")
def login():
# Getting user Creds
userdata = request.get_json()
email = userdata["email"]
password = userdata["password"].encode()

# Getting Creds from db
curr_user = User.query.filter_by(email=email).first()

# checking creds
if curr_user is None:
return jsonify({"msg": "Invalid Email"}), 401
elif bcrypt.checkpw(password, curr_user.password):
# Creating JWT token
access_token = create_access_token(identity=curr_user.id)
return jsonify(access_token=access_token)
else:
return jsonify({"msg": "Bad password"}), 401


# Create User
@app.post("/api/register")
def register():
userdata = request.get_json()

if not userdata["username"] or not userdata["password"]:
return jsonify({"msg": "Please enter username and pasword"}), 400

usr = User.query.filter_by(username=userdata["username"]).first()
em = User.query.filter_by(email=userdata["email"]).first()

if usr or em:
return jsonify({"msg": "User already Exists"}), 400
password = userdata["password"].encode()

# Hashing Password
hashed_pass = bcrypt.hashpw(password, salt)

# commiting Data
db.session.add(
User(
username=userdata["username"],
age=userdata["age"],
gender=userdata["gender"],
pgender=userdata["pgender"],
pagegrp=userdata["pagegrp"],
email=userdata["email"],
password=hashed_pass,
)
)
db.session.commit()
return jsonify("Success")


@app.post("/api/destination")
def destination():
autocomplete_data = request.get_json()
# coordinates = autocomplete_data["geometry"]["location"]
name = autocomplete_data["name"]
return name


@app.post("/api/route")
def generate_route():
locations = request.get_json()
waypoint = locations["waypoint"]
destination = locations["destination"]
# maps_link = f"https://www.google.com/maps/dir/My+Location/{waypoint['lat']},{waypoint['lng']}/{destination['lat']},{destination['lng']} "
maps_link = f"https://www.google.com/maps/dir/My+Location/{waypoint['lat']},{waypoint['lng']}/{destination}"

return maps_link


# Adds users to a searching queue
@app.post("/api/search")
@jwt_required()
def search():
current_userid = get_jwt_identity()
data = request.get_json()

global searching_users

user_obj = {"currentloc": data["loc"], "dest": data["dest"]}
searching_users.update({current_userid: user_obj})

return searching_users


# Compares curr user with all other users in the search queue and matchs with nearest one
@app.get("/api/match")
@jwt_required()
def match():
global searching_users

current_userid = get_jwt_identity()

origin = searching_users[current_userid]["currentloc"]

if origin is None:
return jsonify("Location not enabled"), 400

destinations = []
# print(searching_users)
# print(len(searching_users))

if len(searching_users) < 2:
return jsonify("No other user currently searching"), 401

for user_id, user_data in searching_users.items():
if user_id == current_userid:
continue
currentloc = user_data.get("currentloc", {})
if currentloc:
destination = user_data.get("dest", "")
result = gmaps.distance_matrix(
origins=origin,
destinations=[currentloc],
units="metric",
mode="walking",
)
if result and "rows" in result and result["rows"]:
elements = result["rows"][0]["elements"]
if elements and elements[0]["status"] == "OK":
distance_text = elements[0]["distance"].get("value")
else:
distance_text = "N/A"
else:
distance_text = "N/A"
# print(distance_text)
if (
distance_text < 50000
and destination == searching_users[current_userid]["dest"]
):
response_data = {
"user_id": user_id,
"destination": destination,
"distance": distance_text,
"loc": currentloc,
}
destinations.append(response_data)

# print(len(destinations), destinations)
if len(destinations) == 0:
return jsonify("No user near you!"), 402

destinations = sorted(destinations, key=lambda x: x["distance"])

global matched_users

user1 = {
"user_id": current_userid,
"accepted": False,
"loc": origin,
"matched_id": destinations[0]["user_id"],
}

user2 = {
"user_id": destinations[0]["user_id"],
"accepted": False,
"loc": destinations[0]["loc"],
"matched_id": current_userid,
}
if user1["user_id"] not in matched_users:
matched_users[user1["user_id"]] = user1

if user2["user_id"] not in matched_users:
matched_users[user2["user_id"]] = user2

# print(matched_users)

return matched_users


# Checks if a user has accepted
@app.get("/api/accepted")
@jwt_required()
def origin_accepted():
current_userid = get_jwt_identity()
global matched_users

try:
matched_users[current_userid]["accepted"] = True

return matched_users
except: # noqa
return "no user is matched with current user.", 401


@app.get("/api/reject")
@jwt_required()
def reject():
global matched_users
global searching_users

current_userid = get_jwt_identity()
try:
other_user_id = matched_users[current_userid]["matched_id"]
del searching_users[current_userid]
del matched_users[current_userid]

del searching_users[other_user_id]
del matched_users[other_user_id]

except:
return "Something went wrong. fix it", 400

return jsonify("Rejected")


# Checks if both user accepted
@app.get("/api/consent")
@jwt_required()
def consent():
current_userid = get_jwt_identity()

try:
other_user_id = matched_users[current_userid]["matched_id"]

if (
matched_users[current_userid]["accepted"]
and matched_users[other_user_id]["accepted"]
):
return "both accepted"
else:
return "both did not accepted", 401
except: # noqa
return "no user is matched with current user.", 401


@app.get("/api/id")
@jwt_required()
def id():
current_userid = get_jwt_identity()
user_detail = User.query.filter_by(id=current_userid).first()
# print(user_detail)
if user_detail:
user_data = {
"id": user_detail.id,
"username": user_detail.username,
"age": user_detail.age,
"gender": user_detail.gender,
}
return user_data, 200
else:
return {"message": "User not found"}
# return str(current_userid)


@app.get("/api/id/<int:matchedId>")
# @jwt_required()
def get_user_by_id(matchedId):
user_detail = User.query.filter_by(id=matchedId).first()
if user_detail:
user_data = {
"id": user_detail.id,
"username": user_detail.username,
"age": user_detail.age,
"gender": user_detail.gender,
}
print(user_data)
return user_data, 200
else:
return {"message": "User not found"}, 404


@app.route("/api")
def index():
return "I love automate"
Binary file added Backend/instance/automate.db
Binary file not shown.
28 changes: 28 additions & 0 deletions Backend/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from datetime import timedelta

from flask import Flask
from flask_cors import CORS
from flask_marshmallow import Marshmallow
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///automate.db"

app.config["JWT_SECRET_KEY"] = "SKBw2u4x246vBnTxBcGrwpUNjbvXZm"
app.config["JWT_ACCESS_TOKEN_EXPIRES"] = timedelta(hours=1500)

# Live Link - https://udayp.live
db = SQLAlchemy(app)


ma = Marshmallow(app)

CORS(app)


from controllers import *

if __name__ == "__main__":
with app.app_context():
db.create_all()
app.run(host="0.0.0.0", debug=True)
12 changes: 12 additions & 0 deletions Backend/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from main import db


class User(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
username = db.Column(db.String(80), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
age = db.Column(db.Integer, nullable=False)
gender = db.Column(db.String, nullable=False)
password = db.Column(db.String(120), nullable=False)
pgender = db.Column(db.String)
pagegrp = db.Column(db.Integer)
Loading