From e87aa3d5de872010482e2415f293033b3e868eb7 Mon Sep 17 00:00:00 2001 From: itsGarrin Date: Fri, 10 Nov 2023 17:13:38 -0500 Subject: Finished load() and save() in db.py --- dashboard_website/db.py | 122 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 90 insertions(+), 32 deletions(-) (limited to 'dashboard_website') diff --git a/dashboard_website/db.py b/dashboard_website/db.py index 1bc1f3c..e1c5970 100644 --- a/dashboard_website/db.py +++ b/dashboard_website/db.py @@ -1,34 +1,37 @@ # stores and manages clue DB # also manages currently available bike teams -from datastructs import * -import router -import csv, time +import csv from threading import Thread +import router +from datastructs import * + # constants -CLUE_MIN_DISTANCE = 0.1 # minimum distance between clue and bike to be considered valid visitation +CLUE_MIN_DISTANCE = 0.1 # minimum distance between clue and bike to be considered valid visitation # variables -homeBase = Point(42.340226, -71.088395) # krentzman, can be changed on dashboard +homeBase = Point(42.340226, -71.088395) # krentzman, can be changed on dashboard clues = [] bikes = [] clusters = [] -routes = {"clusters" : [], "cluster_times" : {}, "individual_routes" : []} #geojson polylines, both between all the clusters +routes = {"clusters": [], "cluster_times": {}, + "individual_routes": []} # geojson polylines, both between all the clusters assigned_clues = [] clues_last_changed = time.time() home_last_changed = time.time() -routes_last_changed = time.time() +routes_last_changed = time.time() currently_updating = False -startup = False # +startup = False # + # called every time a node is added # a bike is added/removed # determines/assigns clusters, and assigns routes to bikes -def updateRoutes_background(): # run in thread due to long runtime +def updateRoutes_background(): # run in thread due to long runtime global currently_updating, routes_last_changed, routes print("Calculating clusters...") - routes = {"clusters" : [], "cluster_times" : {}, "individual_routes" : []} # reset + routes = {"clusters": [], "cluster_times": {}, "individual_routes": []} # reset clusters, paths, times = router.getClusters(bikes, clues, homeBase) routes['individual_routes'] = paths.copy() routes['cluster_times'] = times @@ -36,33 +39,39 @@ def updateRoutes_background(): # run in thread due to long runtime for i in range(len(bikes)): if bikes[i].status == "ACTIVE": routes['individual_routes'][i] = router.getRouteHDPolyline(bikes[i], clusters[i][0]) - + routes_last_changed = time.time() print("Finished calculating clusters/routes.") currently_updating = False -def updateRoutes(): # if necessary + +def updateRoutes(): # if necessary global currently_updating if not currently_updating: currently_updating = True t = Thread(target=updateRoutes_background) t.start() + # interface functions def getTime(): return time.time() + def getHomeBaseJSON(timestamp): if timestamp < 0 or home_last_changed - timestamp > 0: return homeBase.toJSON() return False + def setHomeBase(latitude, longitude): homeBase.setCoords(latitude, longitude) home_last_changed = time.time() + def getBikeCluePair(team_name): - b = None; c = None + b = None; + c = None for bike in bikes: if bike.name == team_name: b = bike @@ -72,7 +81,7 @@ def getBikeCluePair(team_name): break break return b, c - + def getRoutesJSON(timestamp): if timestamp < 0 or routes_last_changed - timestamp > 0: @@ -82,28 +91,31 @@ def getRoutesJSON(timestamp): def deleteBike(team_name): for bike in bikes: - if bike.name == team_name: # already exists + if bike.name == team_name: # already exists bike.disable() updateRoutes() - return 0 # OK - return 4 # bike does not exist + return 0 # OK + return 4 # bike does not exist + def addBike(team_name, latitude, longitude): for bike in bikes: - if bike.name == team_name: # already exists - return 4 # already exists + if bike.name == team_name: # already exists + return 4 # already exists newBike = Bike(latitude, longitude, team_name, "ACTIVE") bikes.append(newBike) updateRoutes() return 0 + def pingBike(team_name, latitude, longitude): for bike in bikes: if bike.name == team_name: bike.ping() bike.setCoords(latitude, longitude) return 0 - return 4 # team not found + return 4 # team not found + def getBikesJSON(): global bikes @@ -119,11 +131,13 @@ def getCluesJSON(timestamp): return [x.toJSON() for x in clues] return False + def addClue(clue_name, clue_info, longitude, latitude, visited="UNVISITED"): newClue = Clue(latitude, longitude, clue_name, clue_info, visited) clues.append(newClue) clues_last_changed = time.time() + def deleteClue(clue_name): for i, clue in enumereate(clues): if clue.name == clue_name: @@ -132,38 +146,40 @@ def deleteClue(clue_name): updateRoutes() break + def visitClue(clue_name): for clue in clues: if clue.name == clue_name: if clue.status == "VISITED": - return 3 # already visited + return 3 # already visited clue.visit() clues_last_changed = time.time() - #updateRoutes() - return 0 # OK - return 2 # no clue found + # updateRoutes() + return 0 # OK + return 2 # no clue found + def visitClueTeam(team_name, clue_name): b = None for bike in bikes: - if bike.name == team_name: + if bike.name == team_name: b = bike else: - return 4 # team not found + return 4 # team not found c = None for clue in clues: if clue.name == clue_name: c = clue if c.status == "VISITED": - return 6 # already visited - break # continue + return 6 # already visited + break # continue else: - return 5 # clue not found - + return 5 # clue not found + # if visited clue is the expected one (current target) if clue_name == b.target_name: if c.distanceTo(b) < CLUE_MIN_DISTANCE: - return 3 # too far away + return 3 # too far away b.visitTarget() clues_last_changed = time.time() return 0 @@ -172,13 +188,55 @@ def visitClueTeam(team_name, clue_name): c.visit() clues_last_changed = time.time() + +def load(filename=None): + """ + Loads all clues from a CSV file + :param filename: name of CSV file + :return: None + """ + # if there is no filename, wipe all clues + if filename is None: + clues.clear() + + # otherwise, load from file + with open(filename, newline='') as f: + csvreader = csv.reader(f, delimiter=',', quotechar='"') + + # skip header row + next(csvreader) + + for row in csvreader: + name = row[0] + latitude = row[1] + longitude = row[2] + info = row[3] + status = row[4] + + clues.append(Clue(latitude, longitude, name, info, status)) + + +def save(): + """ + Writes all clues to a csv file + :return: a CSV file with all clues + """ + with open("savefile.csv", 'w', newline='') as f: + csvwriter = csv.writer(f, delimiter=',', quotechar='"') + # add a header row + csvwriter.writerow(["name", "latitude", "longitude", "info", "status"]) + for clue in clues: + csvwriter.writerow([clue.name, clue.latitude, clue.longitude, clue.info, clue.status]) + + # junk for testing with open("all_clues.csv", newline='') as f: csvreader = csv.reader(f, delimiter=',', quotechar='"') i = 1 for row in csvreader: coords = row[1].split(",") - coords[0] = float(coords[0]); coords[1] = float(coords[1]); + coords[0] = float(coords[0]); + coords[1] = float(coords[1]); newClue = Clue(coords[0], coords[1], f"Clue #{i}", row[0], "UNVISITED" if i < 100 else "VISITED") clues.append(newClue) -- cgit v1.2.3