diff --git a/.vscode/settings.json b/.vscode/settings.json index 90429d1..87f404c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,9 @@ { "cSpell.words": [ "sessionmaker" + ], + "python.analysis.extraPaths": [ + "./class/model", + "./class" ] } \ No newline at end of file diff --git a/app.py b/app.py index f7bf3d8..1086369 100644 --- a/app.py +++ b/app.py @@ -1,59 +1,144 @@ +from driverHandler import DriverHandler from gpxInterpreter import GPXHandler +from vehicleHandler import VehicleHandler from dotenv import load_dotenv -from flask import Flask, send_from_directory, jsonify, request -from sqlalchemy import create_engine -from sqlalchemy.orm import sessionmaker +from flask import Flask, app, send_from_directory, request +from sqlalchemy import NullPool, create_engine +from sqlalchemy.orm import sessionmaker, Session +from geoObjects import createTables -Session: Session -app: any +__session: Session +FlaskApp: app +__gpxHandler: GPXHandler +__driverHandler: DriverHandler +__vehicleHandler: VehicleHandler -def entry(): + +def entryPoint(): print("load environment") load_dotenv() print("create flask application") - app = Flask(__name__, static_folder='web/dist') - - # TODO: all the sqlalchemy stuff should be moved out of app.py - Base = declarative_base() + FlaskApp = Flask(__name__, static_folder='web/dist') def db_connect(connectionPath): return create_engine(connectionPath, poolclass=NullPool) - Base.metadata.create_all(db_connect) - session = sessionmaker(bind=db_connect())() + __session = sessionmaker(bind=db_connect())() - # handler class for all gpx files + # handler classes # handles parsing files and interacting with database - gpxHandler = GPXHandler(session) + __gpxHandler = GPXHandler(__session) + __driverHandler = DriverHandler(__session) + __vehicleHandler = VehicleHandler(__session) + + # creating tables + createTables(__session) app.run(debug=True) # TODO: move functional parts out to api package if not handled by other classes -@app.route('/') -def serve_vue_app(): - return send_from_directory(app.static_folder, 'index.html') -@app.route("/route", method=['GET']) + +@FlaskApp.route('/') +def serve_vue_app(): + return send_from_directory(FlaskApp.static_folder, 'index.html') + + +@FlaskApp.route("/route", method=['GET']) def getRoute(): - # TODO: will contact gpx handler to get geoJSON from + # TODO: will contact gpx handler to get geoJSON from return "not implemented", 500 - -@app.route('/upload', methods=['POST']) + + +@FlaskApp.route("/driver", methods=['GET', 'POST']) +def handleDriverRoute(): + + if request.method == "GET": + if 'driver' in request.args: + + try: + __driverHandler.getVehicle(int(request.args["driver"])) + # return drivers, 200 + except Exception as e: + return "error" + " " + str(e), 500 + + else: + + try: + __driverHandler.getVehicles() + # return drivers, 200 + except Exception as e: + return "error" + " " + str(e), 500 + + elif request.method == "POST": + if "name" not in request.args: + return "missing name", 400 + + # handle creating vehicle + try: + __driverHandler.createVehicle(request.args["name"]) + except Exception as e: + return "error" + " " + str(e), 500 + + return "not implemented", 500 + + +@FlaskApp.route("/vehicle", methods=['GET', 'POST']) +def handleVehicleRoute(): + + if request.method == "GET": + if 'vehicle' in request.args: + + try: + __vehicleHandler.getVehicle(int(request.args["driver"])) + # return drivers, 200 + except Exception as e: + return "error" + " " + str(e), 500 + + else: + + try: + __vehicleHandler.getVehicles() + # return drivers, 200 + except Exception as e: + return "error" + " " + str(e), 500 + + elif request.method == "POST": + if "name" not in request.args: + return "missing name", 400 + + if "type" not in request.args: + return "missing type", 400 + + # handle creating vehicle + try: + __vehicleHandler.createVehicle( + request.args["name"], request.args["type"]) + except Exception as e: + return "error" + " " + str(e), 500 + + return "not implemented", 500 + + +@FlaskApp.route('/upload', methods=['POST']) def uploadFile(): if 'file' not in request.files: return "no file provided", 400 + if request.args["routeName"] == '': + return "no routename provided", 400 + file = request.files['file'] if file.filename == '': return "no file selected", 400 try: - gpx_handler = GPXHandler(file.stream) - gpx_handler.parse() + __gpxHandler.parse(file, request.args["routeName"]) return "file stored succesfull", 200 except Exception as e: return "error" + " " + str(e), 500 + if __name__ == '__main__': - entry() \ No newline at end of file + entryPoint() diff --git a/class/driverHandler.py b/class/driverHandler.py new file mode 100644 index 0000000..78ac1d5 --- /dev/null +++ b/class/driverHandler.py @@ -0,0 +1,29 @@ +from sqlalchemy.orm import Session + +from geoObjects import Driver + +class DriverHandler: + __dbSession: Session + + def __init__(self, session:Session): + self.__dbSession = session + pass + + # handles creating a driver in the database + def createDriver(self, name:str): + + # makes sure that a name always is provided + if not name: + raise ValueError("name is empty") + + self.__dbSession.add(Driver(name=name)) + self.__dbSession.commit() + pass + + # handles getting a driver by its id from the database + def getDriver(self, id:int): + pass + + # handles getting all drivers from the database + def getDrivers(self): + pass \ No newline at end of file diff --git a/class/gpxInterpreter.py b/class/gpxInterpreter.py index 8fe6ed3..09e002f 100644 --- a/class/gpxInterpreter.py +++ b/class/gpxInterpreter.py @@ -1,5 +1,6 @@ import gpxpy import gpxpy.gpx +from sqlalchemy.orm import Session class GPXHandler: __dbSession: Session @@ -16,7 +17,7 @@ class GPXHandler: # handles a route from db and converting it into geoJSON def getRoute(self, route): pass - - # handles storing a route in db - def saveInDB(): + + # handles calculating the distance between two points + def calcDist(self, p1, p2): pass \ No newline at end of file diff --git a/class/model/geoObjects.py b/class/model/geoObjects.py index 45406b1..376d499 100644 --- a/class/model/geoObjects.py +++ b/class/model/geoObjects.py @@ -16,8 +16,8 @@ class Track(Base): __tablename__ = 'track' id = Column(Integer, primary_key=True, autoincrement=True) trackName = Column(String(200), nullable=True) - vehicle = Column(Integer, ForeignKey('vehicle.id'), nullable=False) - driver = Column(Integer, ForeignKey('driver.id'), nullable=False) + vehicle = Column(Integer, ForeignKey('vehicle.id'), nullable=False, default=1) + driver = Column(Integer, ForeignKey('driver.id'), nullable=False, default=1) date = Column(Date, nullable=True) distance = Column(Float, nullable=False, default=0) speed = Column(Float, nullable=False, default=0) diff --git a/class/vehicleHandler.py b/class/vehicleHandler.py new file mode 100644 index 0000000..91e7909 --- /dev/null +++ b/class/vehicleHandler.py @@ -0,0 +1,30 @@ +from sqlalchemy.orm import Session + +from geoObjects import Vehicle + +class VehicleHandler: + __dbSession: Session + + def __init__(self, session:Session): + self.__dbSession = session + pass + + # handles creating a vehicle and storing it in the database + def createVehicle(self, name:str, type:str): + if not name: + raise ValueError("name is empty") + + if not type: + raise ValueError("vehicle is empty") + + self.__dbSession.add(Vehicle(name, type)) + self.__dbSession.commit() + pass + + # handles getting a vehicle identified with its id from the database + def getVehicle(self, id:int): + pass + + # handles getting all vehicles from database + def getVehicles(self): + pass \ No newline at end of file diff --git a/compose.yaml b/compose.yaml index 8d76510..6f180e4 100644 --- a/compose.yaml +++ b/compose.yaml @@ -13,7 +13,7 @@ services: networks: - backend - web: + GeoTrack: build: . ports: - "8000:5000"