Skip to content
Snippets Groups Projects
Commit c3788fbb authored by Markus Willman's avatar Markus Willman
Browse files

Merge branch 'master' into 'deploy'

Last set of map related fixes

See merge request Smart_Bus_Stop/frontend-server!33
parents 5eaba9aa 5760af14
No related branches found
No related tags found
No related merge requests found
......@@ -70,7 +70,8 @@ def getViewData(request, stopId, view):
return {
'arrivals': gtfs.getNextTrips(stopId, limit = 2, routeType = GtfsConstants.ROUTE_HEAD),
'gmaps_key': GOOGLE_MAPS_KEY if not app.config['DEBUG'] else GOOGLE_MAPS_TEST_KEY,
'gmaps_region': GOOGLE_MAPS_REGION
'gmaps_region': GOOGLE_MAPS_REGION,
'service_status': { 'active': not locator.isStale() }
}
return {}
......@@ -307,6 +308,8 @@ def apiLocatorService(version, type = 'routed'):
lastModified = data = None
if g.stop_id == 'raw' or not g.stop_id:
lastModified, data = locator.getLastResponse()
elif g.stop_id == 'status':
return jsonify({ 'active': not locator.isStale() })
elif type == 'routed':
lastModified, data = gtfs.locateRoutedVehicles(g.stop_id)
elif type == 'nearby':
......@@ -346,7 +349,10 @@ def apiBusInfo(version, busId = None, getShape = None):
data["shapes"] = gtfs.getTripShapes(data.get('lineref', None), data.get('blockref', None))
if data:
return jsonify(data)
response = jsonify(data)
response.last_modified = lastModified
response.expires = lastModified + timedelta(seconds = 2)
return response.make_conditional(request)
abort(404)
......
# coding=utf-8
import requests, threading, time, json, six, math
from datetime import datetime
from requests.exceptions import ConnectionError, HTTPError, Timeout, RequestException
# This really should be written using multiprocessing instead,
# because of the GIL, but setting up full 2-way communication
......@@ -18,6 +20,7 @@ class PollingThreadReader(object):
_running = False
_response = None
_modified = datetime.utcfromtimestamp(0)
_stale = False
def __init__(self, endpointURI, userAgent, pollFreq = 3):
self.endpoint = endpointURI
......@@ -52,16 +55,33 @@ class PollingThreadReader(object):
def run(self):
while self._running:
response = requests.get(self.endpoint, headers = self.requestHeaders).content
apiResponse = None
# FIXME: better exception handling
try:
apiResponse = requests.get(self.endpoint, headers = self.requestHeaders).content
except (ConnectionError, HTTPError, Timeout):
self._stale = True
time.sleep(self.pollTime)
continue
except RequestException:
self._stale = True
continue
with self._lock:
try:
self._response = json.loads(response)
self._response = json.loads(apiResponse)
self._modified = datetime.utcnow()
self._stale = False
except ValueError:
pass
time.sleep(self.pollTime)
def isStale(self):
# not thread safe, only usable as a suggestion that the response may be stale
return self._stale
def getLastResponse(self):
with self._lock:
return (self._modified, self._response)
......
......@@ -50,6 +50,15 @@
</div>
</div>
{% if not service_status.active %}
<div class="alert alert-info alert-dismissible box-shadow text-center show" role="alert">
{{ _("The location service is currently not active, the map may show outdated information.") }}
<!-- <button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button> -->
</div>
{% endif %}
<!-- draw the map -->
<div class="card border-foli box-shadow">
<div class="card-body p-0">
......@@ -268,7 +277,9 @@
busTrackingLoop("all");
}
);
).fail(function() {
console.log('unable to start tracking vehicles, service unavailable');
});
};
var drawAllBuses = function() {
......@@ -278,8 +289,10 @@
$.getJSON("{{ url_for('apiLocatorService', version = 1, stopId = stop_info.stop_id, type = 'nearby', _external = True) }}",
function (data) {
// poor man's locking
if (trackingLoop === null)
if (trackingLoop === null) {
completeMapUpdate();
return;
}
// temporarily move all markers to a temp list
// one by one all active markers will be moved back to the markers list
......@@ -310,7 +323,9 @@
completeMapUpdate();
}
)
).fail(function() {
completeMapUpdate();
});
};
var initOneBusTracking = function() {
......@@ -339,8 +354,9 @@
{ bus_id: requestFocus, get_shape: 1 },
function (data) {
// poor man's locking (the A in Ajax is for Asynchronous :))
if (requestFocus !== focusedMarker)
if (requestFocus !== focusedMarker) {
return;
}
focusedBus = data;
console.log("found this bus info: ", focusedBus);
......@@ -364,9 +380,6 @@
});
updateInfoWindow(true);
},
'json'
);
marker = gmarkers[focusedMarker];
gmarkers = {};
......@@ -376,6 +389,12 @@
// gmap.setZoom(mapZoom + 1); Föli provided shapes do not line up well enough with Google map tiles to make this a good experience if zoomed
busTrackingLoop("one");
},
'json'
).fail(function() {
console.log('lost track of the bus, going back to normal mode');
mapClicked();
});
};
var drawOneBus = function() {
......@@ -388,8 +407,10 @@
{ bus_id: requestFocus, get_shape: 0 },
function (data) {
// poor man's locking
if (trackingLoop === null || requestFocus !== focusedMarker)
if (trackingLoop === null || requestFocus !== focusedMarker) {
completeMapUpdate();
return;
}
// if the focused bus disappeared from the list, just go back to the 'all' mode
if ($.isEmptyObject(data) || gmarkers[focusedMarker] === undefined) {
......@@ -411,7 +432,12 @@
completeMapUpdate();
},
'json'
)
).fail(function() {
console.log('lost track of the bus, going back to normal mode');
mapClicked();
completeMapUpdate();
});
};
// creates or updates the info window for focused bus
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment