Commit a1f124526ebd44f5e09b69bb99510b3de930b81c

Authored by Antoine Goutenoir
1 parent 77ff53d6
Exists in master

Add the new content from @dbarret

Fix #14
README.md
1 1  
2 2 # Travel Carbon Footprint Calculator
3 3  
  4 +- https://travel-footprint-calculator.apps.goutenoir.com (private demo)
  5 +- http://travel-footprint-calculator.irap.omp.eu (official, for later)
  6 +
  7 +
4 8 ## Overview
5 9  
6 10 - Content is in `content.yml`.
... ...
content.yml
... ... @@ -599,6 +599,22 @@ estimate:
599 599 It may take from a few seconds up to a few minutes,
600 600 depending on the amount of locations you provided.
601 601  
  602 + help:
  603 + first_name: Fill these to say hello.
  604 + last_name: We will never share your data with anyone.
  605 + origin_addresses: |
  606 + Use <code>en_US</code> city and country names, without diacritics.
  607 + &nbsp;
  608 + The comma matters.
  609 + <br>
  610 + This is either a home city and a country
  611 + or the cities and countries of the participants to the conference, meeting…
  612 + destination_addresses: |
  613 + This is either the cities and countries to travel to
  614 + or the host city and country of the conference, meeting…
  615 + <br>
  616 + Please provide multiple cities and countries to compute the location
  617 + of the minimum emission.
602 618  
603 619 # Labels accept HTML, but not markdown
604 620 # Descriptions accept neither, since we use the HTML title attribute
... ... @@ -677,6 +693,23 @@ estimation:
677 693 Sorry about that. Please find the error message below.
678 694 <br>
679 695 Thank you for using our service.
  696 + lolliplot:
  697 + one_to_one: |
  698 + The carbon dioxide equivalent emission is provided for each city of destination.
  699 + Identical trips (i.e. identical destinations) are summed
  700 + and the cumulative distance is provided.
  701 + one_to_many: |
  702 + The carbon dioxide equivalent emission is provided for each city of destination.
  703 + Identical trips (i.e. identical destinations) are summed
  704 + and the cumulative distance is provided.
  705 + many_to_one: |
  706 + The carbon dioxide equivalent emission is provided for each city of origin.
  707 + Identical trips (i.e. identical origins) are summed and the cumulative distance is provided.
  708 + many_to_many: |
  709 + The carbon dioxide equivalent emission is summed
  710 + over all cities of origin and provided for each city of destination.
  711 + The cumulative distance to each city of destination is provided.
  712 + Duplicates in the destinations are removed.
680 713  
681 714 footer:
682 715 credits: |
... ...
flaskr/controllers/main_controller.py
... ... @@ -9,7 +9,7 @@ from os.path import join
9 9  
10 10 from flaskr.extensions import cache, basic_auth
11 11 from flaskr.forms import LoginForm, EstimateForm
12   -from flaskr.models import db, User, Estimation, StatusEnum
  12 +from flaskr.models import db, User, Estimation, StatusEnum, ScenarioEnum
13 13 from flaskr.geocoder import CachedGeocoder
14 14  
15 15 from flaskr.core import generate_unique_id, get_emission_models
... ... @@ -366,6 +366,7 @@ def compute(): # process the queue of estimation requests
366 366 # for each of the Emission Models, and present a mean of all Models.
367 367 #
368 368 if 1 == len(origins):
  369 + estimation.scenario = ScenarioEnum.one_to_many
369 370 results = compute_one_to_many(
370 371 _origin=origins[0],
371 372 _destinations=destinations,
... ... @@ -377,6 +378,7 @@ def compute(): # process the queue of estimation requests
377 378 # Same as A for now.
378 379 #
379 380 elif 1 == len(destinations):
  381 + estimation.scenario = ScenarioEnum.many_to_one
380 382 results = compute_one_to_many(
381 383 _origin=destinations[0],
382 384 _destinations=origins,
... ... @@ -388,6 +390,7 @@ def compute(): # process the queue of estimation requests
388 390 # Run Scenario A for each Destination, and expose optimum Destination.
389 391 #
390 392 else:
  393 + estimation.scenario = ScenarioEnum.many_to_many
391 394 unique_city_keys = []
392 395 result_cities = []
393 396 for destination in destinations:
... ...
flaskr/models.py
... ... @@ -24,6 +24,13 @@ class StatusEnum(enum.Enum):
24 24 failure = 'failure'
25 25  
26 26  
  27 +class ScenarioEnum(enum.Enum):
  28 + one_to_one = 'one_to_one'
  29 + many_to_one = 'many_to_one'
  30 + one_to_many = 'one_to_many'
  31 + many_to_many = 'many_to_many'
  32 +
  33 +
27 34 class Estimation(db.Model):
28 35 id = db.Column(db.Integer(), primary_key=True)
29 36 public_id = db.Column(
... ... @@ -42,12 +49,14 @@ class Estimation(db.Model):
42 49 origin_addresses = db.Column(db.UnicodeText())
43 50 destination_addresses = db.Column(db.UnicodeText())
44 51  
45   - # One slug per line (or blankchar?)
  52 + # One slug per line (or blank char?)
46 53 models_slugs = db.Column(db.UnicodeText())
47 54  
48 55 # Deprecated, we detect this scenario from the amount of locations.
49 56 compute_optimal_destination = db.Column(db.Boolean())
50 57  
  58 + # Outputs
  59 + scenario = db.Column(db.Enum(ScenarioEnum), default=ScenarioEnum.many_to_many)
51 60 output_yaml = db.Column(db.UnicodeText())
52 61 warnings = db.Column(db.UnicodeText())
53 62 errors = db.Column(db.UnicodeText())
... ... @@ -60,10 +69,20 @@ class Estimation(db.Model):
60 69 def get_output_dict(self):
61 70 if self._output_dict is None:
62 71 self._output_dict = yaml_load(self.output_yaml)
63   - return self._output_dict
  72 + return self._output_dict
  73 + pass
  74 +
  75 + def is_one_to_one(self):
  76 + return self.scenario == ScenarioEnum.one_to_one
  77 +
  78 + def is_one_to_many(self):
  79 + return self.scenario == ScenarioEnum.one_to_many
  80 +
  81 + def is_many_to_one(self):
  82 + return self.scenario == ScenarioEnum.many_to_one
64 83  
65   - def has_many_to_many(self):
66   - return 'cities' in self.get_output_dict()
  84 + def is_many_to_many(self):
  85 + return self.scenario == ScenarioEnum.many_to_many
67 86  
68 87 _models = None
69 88  
... ... @@ -82,6 +101,7 @@ class EstimationView(ModelView):
82 101 'first_name',
83 102 'last_name',
84 103 'models_slugs',
  104 + 'scenario',
85 105 'origin_addresses',
86 106 'destination_addresses',
87 107 'warnings',
... ...
flaskr/static/css/common/main.css
... ... @@ -73,7 +73,7 @@ span.required-asterisk {
73 73 /** LISTS *********************************************************************/
74 74  
75 75 .numbered-list {
76   - list-style: upper-roman;
  76 + list-style: decimal-leading-zero;
77 77 }
78 78  
79 79  
... ...
flaskr/templates/estimate.html
... ... @@ -70,11 +70,11 @@
70 70 <div class="form-group row">
71 71 <div class="col-md-6">
72 72 {{ render_field(form.first_name) }}
73   - <small class="form-text text-muted">Fill these to say hello.</small>
  73 + <small class="form-text text-muted">{{ content.estimate.help.first_name | safe }}</small>
74 74 </div>
75 75 <div class="col-md-6">
76 76 {{ render_field(form.last_name) }}
77   - <small class="form-text text-muted">We will never share your data with anyone.</small>
  77 + <small class="form-text text-muted">{{ content.estimate.help.last_name | safe }}</small>
78 78 </div>
79 79 </div>
80 80 <div class="form-group">
... ... @@ -83,19 +83,13 @@
83 83 <div class="form-group">
84 84 {{ render_field(form.origin_addresses) }}
85 85 <small class="form-text text-muted">
86   - Use <code>en_US</code> city and country names, without diacritics.
87   - &nbsp;
88   - The comma matters.
89   - <br>
90   - These usually are the addresses of your participants.
  86 + {{ content.estimate.help.origin_addresses | safe }}
91 87 </small>
92 88 </div>
93 89 <div class="form-group">
94 90 {{ render_field(form.destination_addresses) }}
95 91 <small class="form-text text-muted">
96   - Provide <strong>multiple destinations</strong> to compare them and <strong>compute optimum</strong>.
97   - <br>
98   - These usually are the possible locations for an event.
  92 + {{ content.estimate.help.destination_addresses | safe }}
99 93 </small>
100 94 </div>
101 95 {# <div class="form-check form-group">#}
... ...
flaskr/templates/estimation.html
... ... @@ -79,21 +79,31 @@
79 79  
80 80 {% if not estimation.has_failed() %}
81 81 {#{% set estimation_output = estimation.get_output_dict() %}#}
82   -{% if estimation.has_many_to_many() %}
83   - <div class="col-md-6">
84   - <p>
85   - For each destination city, the sum of the travels from all the origins.
86   - </p>
  82 +<div class="col-md-6">
  83 +{% if estimation.is_one_to_one() %}
  84 + {{ content.estimation.lolliplot.one_to_one | markdown | safe }}
  85 +{# <p>#}
  86 +{# For each destination city, the sum of the travels from all the origins.#}
  87 +{# </p>#}
87 88 {{ render_cities(estimation_output.cities) }}
88   - </div>
89   -{% else %}
90   - <div class="col-md-6">
91   - <p>
92   - Carbon footprint for each city.
93   - </p>
  89 +{% elif estimation.is_many_to_one() %}
  90 + {{ content.estimation.lolliplot.many_to_one | markdown | safe }}
  91 +{# <p>#}
  92 +{# For each destination city, the sum of the travels from all the origins.#}
  93 +{# </p>#}
  94 + {{ render_cities(estimation_output.cities) }}
  95 +{% elif estimation.is_one_to_many() %}
  96 + {{ content.estimation.lolliplot.one_to_many | markdown | safe }}
  97 +
  98 + {{ render_cities(estimation_output.cities) }}
  99 +{% elif estimation.is_many_to_many() %}
  100 + {{ content.estimation.lolliplot.many_to_many | markdown | safe }}
  101 +{# <p>#}
  102 +{# Carbon footprint for each city.#}
  103 +{# </p>#}
94 104 {{ render_cities(estimation_output.cities) }}
95   - </div>
96 105 {% endif %}
  106 +</div>
97 107  
98 108 <div class="col-md-6">
99 109 <ul class="nav">
... ... @@ -153,8 +163,13 @@
153 163 {# </pre>#}
154 164 {# </div>#}
155 165 {#</div>#}
156   -{% endif %}
  166 +
  167 +{% endif %}{# estimation.has_failed() #}
157 168 {% endblock %}
  169 +
  170 +{#############################################################################}
  171 +{#############################################################################}
  172 +
158 173 {% block js %}
159 174 <script src="/static/js/vendor/d3.v4.js"></script>
160 175 <script src="/static/js/vendor/d3-legend.js"></script>
... ...