Commit 6b149919736edf25616423447cfa6eef2a02d793

Authored by Goutte
1 parent 077980eb

Add a Download button.

CHANGELOG.md
... ... @@ -4,6 +4,7 @@
4 4 - [ ] Optimize CSV generation (with some vectorization using numpy)
5 5 - [ ] Credit the author of the pixel art planets
6 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 10 ## 1.0.0
... ... @@ -21,8 +22,9 @@
21 22 - [ ] Cache cleanup
22 23 - [x] API at /cache/clear
23 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 26 - [ ] Same via SAMP
  27 +- [ ] Add a warning for users with javascript disabled
26 28  
27 29  
28 30 ## 0.0.0
... ...
README.md
... ... @@ -6,19 +6,15 @@ The sources of the website available at https://spaceweatheronline.cdpp.eu
6 6  
7 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 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 20 # How
... ... @@ -27,6 +23,7 @@ Gather NetCDF data from AMDA, and serve it as CSV to the javascript plotter.
27 23  
28 24 - `config.yml` : the main configuration file.
29 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 29 ## Install
... ...
web/static/js/swapp.js
... ... @@ -58,6 +58,24 @@
58 58 url = url.replace('<stopped_at>', stopped_at);
59 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 79 SpaceWeather.prototype.addTarget = function(target){
62 80 this.targets[target.slug] = target;
63 81 return this;
... ...
web/static/js/swapp.ls
... ... @@ -88,6 +88,15 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE
88 88 url = url.replace('<stopped_at>', stopped_at)
89 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 100 addTarget: (target) ->
92 101 @targets[target.slug] = target
93 102 this
... ...
web/view/home.html.jinja2
... ... @@ -88,6 +88,10 @@
88 88 <div class="mdl-grid">
89 89 <div class="mdl-cell mdl-cell--4-col">
90 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 95 </div>
92 96 <div class="mdl-cell mdl-cell--8-col">
93 97 <section id="time_series">
... ... @@ -117,7 +121,7 @@
117 121 {# position: relative;#}
118 122 }
119 123 #plots_loader {
120   - position: absolute;
  124 + position: fixed;
121 125 top: 0; left: 0; bottom: 0; right: 0;
122 126 height: 100%;
123 127 width: 100%;
... ... @@ -199,6 +203,11 @@
199 203 animation-delay: .8s;
200 204 }
201 205  
  206 + #download {
  207 + display: block;
  208 + margin: 3em auto;
  209 + }
  210 +
202 211 #time_series .help {
203 212 position: absolute;
204 213 text-align: center;
... ... @@ -329,7 +338,8 @@ var configuration = {
329 338 time_series_container: '#time_series',
330 339 orbits_container: '#orbits',
331 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 344 sun: {
335 345 img: '{{ static('img/sun_128.png') }}'
... ... @@ -440,7 +450,23 @@ jQuery().ready(function($){
440 450 var stopped_at = moment($("#stopped_at").val());
441 451 sw.resizeDomain(started_at, stopped_at);
442 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 472 </script>
... ...