Commit 6b149919736edf25616423447cfa6eef2a02d793
1 parent
077980eb
Exists in
master
and in
2 other branches
Add a Download button.
Showing
5 changed files
with
65 additions
and
13 deletions
Show diff stats
CHANGELOG.md
@@ -4,6 +4,7 @@ | @@ -4,6 +4,7 @@ | ||
4 | - [ ] Optimize CSV generation (with some vectorization using numpy) | 4 | - [ ] Optimize CSV generation (with some vectorization using numpy) |
5 | - [ ] Credit the author of the pixel art planets | 5 | - [ ] Credit the author of the pixel art planets |
6 | - [ ] Set the log level to _error_ in production (see `web/run.py`) | 6 | - [ ] Set the log level to _error_ in production (see `web/run.py`) |
7 | +- [ ] Add a README to the download tarball | ||
7 | 8 | ||
8 | 9 | ||
9 | ## 1.0.0 | 10 | ## 1.0.0 |
@@ -21,8 +22,9 @@ | @@ -21,8 +22,9 @@ | ||
21 | - [ ] Cache cleanup | 22 | - [ ] Cache cleanup |
22 | - [x] API at /cache/clear | 23 | - [x] API at /cache/clear |
23 | - [ ] CRON statement to call it | 24 | - [ ] CRON statement to call it |
24 | -- [ ] Download raw data (tarball of CSV) for current time interval and targets | 25 | +- [x] Download raw data (tarball of CSV) for current time interval and targets |
25 | - [ ] Same via SAMP | 26 | - [ ] Same via SAMP |
27 | +- [ ] Add a warning for users with javascript disabled | ||
26 | 28 | ||
27 | 29 | ||
28 | ## 0.0.0 | 30 | ## 0.0.0 |
README.md
@@ -6,19 +6,15 @@ The sources of the website available at https://spaceweatheronline.cdpp.eu | @@ -6,19 +6,15 @@ The sources of the website available at https://spaceweatheronline.cdpp.eu | ||
6 | 6 | ||
7 | ## Web Server | 7 | ## Web Server |
8 | 8 | ||
9 | -Build and serve the space weather visualization webpages. | ||
10 | -A flask webserver, serving d3.js visualizations. | ||
11 | - | ||
12 | - | ||
13 | -## Bridge | ||
14 | - | ||
15 | -Gather NetCDF data from AMDA, and serve it as CSV to the javascript plotter. | 9 | +Build and serve heliopropa's visualizations. |
10 | +It's a `flask` webserver, serving `d3.js` plots written in `livescript`. | ||
11 | +It also gathers NetCDF data from AMDA, and serves it as CSV to the plotter. | ||
16 | 12 | ||
17 | 13 | ||
18 | ### Rationale | 14 | ### Rationale |
19 | 15 | ||
20 | -- Reading NetCDF from javascript is doable, but still very hacky. | ||
21 | -- The bridge can handle pagination, collecting multiple NetCDF into one CSV. | 16 | +- Reading NetCDF from javascript is doable, but still *very* hacky. |
17 | +- The bridge can handle pagination and collecting multiple NetCDF into one CSV. | ||
22 | 18 | ||
23 | 19 | ||
24 | # How | 20 | # How |
@@ -27,6 +23,7 @@ Gather NetCDF data from AMDA, and serve it as CSV to the javascript plotter. | @@ -27,6 +23,7 @@ Gather NetCDF data from AMDA, and serve it as CSV to the javascript plotter. | ||
27 | 23 | ||
28 | - `config.yml` : the main configuration file. | 24 | - `config.yml` : the main configuration file. |
29 | - `web/run.py` : the front controller, holding most of the code. | 25 | - `web/run.py` : the front controller, holding most of the code. |
26 | +- `web/view/home.html.jinja2` : the HTML template. | ||
30 | 27 | ||
31 | 28 | ||
32 | ## Install | 29 | ## Install |
web/static/js/swapp.js
@@ -58,6 +58,24 @@ | @@ -58,6 +58,24 @@ | ||
58 | url = url.replace('<stopped_at>', stopped_at); | 58 | url = url.replace('<stopped_at>', stopped_at); |
59 | return url; | 59 | return url; |
60 | }; | 60 | }; |
61 | + SpaceWeather.prototype.buildDownloadUrl = function(){ | ||
62 | + var ref$, started_at, stopped_at, targets, t, url; | ||
63 | + ref$ = this.getDomain(), started_at = ref$[0], stopped_at = ref$[1]; | ||
64 | + targets = (function(){ | ||
65 | + var results$ = []; | ||
66 | + for (t in this.targets) { | ||
67 | + if (this.targets[t].active) { | ||
68 | + results$.push(t); | ||
69 | + } | ||
70 | + } | ||
71 | + return results$; | ||
72 | + }.call(this)).sort().join('-'); | ||
73 | + url = this.configuration['api']['download']; | ||
74 | + url = url.replace('<targets>', targets); | ||
75 | + url = url.replace('<started_at>', started_at.format(API_TIME_FORMAT)); | ||
76 | + url = url.replace('<stopped_at>', stopped_at.format(API_TIME_FORMAT)); | ||
77 | + return url; | ||
78 | + }; | ||
61 | SpaceWeather.prototype.addTarget = function(target){ | 79 | SpaceWeather.prototype.addTarget = function(target){ |
62 | this.targets[target.slug] = target; | 80 | this.targets[target.slug] = target; |
63 | return this; | 81 | return this; |
web/static/js/swapp.ls
@@ -88,6 +88,15 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE | @@ -88,6 +88,15 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE | ||
88 | url = url.replace('<stopped_at>', stopped_at) | 88 | url = url.replace('<stopped_at>', stopped_at) |
89 | url | 89 | url |
90 | 90 | ||
91 | + buildDownloadUrl: -> | ||
92 | + [started_at, stopped_at] = @getDomain() | ||
93 | + targets = [t for t of @targets when @targets[t].active].sort().join('-') | ||
94 | + url = @configuration['api']['download'] | ||
95 | + url = url.replace('<targets>', targets) | ||
96 | + url = url.replace('<started_at>', started_at.format(API_TIME_FORMAT)) | ||
97 | + url = url.replace('<stopped_at>', stopped_at.format(API_TIME_FORMAT)) | ||
98 | + url | ||
99 | + | ||
91 | addTarget: (target) -> | 100 | addTarget: (target) -> |
92 | @targets[target.slug] = target | 101 | @targets[target.slug] = target |
93 | this | 102 | this |
web/view/home.html.jinja2
@@ -88,6 +88,10 @@ | @@ -88,6 +88,10 @@ | ||
88 | <div class="mdl-grid"> | 88 | <div class="mdl-grid"> |
89 | <div class="mdl-cell mdl-cell--4-col"> | 89 | <div class="mdl-cell mdl-cell--4-col"> |
90 | <section id="orbits"></section> | 90 | <section id="orbits"></section> |
91 | + <button id="download" class="mdl-button mdl-button--raised mdl-button--primary" | ||
92 | + title="Download the CSV raw data for each target in a tarball."> | ||
93 | + Download | ||
94 | + </button> | ||
91 | </div> | 95 | </div> |
92 | <div class="mdl-cell mdl-cell--8-col"> | 96 | <div class="mdl-cell mdl-cell--8-col"> |
93 | <section id="time_series"> | 97 | <section id="time_series"> |
@@ -117,7 +121,7 @@ | @@ -117,7 +121,7 @@ | ||
117 | {# position: relative;#} | 121 | {# position: relative;#} |
118 | } | 122 | } |
119 | #plots_loader { | 123 | #plots_loader { |
120 | - position: absolute; | 124 | + position: fixed; |
121 | top: 0; left: 0; bottom: 0; right: 0; | 125 | top: 0; left: 0; bottom: 0; right: 0; |
122 | height: 100%; | 126 | height: 100%; |
123 | width: 100%; | 127 | width: 100%; |
@@ -199,6 +203,11 @@ | @@ -199,6 +203,11 @@ | ||
199 | animation-delay: .8s; | 203 | animation-delay: .8s; |
200 | } | 204 | } |
201 | 205 | ||
206 | + #download { | ||
207 | + display: block; | ||
208 | + margin: 3em auto; | ||
209 | + } | ||
210 | + | ||
202 | #time_series .help { | 211 | #time_series .help { |
203 | position: absolute; | 212 | position: absolute; |
204 | text-align: center; | 213 | text-align: center; |
@@ -329,7 +338,8 @@ var configuration = { | @@ -329,7 +338,8 @@ var configuration = { | ||
329 | time_series_container: '#time_series', | 338 | time_series_container: '#time_series', |
330 | orbits_container: '#orbits', | 339 | orbits_container: '#orbits', |
331 | api : { | 340 | api : { |
332 | - 'data_for_interval': "{{ request.url_root }}<target>_<started_at>_<stopped_at>.csv" | 341 | + 'data_for_interval': "{{ request.url_root }}<target>_<started_at>_<stopped_at>.csv", |
342 | + 'download': "{{ request.url_root }}<targets>_<started_at>_<stopped_at>.tar.gz" | ||
333 | }, | 343 | }, |
334 | sun: { | 344 | sun: { |
335 | img: '{{ static('img/sun_128.png') }}' | 345 | img: '{{ static('img/sun_128.png') }}' |
@@ -440,7 +450,23 @@ jQuery().ready(function($){ | @@ -440,7 +450,23 @@ jQuery().ready(function($){ | ||
440 | var stopped_at = moment($("#stopped_at").val()); | 450 | var stopped_at = moment($("#stopped_at").val()); |
441 | sw.resizeDomain(started_at, stopped_at); | 451 | sw.resizeDomain(started_at, stopped_at); |
442 | return false; | 452 | return false; |
443 | - }) | 453 | + }); |
454 | + $('#download').on("click", function(e){ | ||
455 | + var url = sw.buildDownloadUrl(); | ||
456 | + $.ajax({ | ||
457 | + type: 'GET', | ||
458 | + url: url, | ||
459 | + processData: false, | ||
460 | + success: function (data) { | ||
461 | + window.location = url; | ||
462 | + }, | ||
463 | + error: function (xhr) { | ||
464 | + console.error('Cannot download.', xhr); | ||
465 | + alert("Our apologies, there was an error while downloading."); | ||
466 | + } | ||
467 | + }); | ||
468 | + return false; | ||
469 | + }); | ||
444 | 470 | ||
445 | }); | 471 | }); |
446 | </script> | 472 | </script> |