Commit 60b73eb1d737e7bca73ec075ba3f5c99aabc5e59
1 parent
1324cc91
Exists in
master
and in
2 other branches
Change temperature units from `K` to `eV`.
Handle errors more gracefully. Load targets' data sequentially.
Showing
5 changed files
with
60 additions
and
33 deletions
Show diff stats
web/run.py
@@ -103,8 +103,8 @@ PARAMETERS = { | @@ -103,8 +103,8 @@ PARAMETERS = { | ||
103 | 'temp': { | 103 | 'temp': { |
104 | 'slug': 'temp', | 104 | 'slug': 'temp', |
105 | 'name': 'Temperature', | 105 | 'name': 'Temperature', |
106 | - 'title': 'The absolute temperature.', | ||
107 | - 'units': 'K', | 106 | + 'title': 'The temperature.', |
107 | + 'units': 'eV', | ||
108 | 'active': False, | 108 | 'active': False, |
109 | 'position': 40, | 109 | 'position': 40, |
110 | }, | 110 | }, |
@@ -457,10 +457,12 @@ def get_data_for_target(target_config, started_at, stopped_at): | @@ -457,10 +457,12 @@ def get_data_for_target(target_config, started_at, stopped_at): | ||
457 | for orbit in orbits: | 457 | for orbit in orbits: |
458 | if 'started_at' in orbit: | 458 | if 'started_at' in orbit: |
459 | s0 = datetime.datetime.strptime(orbit['started_at'], FILE_DATE_FMT) | 459 | s0 = datetime.datetime.strptime(orbit['started_at'], FILE_DATE_FMT) |
460 | + s0 = max(s0, started_at) | ||
460 | else: | 461 | else: |
461 | s0 = started_at | 462 | s0 = started_at |
462 | if 'stopped_at' in orbit: | 463 | if 'stopped_at' in orbit: |
463 | s1 = datetime.datetime.strptime(orbit['stopped_at'], FILE_DATE_FMT) | 464 | s1 = datetime.datetime.strptime(orbit['stopped_at'], FILE_DATE_FMT) |
465 | + s1 = min(s1, stopped_at) | ||
464 | else: | 466 | else: |
465 | s1 = stopped_at | 467 | s1 = stopped_at |
466 | 468 |
1.1 KB
web/static/js/swapp.js
@@ -181,7 +181,7 @@ | @@ -181,7 +181,7 @@ | ||
181 | url = sw.buildDataUrlForTarget(target_slug, started_at, stopped_at); | 181 | url = sw.buildDataUrlForTarget(target_slug, started_at, stopped_at); |
182 | return d3.csv(url, function(csv){ | 182 | return d3.csv(url, function(csv){ |
183 | var timeFormat, data; | 183 | var timeFormat, data; |
184 | - console.debug("Requested CSV for " + target_slug + "...", csv); | 184 | + console.debug("Requested CSV for " + target_slug + "…", csv); |
185 | timeFormat = d3.timeParse('%Y-%m-%dT%H:%M:%S%Z'); | 185 | timeFormat = d3.timeParse('%Y-%m-%dT%H:%M:%S%Z'); |
186 | data = { | 186 | data = { |
187 | 'hee': [] | 187 | 'hee': [] |
@@ -220,41 +220,49 @@ | @@ -220,41 +220,49 @@ | ||
220 | }; | 220 | }; |
221 | SpaceWeather.prototype.loadAndCreatePlots = function(started_at, stopped_at){ | 221 | SpaceWeather.prototype.loadAndCreatePlots = function(started_at, stopped_at){ |
222 | "started_at: moment(.js) datetime object\nstopped_at: moment(.js) datetime object"; | 222 | "started_at: moment(.js) datetime object\nstopped_at: moment(.js) datetime object"; |
223 | - var k, this$ = this; | 223 | + var targets, res$, k, handleTarget, this$ = this; |
224 | this.showLoader(); | 224 | this.showLoader(); |
225 | this.started_at = started_at; | 225 | this.started_at = started_at; |
226 | this.stopped_at = stopped_at; | 226 | this.stopped_at = stopped_at; |
227 | this.orbits = new Orbits(this.configuration.orbits_container, this.configuration); | 227 | this.orbits = new Orbits(this.configuration.orbits_container, this.configuration); |
228 | started_at = started_at.format(API_TIME_FORMAT); | 228 | started_at = started_at.format(API_TIME_FORMAT); |
229 | stopped_at = stopped_at.format(API_TIME_FORMAT); | 229 | stopped_at = stopped_at.format(API_TIME_FORMAT); |
230 | - return (function(){ | ||
231 | - var results$ = []; | ||
232 | - for (k in this.targets) { | ||
233 | - results$.push(this.targets[k]); | ||
234 | - } | ||
235 | - return results$; | ||
236 | - }.call(this)).forEach(function(target){ | 230 | + res$ = []; |
231 | + for (k in this.targets) { | ||
232 | + res$.push(this.targets[k]); | ||
233 | + } | ||
234 | + targets = res$; | ||
235 | + targets.forEach(function(target){ | ||
237 | var targetButton; | 236 | var targetButton; |
238 | - console.info("Loading CSV data of " + target.name + "…"); | ||
239 | targetButton = $(".targets-filters .target." + target.slug); | 237 | targetButton = $(".targets-filters .target." + target.slug); |
240 | targetButton.addClass('loading'); | 238 | targetButton.addClass('loading'); |
241 | - targetButton.removeClass('failed empty'); | 239 | + return targetButton.removeClass('failed error empty'); |
240 | + }); | ||
241 | + handleTarget = function(i){ | ||
242 | + var target, targetButton; | ||
243 | + if (i >= targets.length) { | ||
244 | + return; | ||
245 | + } | ||
246 | + target = targets[i]; | ||
247 | + console.info("Loading CSV data of " + target.name + "…"); | ||
248 | + targetButton = $(".targets-filters .target." + target.slug); | ||
242 | return this$.loadData(target.slug, started_at, stopped_at).then(function(data){ | 249 | return this$.loadData(target.slug, started_at, stopped_at).then(function(data){ |
243 | console.info("Loaded CSV data of " + target.name + ".", data); | 250 | console.info("Loaded CSV data of " + target.name + ".", data); |
244 | this$.createTimeSeries(target, data); | 251 | this$.createTimeSeries(target, data); |
245 | this$.orbits.initOrbiter(target.slug, target.config, data['hee']); | 252 | this$.orbits.initOrbiter(target.slug, target.config, data['hee']); |
246 | targetButton.removeClass('loading'); | 253 | targetButton.removeClass('loading'); |
247 | if (target.active) { | 254 | if (target.active) { |
248 | - return this$.hideLoader(); | 255 | + this$.hideLoader(); |
249 | } else { | 256 | } else { |
250 | - return this$.disableTarget(target.slug); | 257 | + this$.disableTarget(target.slug); |
251 | } | 258 | } |
259 | + return handleTarget(i + 1); | ||
252 | }, function(error){ | 260 | }, function(error){ |
253 | var msg; | 261 | var msg; |
254 | switch (error) { | 262 | switch (error) { |
255 | case 'invalid': | 263 | case 'invalid': |
256 | console.error("Failed loading CSV data of " + target.name + "."); | 264 | console.error("Failed loading CSV data of " + target.name + "."); |
257 | - alert("There was an error with " + target.name + ".\nPlease retry in a few moments."); | 265 | + targetButton.addClass('error'); |
258 | this$.is_invalid = true; | 266 | this$.is_invalid = true; |
259 | break; | 267 | break; |
260 | case 'empty': | 268 | case 'empty': |
@@ -265,9 +273,12 @@ | @@ -265,9 +273,12 @@ | ||
265 | } | 273 | } |
266 | targetButton.addClass('failed'); | 274 | targetButton.addClass('failed'); |
267 | targetButton.removeClass('loading'); | 275 | targetButton.removeClass('loading'); |
268 | - return this$.hideLoader(); | 276 | + this$.hideLoader(); |
277 | + return handleTarget(i + 1); | ||
269 | }); | 278 | }); |
270 | - }); | 279 | + }; |
280 | + handleTarget(0); | ||
281 | + return this; | ||
271 | }; | 282 | }; |
272 | SpaceWeather.prototype.clearPlots = function(){ | 283 | SpaceWeather.prototype.clearPlots = function(){ |
273 | this.orbits.clear(); | 284 | this.orbits.clear(); |
web/static/js/swapp.ls
@@ -157,7 +157,7 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE | @@ -157,7 +157,7 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE | ||
157 | new Promise((resolve, reject) -> | 157 | new Promise((resolve, reject) -> |
158 | url = sw.buildDataUrlForTarget(target_slug, started_at, stopped_at) | 158 | url = sw.buildDataUrlForTarget(target_slug, started_at, stopped_at) |
159 | d3.csv(url, (csv) -> | 159 | d3.csv(url, (csv) -> |
160 | - console.debug("Requested CSV for #{target_slug}...", csv) | 160 | + console.debug("Requested CSV for #{target_slug}…", csv) |
161 | timeFormat = d3.timeParse('%Y-%m-%dT%H:%M:%S%Z') | 161 | timeFormat = d3.timeParse('%Y-%m-%dT%H:%M:%S%Z') |
162 | data = { 'hee': [] } | 162 | data = { 'hee': [] } |
163 | configuration['parameters'].forEach((parameter) -> | 163 | configuration['parameters'].forEach((parameter) -> |
@@ -191,12 +191,18 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE | @@ -191,12 +191,18 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE | ||
191 | @orbits = new Orbits(@configuration.orbits_container, @configuration) | 191 | @orbits = new Orbits(@configuration.orbits_container, @configuration) |
192 | started_at = started_at.format(API_TIME_FORMAT) | 192 | started_at = started_at.format(API_TIME_FORMAT) |
193 | stopped_at = stopped_at.format(API_TIME_FORMAT) | 193 | stopped_at = stopped_at.format(API_TIME_FORMAT) |
194 | - # active_targets = [@targets[k] for k of @targets when @targets[k].active] | ||
195 | - [@targets[k] for k of @targets].forEach((target) ~> | ||
196 | - console.info "Loading CSV data of #{target.name}…" | 194 | + |
195 | + targets = [@targets[k] for k of @targets] | ||
196 | + targets.forEach((target) ~> | ||
197 | targetButton = $(".targets-filters .target.#{target.slug}") | 197 | targetButton = $(".targets-filters .target.#{target.slug}") |
198 | targetButton.addClass('loading') | 198 | targetButton.addClass('loading') |
199 | - targetButton.removeClass('failed empty') | 199 | + targetButton.removeClass('failed error empty') |
200 | + ) | ||
201 | + handleTarget = (i) ~> | ||
202 | + if i >= targets.length then return | ||
203 | + target = targets[i] | ||
204 | + console.info "Loading CSV data of #{target.name}…" | ||
205 | + targetButton = $(".targets-filters .target.#{target.slug}") | ||
200 | @loadData(target.slug, started_at, stopped_at).then( | 206 | @loadData(target.slug, started_at, stopped_at).then( |
201 | (data) ~> | 207 | (data) ~> |
202 | console.info "Loaded CSV data of #{target.name}.", data | 208 | console.info "Loaded CSV data of #{target.name}.", data |
@@ -204,6 +210,7 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE | @@ -204,6 +210,7 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE | ||
204 | @orbits.initOrbiter(target.slug, target.config, data['hee']) | 210 | @orbits.initOrbiter(target.slug, target.config, data['hee']) |
205 | targetButton.removeClass('loading') | 211 | targetButton.removeClass('loading') |
206 | if target.active then @hideLoader() else @disableTarget(target.slug) | 212 | if target.active then @hideLoader() else @disableTarget(target.slug) |
213 | + handleTarget(i+1) | ||
207 | , | 214 | , |
208 | (error) ~> | 215 | (error) ~> |
209 | switch error | 216 | switch error |
@@ -211,7 +218,8 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE | @@ -211,7 +218,8 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE | ||
211 | console.error("Failed loading CSV data of #{target.name}.") | 218 | console.error("Failed loading CSV data of #{target.name}.") |
212 | # Sometimes, AMDA's API returns garbage, so the CSV sometime fails | 219 | # Sometimes, AMDA's API returns garbage, so the CSV sometime fails |
213 | # But when we re-generate it a second time, usually it's okay. | 220 | # But when we re-generate it a second time, usually it's okay. |
214 | - alert("There was an error with #{target.name}.\nPlease retry in a few moments.") | 221 | + # alert("There was an error with #{target.name}.\nPlease retry in a few moments.") |
222 | + targetButton.addClass('error') | ||
215 | @is_invalid = true | 223 | @is_invalid = true |
216 | break | 224 | break |
217 | case 'empty' | 225 | case 'empty' |
@@ -223,9 +231,12 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE | @@ -223,9 +231,12 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE | ||
223 | targetButton.addClass('failed') | 231 | targetButton.addClass('failed') |
224 | targetButton.removeClass('loading') | 232 | targetButton.removeClass('loading') |
225 | @hideLoader() | 233 | @hideLoader() |
226 | - | 234 | + handleTarget(i+1) |
227 | ) | 235 | ) |
228 | - ) | 236 | + handleTarget(0) |
237 | + | ||
238 | + | ||
239 | + this | ||
229 | 240 | ||
230 | clearPlots: -> | 241 | clearPlots: -> |
231 | @orbits.clear() | 242 | @orbits.clear() |
web/view/home.html.jinja2
@@ -16,14 +16,14 @@ | @@ -16,14 +16,14 @@ | ||
16 | alt="{{ target.name }}"> | 16 | alt="{{ target.name }}"> |
17 | <img width="64px" height="64px" | 17 | <img width="64px" height="64px" |
18 | src="{{ static('img/target/empty_128.png') }}" | 18 | src="{{ static('img/target/empty_128.png') }}" |
19 | - title="No data at specified interval for {{ target.title }}" | ||
20 | - alt="No data for {{ target.name }}" | 19 | + title="No data at specified interval for {{ target.title }}." |
20 | + alt="NO DATA" | ||
21 | class="decorator empty"> | 21 | class="decorator empty"> |
22 | -{# <img width="32px" height="32px"#} | ||
23 | -{# src="{{ static('img/target/loading_32.gif') }}"#} | ||
24 | -{# title="Loading data for {{ target.title }}…"#} | ||
25 | -{# alt="Loader for {{ target.name }}"#} | ||
26 | -{# class="decorator loading">#} | 22 | + <img width="64px" height="64px" |
23 | + src="{{ static('img/target/error_128.png') }}" | ||
24 | + title="There was an error with {{ target.title }}." | ||
25 | + alt="ERROR" | ||
26 | + class="decorator error"> | ||
27 | <div class="decorator loading" title="Loading data for {{ target.title }}…"> | 27 | <div class="decorator loading" title="Loading data for {{ target.title }}…"> |
28 | <div class="small-loader-container"> | 28 | <div class="small-loader-container"> |
29 | <div class="small-loader-circle-1"> | 29 | <div class="small-loader-circle-1"> |
@@ -361,6 +361,9 @@ | @@ -361,6 +361,9 @@ | ||
361 | .targets-filters .target.empty .decorator.empty { | 361 | .targets-filters .target.empty .decorator.empty { |
362 | display: block; | 362 | display: block; |
363 | } | 363 | } |
364 | + .targets-filters .target.error .decorator.error { | ||
365 | + display: block; | ||
366 | + } | ||
364 | .targets-filters .target .decorator.loading { | 367 | .targets-filters .target .decorator.loading { |
365 | top: 19px; | 368 | top: 19px; |
366 | left: 19px; | 369 | left: 19px; |