Compare commits
	
		
			4 Commits
		
	
	
		
			main
			...
			update_dep
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| b72704348c | |||
| cdde09eee9 | |||
| ec132b3e7a | |||
| b8f532d5c2 | 
| @ -229,86 +229,3 @@ def get_pit_stops(): | ||||
|         user["vehicles"].append(v) | ||||
| 
 | ||||
|     return render_template("pitstops.html", user=user) | ||||
| 
 | ||||
| 
 | ||||
| @app.route("/pitstops/plan/vehicle/select", methods=["GET", "POST"]) | ||||
| @login_required | ||||
| def select_vehicle_for_plan_pitstop(): | ||||
|     if len(current_user.vehicles) == 1: | ||||
|         return redirect( | ||||
|             url_for( | ||||
|                 "select_consumable_for_plan_pitstop", vid=current_user.vehicles[0].id | ||||
|             ) | ||||
|         ) | ||||
| 
 | ||||
|     form = SelectVehicleForm() | ||||
|     form.vehicle.choices = [(g.id, g.name) for g in current_user.vehicles] | ||||
| 
 | ||||
|     if form.validate_on_submit(): | ||||
|         return redirect( | ||||
|             url_for("select_consumable_for_plan_pitstop", vid=form.vehicle.data) | ||||
|         ) | ||||
| 
 | ||||
|     return render_template("selectVehicle.html", form=form) | ||||
| 
 | ||||
| 
 | ||||
| @app.route( | ||||
|     "/pitstops/plan/vehicle/<int:vid>/consumable/select", methods=["GET", "POST"] | ||||
| ) | ||||
| @login_required | ||||
| def select_consumable_for_plan_pitstop(vid): | ||||
|     vehicle = Vehicle.query.get(vid) | ||||
|     if vehicle is None or vehicle not in current_user.vehicles: | ||||
|         return redirect(url_for("select_consumable_for_plan_pitstop")) | ||||
| 
 | ||||
|     if len(vehicle.consumables) == 0: | ||||
|         flash("Please choose at least one consumable!", "warning") | ||||
|         return redirect(url_for("edit_vehicle", vid=vid)) | ||||
| 
 | ||||
|     if len(vehicle.consumables) == 1: | ||||
|         return redirect( | ||||
|             url_for("plan_pit_stop_form", vid=vid, cid=vehicle.consumables[0].id) | ||||
|         ) | ||||
| 
 | ||||
|     form = SelectConsumableForm() | ||||
|     form.consumable.choices = [(g.id, g.name) for g in vehicle.consumables] | ||||
| 
 | ||||
|     if form.validate_on_submit(): | ||||
|         return redirect( | ||||
|             url_for("plan_pit_stop_form", vid=vid, cid=form.consumable.data) | ||||
|         ) | ||||
| 
 | ||||
|     return render_template( | ||||
|         "selectConsumableForVehicle.html", vehicle=vehicle, form=form | ||||
|     ) | ||||
| 
 | ||||
| 
 | ||||
| @app.route( | ||||
|     "/pitstops/plan/vehicle/<int:vid>/consumable/<int:cid>", methods=["GET", "POST"] | ||||
| ) | ||||
| @login_required | ||||
| def plan_pit_stop_form(vid, cid): | ||||
|     vehicle = Vehicle.query.get(vid) | ||||
|     if vehicle is None or vehicle not in current_user.vehicles: | ||||
|         return redirect(url_for("select_vehicle_for_new_pitstop")) | ||||
| 
 | ||||
|     consumable = Consumable.query.get(cid) | ||||
|     if consumable not in vehicle.consumables: | ||||
|         return redirect(url_for("select_consumable_for_new_pitstop", vid=vid)) | ||||
| 
 | ||||
|     update_filling_station_prices( | ||||
|         [x.id for x in current_user.favourite_filling_stations] | ||||
|     ) | ||||
| 
 | ||||
|     offers = [] | ||||
|     for fs in current_user.favourite_filling_stations: | ||||
|         offers.append( | ||||
|             ( | ||||
|                 fs, | ||||
|                 getattr(fs, consumable.ext_id), | ||||
|             ) | ||||
|         ) | ||||
| 
 | ||||
|     return render_template( | ||||
|         "planPitStopForm.html", vehicle=vehicle, consumable=consumable, offers=offers | ||||
|     ) | ||||
|  | ||||
| @ -1,184 +0,0 @@ | ||||
| // initially display germany
 | ||||
| var lat = 50.75653081787912, | ||||
|     lon = 9.262980794432847, | ||||
|     zoom = 5; | ||||
| 
 | ||||
| var map; | ||||
| 
 | ||||
| var filling_stations = {}; | ||||
| var filling_station_markers; | ||||
| 
 | ||||
| query_location = function(updater) { | ||||
|     if(navigator.geolocation) { | ||||
|         navigator.geolocation.getCurrentPosition(function(position) { | ||||
|             lat = position.coords.latitude; | ||||
|             lon = position.coords.longitude; | ||||
|             zoom = 11; | ||||
|             if(updater){ | ||||
|                 updater(lat, lon); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| update_map = function() { | ||||
|     var lonLat = new OpenLayers.LonLat( lon, lat ) | ||||
|         .transform( | ||||
|             new OpenLayers.Projection("EPSG:4326"), // transform from WGS 1984
 | ||||
|             map.getProjectionObject() // to Spherical Mercator Projection
 | ||||
|         ); | ||||
|     map.setCenter (lonLat, zoom); | ||||
| } | ||||
| 
 | ||||
| load_filling_stations = function() { | ||||
|     var url = '/filling_stations?latitude=' + lat + '&longitude='+ lon + '&type=all&radius=5&sort=dist'; | ||||
|     $.ajax({ | ||||
|         type: 'GET', | ||||
|         url: url, | ||||
|         success: function(data) { | ||||
|             data.stations.forEach(function(station) { | ||||
|                 if (!(station.id in filling_stations)) { | ||||
|                     filling_stations[station.id] = station; | ||||
|                     filling_stations[station.id].marker = false; | ||||
|                 } | ||||
|             }); | ||||
|             update_filling_station_markers(); | ||||
|         } | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| clicked_on_filling_station_marker = function(station, marker) { | ||||
|     return function(data) { | ||||
|         $.ajax({ | ||||
|             type: 'GET', | ||||
|             url: '/filling_stations/favourites/toggle/'+station.id, | ||||
|             dataType: 'json', | ||||
|             timeout: 1000, | ||||
|             success: function(data) { | ||||
|                 if (data.state == 'favourite') { | ||||
|                     marker.setUrl('/static/img/filling_station_favourite_marker.png'); | ||||
|                 } else { | ||||
|                     marker.setUrl('/static/img/filling_station_marker.png'); | ||||
|                 } | ||||
|             }, | ||||
|             contentType : 'application/json' | ||||
|         }); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| display_station_information = function(station) { | ||||
|     return function(event) { | ||||
|         var info = $('#station_info'); | ||||
|         info.empty(); | ||||
|         info.addClass('filling_station_info'); | ||||
| 
 | ||||
|         var cell1 = $('<div>', {'class':'col-md-8'}) | ||||
|         var cell2 = $('<div>', {'class':'col-md-4'}) | ||||
| 
 | ||||
|         var img = $('<img>', {'src': '/static/logos/'+station.brand.toLowerCase()+'.png'}); | ||||
|         // hide if the brand icon loads with error
 | ||||
|         img.error(function(){ | ||||
|             $(this).hide(); | ||||
|         }); | ||||
| 
 | ||||
|         var name = $('<div>').text(station.name); | ||||
| 
 | ||||
|         var street_number = $('<div>').text(station.street + ' ' + station.houseNumber); | ||||
| 
 | ||||
|         var postcode_place = $('<div>').text(station.postCode + ' ' + station.place); | ||||
| 
 | ||||
|         info.append(cell1 | ||||
|                 .append(name) | ||||
|                 .append(street_number) | ||||
|                 .append(postcode_place)) | ||||
|             .append(cell2 | ||||
|                 .append(img)); | ||||
| 
 | ||||
|         cell2.height(cell1.height()); | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| update_filling_station_markers = function() { | ||||
|     for(id in filling_stations) { | ||||
|         var station = filling_stations[id]; | ||||
|         if(!station.marker) { | ||||
|             var lonLat = new OpenLayers.LonLat(station.lng, station.lat) | ||||
|                             .transform(new OpenLayers.Projection('EPSG:4326'), map.getProjectionObject()); | ||||
|             if (station.state == 'favourite') { | ||||
|                 var icon = new OpenLayers.Icon('/static/img/filling_station_favourite_marker.png'); | ||||
|             } else { | ||||
|                 var icon = new OpenLayers.Icon('/static/img/filling_station_marker.png'); | ||||
|             } | ||||
| 			var marker = new OpenLayers.Marker(lonLat, icon); | ||||
| 			marker.events.register('click', marker, clicked_on_filling_station_marker(station, marker)); | ||||
| 			marker.events.register('mouseover', null, display_station_information(station)); | ||||
| 			filling_station_markers.addMarker(marker); | ||||
|             station.marker = true; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| activate_map = function(map_div_id, button_ids, home_lat, home_long, home_zoom, init_stations) { | ||||
| 
 | ||||
|     // resize to reasonable height
 | ||||
|     $('#' + map_div_id).css('height',0.75*($('#' + map_div_id).css('width'))); | ||||
| 
 | ||||
|     // init map
 | ||||
|     map = new OpenLayers.Map(map_div_id); | ||||
|     map.addLayer(new OpenLayers.Layer.OSM()); | ||||
|     map.events.register('moveend', null, function(e){ | ||||
|         var p = e.object.center.clone(); | ||||
|         var p = p.transform(map.getProjectionObject(), 'EPSG:4326'); | ||||
|         lon = p.lon; | ||||
|         lat = p.lat; | ||||
|         zoom = e.object.zoom; | ||||
|     }); | ||||
|     filling_station_markers = new OpenLayers.Layer.Markers('Filling Stations'); | ||||
|     map.addLayer(filling_station_markers); | ||||
| 
 | ||||
|     // handle initial / favourite stations
 | ||||
|     filling_stations = init_stations; | ||||
|     update_filling_station_markers(); | ||||
| 
 | ||||
|     update_map(); | ||||
|     if ((home_lat == 0) && (home_long == 0)) { | ||||
|         query_location(update_map); | ||||
|     } else  { | ||||
|         lat = home_lat; | ||||
|         lon = home_long; | ||||
|         zoom = home_zoom; | ||||
|         update_map(); | ||||
|     } | ||||
| 
 | ||||
|     // get button
 | ||||
|     $('#'+button_ids[0]).click(function(e){ | ||||
|         load_filling_stations(); | ||||
|     }); | ||||
|     // set home button
 | ||||
|     $('#'+button_ids[1]).click(function(e){ | ||||
|         $.ajax({ | ||||
|             type: 'POST', | ||||
|             url: '/account/home', | ||||
|             data: JSON.stringify({'long': lon, 'lat': lat, 'zoom': zoom}), | ||||
|             dataType: 'json', | ||||
|             timeout: 1000, | ||||
|             contentType : 'application/json' | ||||
|         }); | ||||
|     }); | ||||
|     // go home button
 | ||||
|     $('#'+button_ids[2]).click(function(e){ | ||||
|         $.ajax({ | ||||
|             type: 'GET', | ||||
|             url: '/account/home', | ||||
|             dataType: 'json', | ||||
|             timeout: 1000, | ||||
|             success: function(data) { | ||||
|                 lat = data.lat; | ||||
|                 lon = data.long; | ||||
|                 zoom = data.zoom; | ||||
|                 update_map(); | ||||
|             }, | ||||
|             contentType : 'application/json' | ||||
|         }); | ||||
|     }); | ||||
| } | ||||
| @ -66,32 +66,6 @@ | ||||
|             </tbody> | ||||
|         </table> | ||||
|     </div> | ||||
|     <div class="panel panel-default"> | ||||
|         <div class="panel-heading">Filling Stations</div> | ||||
|         <div class="panel-body"> | ||||
|             <div class="row"> | ||||
|                 <div class="col-md-6 olMap" style="height: 400px" id="mapdiv"></div> | ||||
|                 <div class="col-md-6"> | ||||
|                     <div class="row"> | ||||
|                         <div class="btn-group col-md-12" role="group"> | ||||
|                             <button type="button" class="btn btn-default glyphicon glyphicon-home" id="go_home_button" title="go to home location"/> | ||||
|                             <button type="button" class="btn btn-default glyphicon glyphicon-screenshot " id="set_home_button" title="set home location"/> | ||||
|                             <button type="button" class="btn btn-default glyphicon glyphicon-download" id="get_button" title="load fuel stations"/> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                     <div id="station_info" class="row"> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
|     <script> | ||||
|         var lat = {{ map_pos[0] or 0 }}; | ||||
|         var long = {{ map_pos[1] or 0 }}; | ||||
|         var zoom = {{ map_pos[2] or 0 }}; | ||||
|         var init_filling_station = JSON.parse({{ fs|tojson }}); | ||||
|         activate_map('mapdiv', ['get_button', 'set_home_button', 'go_home_button'], lat, long, zoom, init_filling_station); | ||||
|     </script> | ||||
|     </div> | ||||
|     <div class="panel panel-default"> | ||||
|         <div class="panel-heading">Account</div> | ||||
|         <div class="panel-body"> | ||||
|  | ||||
| @ -5,7 +5,6 @@ | ||||
| 		<li><a id='new_service_link' href='{{ url_for('select_vehicle_for_new_regular_cost') }}'>Create Regular Cost</a></li> | ||||
| 		<li><a id='statistics_limk' href='{{ url_for('get_statistics') }}'>Statistics</a></li> | ||||
| 		<li><a id='account_link' href='{{ url_for('get_account_page') }}'>Account</a></li> | ||||
| 		<li><a id='plan_pitstop_link' href='{{ url_for('select_vehicle_for_plan_pitstop') }}'>Plan Pitstop</a></li> | ||||
| 		{% if current_user.has_role('admin') %} | ||||
| 			<li><a id='admin_link' href='{{ url_for('get_admin_page') }}'>Admin</a></li> | ||||
| 		{% endif %} | ||||
| @ -136,7 +135,6 @@ | ||||
| 		<script src="https://www.amcharts.com/lib/3/themes/patterns.js"></script> | ||||
| 		<script src="https://openlayers.org/api/OpenLayers.js"></script> | ||||
| 		<script src="{{ url_for('static', filename='js/main.js') }}"></script> | ||||
| 		<script src="{{ url_for('static', filename='js/fillingstations.js') }}"></script> | ||||
|     </head> | ||||
|     <body> | ||||
| 	    <nav class="navbar navbar-inverse navbar-fixed-top"> | ||||
|  | ||||
| @ -1,57 +0,0 @@ | ||||
| {% extends "layout.html" %} | ||||
| 
 | ||||
| {% block body %} | ||||
| <div class="col-md-2" ></div> | ||||
| <div class="col-md-8"> | ||||
|     <div class="panel panel-default"> | ||||
|         <div class="panel-body"> | ||||
|             <h3>Plan Pitstop for '{{ vehicle.name }}'</h3> | ||||
|             Price comparision for {{ consumable.name }}: | ||||
|             <div class="table-responsive"> | ||||
|                 <table id="compare" class="table table-striped table-bordered table-condensed tablesorter"> | ||||
|                     <thead> | ||||
|                         <tr> | ||||
|                             <th>Filling Station</th> | ||||
|                             <th>Price/{{ consumable.unit }}</th> | ||||
|                         </tr> | ||||
|                     </thead> | ||||
|                     <tbody> | ||||
|                         {% for offer in offers %} | ||||
|                             <tr> | ||||
|                                 <td> | ||||
|                                     <div class="row filling_station_info " style="border: 0px"> | ||||
|                                         <div class="col-md-8"> | ||||
|                                             <div>{{ offer[0].name }}</div> | ||||
|                                             <div>{{ offer[0].street }} {{ offer[0].houseNumber }}</div> | ||||
|                                             <div>{{ offer[0].postCode }} {{ offer[0].place }}</div> | ||||
|                                         </div> | ||||
|                                         <div class="col-md-4" style="height: 60px;"> | ||||
|                                             <img src="/static/logos/{{ offer[0].brand|lower }}.png"> | ||||
|                                         </div> | ||||
|                                     </div> | ||||
|                                 </td> | ||||
|                                 <td> | ||||
|                                     {% if offer[0].open %} | ||||
|                                         {{ offer[1] }} €/{{ consumable.unit }} | ||||
|                                     {% else %} | ||||
|                                         Closed | ||||
|                                     {% endif %} | ||||
|                                 </td> | ||||
|                             </tr> | ||||
|                         {% endfor %} | ||||
|                     </tbody> | ||||
|                 </table> | ||||
|             </div> | ||||
|         </div> | ||||
|     </div> | ||||
| </div> | ||||
| <script> | ||||
|     $(document).ready(function() { | ||||
|         $("#compare").tablesorter({sortList: [[1,0]]}); | ||||
|         $("img").error(function(){ | ||||
|             $(this).hide(); | ||||
|         }); | ||||
|     }); | ||||
| </script> | ||||
| <div class="col-md-2" ></div> | ||||
| {% endblock %} | ||||
| @ -1,13 +1,13 @@ | ||||
| Flask==2.1.2 | ||||
| Flask-SQLAlchemy==2.5.1 | ||||
| Flask==3.0.3 | ||||
| Flask-SQLAlchemy==3.1.1 | ||||
| Flask-Security==3.0.0 | ||||
| Flask-WTF==1.0.1 | ||||
| PyMySQL==1.0.2 | ||||
| Flask-WTF==1.2.1 | ||||
| PyMySQL==1.1.1 | ||||
| markdown | ||||
| Flask-Limiter==2.4.5.1 | ||||
| requests==2.27.1 | ||||
| email-validator==1.2.1 | ||||
| gunicorn==20.1.0 | ||||
| pytz==2022.1 | ||||
| SQLAlchemy==1.4.36 | ||||
| Werkzeug==2.2.2 | ||||
| Flask-Limiter==3.7.0 | ||||
| requests==2.32.2 | ||||
| email-validator==2.1.1 | ||||
| gunicorn==22.0.0 | ||||
| pytz==2024.1 | ||||
| SQLAlchemy==2.0.30 | ||||
| Werkzeug==3.0.3 | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user