Commit 24f55cdeded6e35233d91c47760c2076468ec33d

Authored by Antoine Goutenoir
1 parent 4392f295
Exists in master

Geocode destinations.

Showing 1 changed file with 61 additions and 7 deletions   Show diff stats
flaskr/controllers/main_controller.py
@@ -2,10 +2,14 @@ from flask import Blueprint, render_template, flash, request, redirect, url_for @@ -2,10 +2,14 @@ from flask import Blueprint, render_template, flash, request, redirect, url_for
2 2
3 from flaskr.extensions import cache 3 from flaskr.extensions import cache
4 from flaskr.forms import LoginForm, EstimateForm 4 from flaskr.forms import LoginForm, EstimateForm
5 -from flaskr.models import db, User, Estimation 5 +from flaskr.models import db, User, Estimation, StatusEnum
  6 +from flaskr.geocoder import CachedGeocoder
6 7
7 from flaskr.core import generate_unique_id 8 from flaskr.core import generate_unique_id
8 9
  10 +import sqlalchemy
  11 +import geopy
  12 +
9 main = Blueprint('main', __name__) 13 main = Blueprint('main', __name__)
10 14
11 15
@@ -27,10 +31,10 @@ def estimate(): @@ -27,10 +31,10 @@ def estimate():
27 estimation.email = form.email.data 31 estimation.email = form.email.data
28 estimation.first_name = form.first_name.data 32 estimation.first_name = form.first_name.data
29 estimation.last_name = form.last_name.data 33 estimation.last_name = form.last_name.data
30 - estimation.status = 'pending'  
31 - estimation.origin_addresses = form.origin_addresses  
32 - estimation.destination_addresses = form.destination_addresses  
33 - estimation.compute_optimal_destination = form.compute_optimal_destination 34 + estimation.status = StatusEnum.pending
  35 + estimation.origin_addresses = form.origin_addresses.data
  36 + estimation.destination_addresses = form.destination_addresses.data
  37 + estimation.compute_optimal_destination = form.compute_optimal_destination.data
34 38
35 db.session.add(estimation) 39 db.session.add(estimation)
36 db.session.commit() 40 db.session.commit()
@@ -44,8 +48,58 @@ def estimate(): @@ -44,8 +48,58 @@ def estimate():
44 48
45 @main.route("/compute") 49 @main.route("/compute")
46 def compute(): 50 def compute():
  51 +
  52 + def _respond(_msg):
  53 + return "<pre>%s</pre>" % _msg
  54 +
  55 + def _handle_failure(_estimation, _failure_message):
  56 + _estimation.status = StatusEnum.failed
  57 + db.session.commit()
  58 +
47 response = "" 59 response = ""
48 60
49 - # TODO 61 + try:
  62 + estimation = Estimation.query \
  63 + .filter_by(status=StatusEnum.pending) \
  64 + .order_by(Estimation.id.desc()) \
  65 + .one()
  66 + except sqlalchemy.orm.exc.NoResultFound:
  67 + return _respond("No estimation in the queue.")
  68 +
  69 + response += u"Processing estimation `%s` of `%s`...\n" % (estimation.id, estimation.email)
  70 +
  71 + geocoder = CachedGeocoder()
  72 +
  73 + destinations_addresses = estimation.destination_addresses.split("\n")
  74 + destinations = []
  75 +
  76 + for i in range(len(destinations_addresses)):
  77 +
  78 + destination_address = str(destinations_addresses[i])
  79 +
  80 + try:
  81 + destination = geocoder.geocode(destination_address)
  82 + except geopy.exc.GeopyError as e:
  83 + response += u"Failed to geolocalize destination `%s`.\n%s" % (
  84 + destination_address, e,
  85 + )
  86 + _handle_failure(estimation, response)
  87 + return _respond(response)
  88 +
  89 + if destination is None:
  90 + response += u"Failed to geolocalize destination `%s`." % (
  91 + destination_address,
  92 + )
  93 + _handle_failure(estimation, response)
  94 + return _respond(response)
  95 +
  96 + destinations.append(destination)
  97 +
  98 + response += u"Destination: %s == %s (%f, %f)\n" % (
  99 + destination_address, destination.address,
  100 + destination.latitude, destination.longitude,
  101 + )
  102 +
  103 +
50 104
51 - return response 105 + return _respond(response)