From 0d484dd42a0149c227249696debeeea174ec3f6c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Oct 2025 13:47:39 +0000 Subject: [PATCH 1/7] Initial plan From ece380007228c927ac9a72342d89f4efa35d4fcd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Oct 2025 13:51:30 +0000 Subject: [PATCH 2/7] Initial analysis of bustracker repository for seat management feature Co-authored-by: Terrificdatabytes <66877413+Terrificdatabytes@users.noreply.github.com> --- __pycache__/app.cpython-312.pyc | Bin 0 -> 79192 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 __pycache__/app.cpython-312.pyc diff --git a/__pycache__/app.cpython-312.pyc b/__pycache__/app.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1e4de1c240f2b7bbad4deece499cee9d19c9a987 GIT binary patch literal 79192 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

PZvsIe-z3A#%-Nk!R)>Z96 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%0A9gpAb_Aesx+Hh7Rml`bkQ@F`^&V=jY7irMDY& zI3(;K8^J>^3~AyhxauqWkuBkCE3N|7+87Ss; z1#tWqYft!Vak`+TK;@5m68<%Kxato6U}wTzkAnpzIuiamv4pSe2h#~}6ON&)h2=kL zP86cB7a$ z_kTI0uhSRb+@~+rd%x^Fq1QLuJYX>EJ8tGX^uC*+2le{=n_F{2`i(bxj!>l`gH7La zGvL*G(hYg~Uj5C|eEl=}n{|49*Uemy-j}ZN>$mA|uHCFJ{_?>bGwS7=^!xN*=9Q!U z0eyqM`sM+>OJDP4g;VdoS=yvubMv775vqMG$D^;iS>w>x0x}%dAJuy5f-ki`E zQ~js(R3u0ZJViK&+(KPKUwFq z6~~QO`WZCNDhtkvgue1dPLbYD*;Q$Z0iI>lZ4omuXT;RHXP-*wgEw+q`ckSIf}c5k zDL}eZ_34B@bR*~G9DO0>mZVuU4e9gDj(e~{#f}k6;{qgShZFkp8#zAxCd#fzQw(t1 z=r}u-Fce)iTF=&fXE*)`Ow~~H?0~w_CdzO?_GGP;k+eHs-|*cHuW$bD=J}>&d+k-H zXRhfT!~2hX>Rgl7IjydR-ef`9+}`s~eE*4<{*9;L^v;q0`tI-UPJ~V@JI3&utJ`DS z-W&SS(1#nZv~RuKzBSQ4kf_>rrE1URsy&ISz2sY7tO0P4bXQ+>mtJ*;uDZ*T?$Dg& zyyN?hH}bBy>n^+N67Ghy(_E5wOJ{bvZadNU7a^TBPsn?4+0uK};uP|pUbY;!&H|9`PuPZN7CU+=KHUDim!SKl0~IJo4;`CtOZ}{%vM|aF}==M{JZpt9tbep z&;|7Mw{!fa`dc~#X#*bb+@3N4^nmSbD*FRg$5M1dm!t2~CmrsYesMHcj9Vb9L&@uu zR7dNAJ|5+5?N^K)myI3dpj;0peiQ4l3hXufAq}`MTG(%8lWzXCr6pbI(2{N^&V<8{9TO)@l@lM!e<%{|EV+h z%m&?W3tWfl48N__Q`l%aw9fq7H5L^5ZKwO0I>R-)kwRDAGnIyGl_rWenx5$}U)zv3 VTyFT>Y^2cc7!Dae51A1Ee*i34a8CdL literal 0 HcmV?d00001 From fc44106d850173799b1a1e99152bff7032dce366 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Oct 2025 13:56:30 +0000 Subject: [PATCH 3/7] Add backend seat management and priority queue system Co-authored-by: Terrificdatabytes <66877413+Terrificdatabytes@users.noreply.github.com> --- app.py | 288 ++++++++++++++++++++++++++++++++++++++++++- templates/index.html | 91 +++++++++++++- 2 files changed, 371 insertions(+), 8 deletions(-) diff --git a/app.py b/app.py index 28afcb2..99d9b5d 100644 --- a/app.py +++ b/app.py @@ -197,6 +197,10 @@ def score(self, X, y): authenticated_drivers = {} bus_logged_locations = defaultdict(set) +# Seat management data structures +bus_seats = defaultdict(lambda: {'occupied': 0, 'total': 50, 'bus_number': None}) +priority_queue = defaultdict(lambda: defaultdict(list)) # {route_id: {stop_id: [passenger_ids]}} + # Bidirectional tracking data structures bus_last_passed_stop = defaultdict(lambda: None) bus_direction = defaultdict(lambda: None) @@ -1362,6 +1366,23 @@ def get_routes(): def get_waiting_stats(): return jsonify(dict(waiting_passengers)) +@app.route('/api/priority_queue/') +def get_priority_queue(route_id): + """Get priority queue information for a route""" + priority_data = {} + if route_id in priority_queue: + for stop_id, passengers in priority_queue[route_id].items(): + priority_data[stop_id] = { + 'count': len(passengers), + 'passengers': passengers + } + + return jsonify({ + 'route_id': route_id, + 'priority_queue': priority_data, + 'total_priority': sum(len(p) for p in priority_queue[route_id].values()) if route_id in priority_queue else 0 + }) + @app.route('/api/active_buses/') def get_active_buses(route_id): """Filter out full buses for passengers""" @@ -1385,7 +1406,11 @@ def get_active_buses(route_id): 'current_stop': bus_data.get('current_stop', None), 'is_full': bus_data.get('is_full', False), 'progress_pct': bus_data.get('progress_pct', 0), - 'distance_from_start': bus_data.get('distance_from_start', 0) + 'distance_from_start': bus_data.get('distance_from_start', 0), + 'occupied_seats': bus_data.get('occupied_seats', 0), + 'total_seats': bus_data.get('total_seats', 50), + 'available_seats': bus_data.get('available_seats', 50), + 'bus_number': bus_data.get('bus_number', 'N/A') }) return jsonify({'buses': buses}) @@ -1777,6 +1802,12 @@ def handle_bus_location(data): # Get bus capacity status is_full = bus_capacity_status.get(bus_id, False) + # Get seat information + seat_data = bus_seats[bus_id] + occupied_seats = seat_data['occupied'] + total_seats = seat_data['total'] + bus_number = seat_data.get('bus_number', 'N/A') + # Store bus location with enhanced data with bus_data_lock: active_buses[route_id][bus_id] = { @@ -1797,7 +1828,11 @@ def handle_bus_location(data): 'current_stop': current_stop_name, 'current_stop_id': current_stop_id, 'is_full': is_full, - 'distance_from_start': round(distance_from_start, 3) + 'distance_from_start': round(distance_from_start, 3), + 'occupied_seats': occupied_seats, + 'total_seats': total_seats, + 'available_seats': total_seats - occupied_seats, + 'bus_number': bus_number } # Log location @@ -1847,7 +1882,11 @@ def handle_bus_location(data): 'progress_pct': round(progress_pct, 1), 'current_stop': current_stop_name, 'current_stop_id': current_stop_id, - 'is_full': is_full + 'is_full': is_full, + 'occupied_seats': occupied_seats, + 'total_seats': total_seats, + 'available_seats': total_seats - occupied_seats, + 'bus_number': bus_number }) # Broadcast to passengers (only if bus is not full) @@ -1871,7 +1910,11 @@ def handle_bus_location(data): 'current_stop_id': current_stop_id, 'is_full': is_full, 'progress_pct': round(progress_pct, 1), - 'distance_from_start': round(distance_from_start, 3) + 'distance_from_start': round(distance_from_start, 3), + 'occupied_seats': occupied_seats, + 'total_seats': total_seats, + 'available_seats': total_seats - occupied_seats, + 'bus_number': bus_number }, room=route_id, include_self=False) # Update bus count @@ -1968,6 +2011,243 @@ def handle_passenger_waiting(data): socketio.emit('waiting_stats', dict(waiting_passengers)) +@socketio.on('driver_select_bus') +def handle_driver_select_bus(data): + """Handle bus number selection by driver""" + if request.sid not in authenticated_drivers: + emit('authentication_required', {'message': 'Please authenticate first'}) + return + + bus_id = data.get('bus_id') + bus_number = data.get('bus_number') + route_id = data.get('route_id') + + if not all([bus_id, bus_number, route_id]): + emit('error', {'message': 'Missing required fields'}) + return + + # Store bus number + bus_seats[bus_id]['bus_number'] = bus_number + + # Update active bus data + if route_id in active_buses and bus_id in active_buses[route_id]: + active_buses[route_id][bus_id]['bus_number'] = bus_number + + print(f"✓ Bus {bus_id} assigned number: {bus_number}") + + emit('bus_number_confirmed', { + 'bus_id': bus_id, + 'bus_number': bus_number, + 'message': f'Bus #{bus_number} assigned successfully' + }) + +@socketio.on('update_seat_count') +def handle_update_seat_count(data): + """Handle manual seat count update by driver""" + if request.sid not in authenticated_drivers: + emit('authentication_required', {'message': 'Please authenticate first'}) + return + + bus_id = data.get('bus_id') + route_id = data.get('route_id') + action = data.get('action') # 'increment' or 'decrement' + + if not all([bus_id, route_id, action]): + emit('error', {'message': 'Missing required fields'}) + return + + current_occupied = bus_seats[bus_id]['occupied'] + total_seats = bus_seats[bus_id]['total'] + + if action == 'increment' and current_occupied < total_seats: + bus_seats[bus_id]['occupied'] += 1 + elif action == 'decrement' and current_occupied > 0: + bus_seats[bus_id]['occupied'] -= 1 + + new_occupied = bus_seats[bus_id]['occupied'] + is_full = new_occupied >= total_seats + + # Update capacity status + bus_capacity_status[bus_id] = is_full + + # Update active bus data + if route_id in active_buses and bus_id in active_buses[route_id]: + active_buses[route_id][bus_id]['occupied_seats'] = new_occupied + active_buses[route_id][bus_id]['total_seats'] = total_seats + active_buses[route_id][bus_id]['is_full'] = is_full + + print(f"✓ Bus {bus_id} seats: {new_occupied}/{total_seats}") + + # Emit to driver + emit('seat_count_updated', { + 'bus_id': bus_id, + 'occupied': new_occupied, + 'total': total_seats, + 'is_full': is_full + }) + + # Broadcast to all passengers on route + socketio.emit('bus_seat_status', { + 'route_id': route_id, + 'bus_id': bus_id, + 'occupied': new_occupied, + 'total': total_seats, + 'available': total_seats - new_occupied, + 'is_full': is_full + }, room=route_id) + + # If bus just became full, remove from passenger view + if is_full: + socketio.emit('bus_removed', { + 'route_id': route_id, + 'bus_id': bus_id, + 'reason': 'full' + }, room=route_id) + +@socketio.on('passenger_booking') +def handle_passenger_booking(data): + """Handle passenger seat booking""" + route_id = data.get('route_id') + stop_id = data.get('stop_id') + passenger_id = data.get('passenger_id', request.sid) + bus_id = data.get('bus_id') + + if not all([route_id, stop_id]): + emit('booking_error', {'message': 'Missing required fields'}) + return + + # Find available bus or assign to priority queue + if bus_id: + # Specific bus requested + if bus_id in bus_seats: + current_occupied = bus_seats[bus_id]['occupied'] + total_seats = bus_seats[bus_id]['total'] + + if current_occupied < total_seats: + # Book seat + bus_seats[bus_id]['occupied'] += 1 + emit('booking_confirmed', { + 'bus_id': bus_id, + 'bus_number': bus_seats[bus_id].get('bus_number', 'N/A'), + 'seat_number': current_occupied + 1, + 'status': 'confirmed' + }) + + # Broadcast seat status update + socketio.emit('bus_seat_status', { + 'route_id': route_id, + 'bus_id': bus_id, + 'occupied': bus_seats[bus_id]['occupied'], + 'total': total_seats, + 'available': total_seats - bus_seats[bus_id]['occupied'], + 'is_full': bus_seats[bus_id]['occupied'] >= total_seats + }, room=route_id) + + print(f"✓ Passenger {passenger_id} booked seat on bus {bus_id}") + else: + # Bus full - add to priority queue + priority_queue[route_id][stop_id].append({ + 'passenger_id': passenger_id, + 'timestamp': datetime.now().isoformat() + }) + + emit('booking_priority', { + 'status': 'priority', + 'message': 'Bus is full. You are added to priority queue for next bus.', + 'queue_position': len(priority_queue[route_id][stop_id]) + }) + + print(f"✓ Passenger {passenger_id} added to priority queue for stop {stop_id}") + else: + # No specific bus - find available or add to priority + available_bus = None + + if route_id in active_buses: + for bid, bdata in active_buses[route_id].items(): + if not bus_capacity_status.get(bid, False): + current_occupied = bus_seats[bid]['occupied'] + total_seats = bus_seats[bid]['total'] + + if current_occupied < total_seats: + available_bus = bid + break + + if available_bus: + # Book on available bus + bus_seats[available_bus]['occupied'] += 1 + emit('booking_confirmed', { + 'bus_id': available_bus, + 'bus_number': bus_seats[available_bus].get('bus_number', 'N/A'), + 'seat_number': bus_seats[available_bus]['occupied'], + 'status': 'confirmed' + }) + + # Broadcast update + socketio.emit('bus_seat_status', { + 'route_id': route_id, + 'bus_id': available_bus, + 'occupied': bus_seats[available_bus]['occupied'], + 'total': bus_seats[available_bus]['total'], + 'available': bus_seats[available_bus]['total'] - bus_seats[available_bus]['occupied'], + 'is_full': bus_seats[available_bus]['occupied'] >= bus_seats[available_bus]['total'] + }, room=route_id) + else: + # All buses full - add to priority queue + priority_queue[route_id][stop_id].append({ + 'passenger_id': passenger_id, + 'timestamp': datetime.now().isoformat() + }) + + emit('booking_priority', { + 'status': 'priority', + 'message': 'All buses are full. You are added to priority queue for next bus.', + 'queue_position': len(priority_queue[route_id][stop_id]) + }) + +@socketio.on('get_priority_count') +def handle_get_priority_count(data): + """Get count of priority passengers per stop""" + route_id = data.get('route_id') + + if not route_id: + emit('priority_count', {'count': 0}) + return + + priority_counts = {} + if route_id in priority_queue: + for stop_id, passengers in priority_queue[route_id].items(): + priority_counts[stop_id] = len(passengers) + + emit('priority_count', { + 'route_id': route_id, + 'counts': priority_counts, + 'total': sum(priority_counts.values()) + }) + +@socketio.on('get_seat_status') +def handle_get_seat_status(data): + """Get current seat status for a bus""" + bus_id = data.get('bus_id') + + if not bus_id or bus_id not in bus_seats: + emit('seat_status', { + 'occupied': 0, + 'total': 50, + 'available': 50, + 'is_full': False + }) + return + + seat_data = bus_seats[bus_id] + emit('seat_status', { + 'bus_id': bus_id, + 'bus_number': seat_data.get('bus_number', 'N/A'), + 'occupied': seat_data['occupied'], + 'total': seat_data['total'], + 'available': seat_data['total'] - seat_data['occupied'], + 'is_full': seat_data['occupied'] >= seat_data['total'] + }) + # ==================== MAIN SERVER STARTUP ==================== if __name__ == '__main__': print("=" * 80) diff --git a/templates/index.html b/templates/index.html index 823c49a..10ab3e7 100644 --- a/templates/index.html +++ b/templates/index.html @@ -952,6 +952,48 @@

Select Route

👤 Driver: Not Set

🚌 Bus ID: Waiting...

🛣️ Route:

+

🚍 Bus Number: Not Set

+ + + +
+

Select Bus Number

+
+ + +
+

+ ℹ️ Select your bus number (1, 2, 3, etc.) if multiple buses operate on the same route +

+
+ + +
+

💺 Seat Management

+
+ +
+
Occupied Seats
+
+ 0 / 50 +
+ +
+ +
+

+ ℹ️ Use +/- buttons to update occupied seat count manually +

+ + +
+

👥 Waiting Passengers

+
+

@@ -1068,6 +1116,25 @@

📊 Real-time Statistics