adds functionality to handle favourit filling stations

This commit is contained in:
Joachim Lusiardi 2017-11-10 10:38:15 +01:00
parent 8a99e4a616
commit eaacd3f42e
5 changed files with 173 additions and 60 deletions

View File

@ -10,6 +10,11 @@ vehicles_consumables = db.Table('vehicles_consumables',
db.Column('consumable_id', db.Integer(), db.ForeignKey('consumable.id'))) db.Column('consumable_id', db.Integer(), db.ForeignKey('consumable.id')))
users_fillingstations = db.Table('users_fillingstations',
db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
db.Column('fillingstation_id', db.Integer(), db.ForeignKey('filling_station.int_id')))
class Role(db.Model, RoleMixin): class Role(db.Model, RoleMixin):
""" """
Entity to handle different roles for users: Typically user and admin exist Entity to handle different roles for users: Typically user and admin exist
@ -46,6 +51,10 @@ class User(db.Model, UserMixin):
secondary=roles_users, secondary=roles_users,
backref=db.backref('users', lazy='dynamic') backref=db.backref('users', lazy='dynamic')
) )
favourite_filling_stations = db.relationship(
'FillingStation',
secondary=users_fillingstations
)
def __repr__(self): def __repr__(self):
return '<User id="%r" email="%r" ' % (self.id, self.email) return '<User id="%r" email="%r" ' % (self.id, self.email)
@ -166,3 +175,27 @@ class Service(db.Model):
def __repr__(self): def __repr__(self):
return '<Service odometer="%r" date="%r" vehicle_id="%r" costs="%r" description="%r">' % \ return '<Service odometer="%r" date="%r" vehicle_id="%r" costs="%r" description="%r">' % \
(self.odometer, self.date, self.vehicle_id, self.costs, self.description) (self.odometer, self.date, self.vehicle_id, self.costs, self.description)
class FillingStation(db.Model):
int_id = db.Column(db.Integer, primary_key=True)
id = db.Column(db.String(40), unique=True, nullable=False)
name = db.Column(db.Text(), nullable=False)
street = db.Column(db.Text(), nullable=False)
place = db.Column(db.Text(), nullable=False)
houseNumber = db.Column(db.Text())
postCode = db.Column(db.Integer(), nullable=False)
brand = db.Column(db.Text(), nullable=False)
lat = db.Column(db.Numeric(2, 5), nullable=False)
lng = db.Column(db.Numeric(2, 5), nullable=False)
def as_dict(self):
res = {}
for c in self.__table__.columns:
val = getattr(self, c.name)
import decimal
if isinstance(val, decimal.Decimal):
val = float(val)
val = str(val)
res[c.name] = val
return res

View File

@ -3,8 +3,9 @@ from flask_security import login_required
from flask_security.core import current_user from flask_security.core import current_user
from sqlalchemy.exc import IntegrityError from sqlalchemy.exc import IntegrityError
import requests import requests
import json
from ..entities import Vehicle, Consumable from ..entities import Vehicle, Consumable, FillingStation
from ..forms import EditVehicleForm, DeleteVehicleForm, DeleteAccountForm from ..forms import EditVehicleForm, DeleteVehicleForm, DeleteAccountForm
from ..tools import db_log_update, db_log_delete, db_log_add from ..tools import db_log_update, db_log_delete, db_log_add
from .. import app, db, user_datastore, limiter from .. import app, db, user_datastore, limiter
@ -13,9 +14,12 @@ from .. import app, db, user_datastore, limiter
@app.route('/account', methods=['GET']) @app.route('/account', methods=['GET'])
@login_required @login_required
def get_account_page(): def get_account_page():
print(current_user.home_lat, current_user.home_long) stations = [x.as_dict() for x in current_user.favourite_filling_stations]
for station in stations:
station['state'] = 'favourite'
return render_template('account.html', return render_template('account.html',
map_pos=(current_user.home_lat, current_user.home_long, current_user.home_zoom)) map_pos=(current_user.home_lat, current_user.home_long, current_user.home_zoom),
fs=json.dumps(stations))
@app.route('/account/vehicle/edit/<int:vid>', methods=['GET', 'POST']) @app.route('/account/vehicle/edit/<int:vid>', methods=['GET', 'POST'])
@ -147,7 +151,29 @@ def set_users_home():
current_user.home_long = request.json['long'] current_user.home_long = request.json['long']
current_user.home_zoom = request.json['zoom'] current_user.home_zoom = request.json['zoom']
db.session.commit() db.session.commit()
return jsonify({'lat': float(current_user.home_lat)}) return jsonify({})
@app.route('/filling_stations/update')
def update_filling_stations():
print(FillingStation.query.all())
return jsonify({})
@app.route('/filling_stations/favourites/toggle/<fsid>')
def add_favourite_filling_stations(fsid):
favourite_ids = {x.id:x for x in current_user.favourite_filling_stations}
print(favourite_ids)
if fsid in favourite_ids:
current_user.favourite_filling_stations.remove(favourite_ids[fsid])
state = 'normal'
else:
fs = FillingStation.query.filter(FillingStation.id == fsid).first()
current_user.favourite_filling_stations.append(fs)
state = 'favourite'
db.session.commit()
return jsonify({'state':state})
@app.route('/filling_stations', methods=['GET']) @app.route('/filling_stations', methods=['GET'])
@ -167,8 +193,27 @@ def query_filling_stations():
'lat': latitude, 'lng': longitude, 'rad': radius, 'apikey': api_key, 'type': type, 'sort': sort 'lat': latitude, 'lng': longitude, 'rad': radius, 'apikey': api_key, 'type': type, 'sort': sort
} }
response = requests.get(url, params=params) response = requests.get(url, params=params)
print(response.url) data = response.json()
return jsonify(response.json()) for station in data['stations']:
fs = FillingStation.query.filter(FillingStation.id == station['id']).first()
if not fs:
fs = FillingStation()
fs.id = station['id']
fs.brand = station['brand']
fs.lat = station['lat']
fs.lng = station['lng']
fs.name = station['name']
fs.street = station['street']
fs.place = station['place']
fs.houseNumber = station['houseNumber']
fs.postCode = station['postCode']
db.session.add(fs)
if fs in current_user.favourite_filling_stations:
station['state'] = 'favourite'
else:
station['state'] = 'normal'
db.session.commit()
return jsonify(data)
@app.route('/filling_stations/<fsid>', methods=['GET']) @app.route('/filling_stations/<fsid>', methods=['GET'])

View File

@ -27,7 +27,6 @@ update_map = function() {
map.getProjectionObject() // to Spherical Mercator Projection map.getProjectionObject() // to Spherical Mercator Projection
); );
map.setCenter (lonLat, zoom); map.setCenter (lonLat, zoom);
//load_filling_stations();
} }
load_filling_stations = function() { load_filling_stations = function() {
@ -47,36 +46,57 @@ load_filling_stations = function() {
}); });
} }
clicked_on_filling_station_marker = function(station) { clicked_on_filling_station_marker = function(station, marker) {
return function() { return function(data) {
console.log(station) console.log(station);
/* console.log(marker);
var desc = '<div>'+ $.ajax({
'<div class="row">' + type: 'GET',
'<div class="col-md-6" style="text-align: left;">' + station.brand + '</div>' + url: '/filling_stations/favourites/toggle/'+station.id,
'<div class="col-md-3" style="text-align: left;">Super:</div>' + dataType: 'json',
'<div class="col-md-3" style="text-align: left;">'+ station.e5 + '€</div>' + timeout: 1000,
'</div>' + success: function(data) {
'<div class="row">' + console.log(data);
'<div class="col-md-6" style="text-align: left;">' + station.name + '</div>' + if (data.state == 'favourite') {
'<div class="col-md-3" style="text-align: left;">Super E10:</div>' + marker.setUrl('/static/filling_station_favourite_marker.png');
'<div class="col-md-3" style="text-align: left;">'+ station.e10 + '€</div>' + } else {
'</div>' + marker.setUrl('/static/filling_station_marker.png');
'<div class="row">' +
'<div class="col-md-6" style="text-align: left;">' + station.street + ' ' + station.houseNumber + '</div>' +
'<div class="col-md-3" style="text-align: left;">Diesel:</div>' +
'<div class="col-md-3" style="text-align: left;">'+ station.diesel + '€</div>' +
'</div>' +
'<div class="row">' +
'<div class="col-md-6" style="text-align: left;">' + station.postCode + ' ' + station.place + '</div>' +
'<div class="col-md-3" style="text-align: left;">Open:</div>' +
'<div class="col-md-3" style="text-align: left;">'+ station.isOpen + '€</div>' +
'</div>' +
'</div>';
$('#station_info').empty();
$('#station_info').html(desc);
*/
} }
},
contentType : 'application/json'
});
}
}
display_station_information = function(station) {
return function(event) {
console.log(station);
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'});
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));
console.log(cell1.height())
cell2.height(cell1.height());
};
} }
update_filling_station_markers = function() { update_filling_station_markers = function() {
@ -86,15 +106,23 @@ update_filling_station_markers = function() {
console.log(station.id); console.log(station.id);
var lonLat = new OpenLayers.LonLat(station.lng, station.lat) var lonLat = new OpenLayers.LonLat(station.lng, station.lat)
.transform(new OpenLayers.Projection('EPSG:4326'), map.getProjectionObject()); .transform(new OpenLayers.Projection('EPSG:4326'), map.getProjectionObject());
var marker = new OpenLayers.Marker(lonLat); if (station.state == 'favourite') {
marker.events.register('click', marker, clicked_on_filling_station_marker(station)); var icon = new OpenLayers.Icon('/static/filling_station_favourite_marker.png');
} else {
var icon = new OpenLayers.Icon('/static/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));
marker.events.register('mouseout', null, function(e){console.log('out');});
filling_station_markers.addMarker(marker); filling_station_markers.addMarker(marker);
station.marker = true; station.marker = true;
} }
} }
} }
activate_map = function(map_div_id, button_ids, home_lat, home_long, home_zoom) { activate_map = function(map_div_id, button_ids, home_lat, home_long, home_zoom, init_stations) {
// resize to reasonable height // resize to reasonable height
$('#' + map_div_id).css('height',0.75*($('#' + map_div_id).css('width'))); $('#' + map_div_id).css('height',0.75*($('#' + map_div_id).css('width')));
@ -110,6 +138,11 @@ activate_map = function(map_div_id, button_ids, home_lat, home_long, home_zoom)
}); });
filling_station_markers = new OpenLayers.Layer.Markers('Filling Stations'); filling_station_markers = new OpenLayers.Layer.Markers('Filling Stations');
map.addLayer(filling_station_markers); map.addLayer(filling_station_markers);
// handle initial / favourite stations
filling_stations = init_stations;
update_filling_station_markers();
update_map(); update_map();
if ((home_lat == 0) && (home_long == 0)) { if ((home_lat == 0) && (home_long == 0)) {
query_location(update_map); query_location(update_map);
@ -129,9 +162,6 @@ activate_map = function(map_div_id, button_ids, home_lat, home_long, home_zoom)
// set home button // set home button
$('#'+button_ids[1]).click(function(e){ $('#'+button_ids[1]).click(function(e){
console.log('clicked set home'); console.log('clicked set home');
console.log(lon);
console.log(lat);
console.log(zoom);
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
url: '/account/home', url: '/account/home',

View File

@ -93,3 +93,13 @@ and (max-device-width : 568px) {
display:none; display:none;
} }
} }
.filling_station_info {
margin: 5px;
border: 1px solid;
}
.filling_station_info img{
margin-top: 6px;
height:48px;
}

View File

@ -69,20 +69,14 @@
<div class="row"> <div class="row">
<div class="col-md-6 olMap" style="height: 400px" id="mapdiv"></div> <div class="col-md-6 olMap" style="height: 400px" id="mapdiv"></div>
<div class="col-md-6"> <div class="col-md-6">
<div class="btn-group" role="group"> <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" /> <button type="button" class="btn btn-default glyphicon glyphicon-home" id="go_home_button" />
<button type="button" class="btn btn-default glyphicon glyphicon-screenshot " id="set_home_button" /> <button type="button" class="btn btn-default glyphicon glyphicon-screenshot " id="set_home_button" />
<button type="button" class="btn btn-default glyphicon glyphicon-download" id="get_button" /> <button type="button" class="btn btn-default glyphicon glyphicon-download" id="get_button" />
</div> </div>
<table class="table"> </div>
<thead> <div id="station_info" class="row">
<tr>
<th>Station</th><th></th>
</tr>
</thead>
</table>
<div id="station_info">
</div> </div>
</div> </div>
</div> </div>
@ -91,7 +85,8 @@
var lat = {{ map_pos[0] }}; var lat = {{ map_pos[0] }};
var long = {{ map_pos[1] }}; var long = {{ map_pos[1] }};
var zoom = {{ map_pos[2] }}; var zoom = {{ map_pos[2] }};
activate_map('mapdiv', ['get_button', 'set_home_button', 'go_home_button'], lat, long, zoom); 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> </script>
</div> </div>
<div class="panel panel-default"> <div class="panel panel-default">