Commit cad44b6d55940ae698ee8784942558100af12b88

Authored by Goutte
1 parent 6491a1f1

Finish adding the SAMP button (finally!)

web/static/js/swapp.js
@@ -30,7 +30,7 @@ @@ -30,7 +30,7 @@
30 } 30 }
31 configs = res$; 31 configs = res$;
32 configs.forEach(function(target_config){ 32 configs.forEach(function(target_config){
33 - return this$.targets[target_config.slug] = new Target(target_config.slug, target_config.name, target_config); 33 + return this$.addTarget(new Target(target_config.slug, target_config.name, target_config));
34 }); 34 });
35 this.parameters = {}; 35 this.parameters = {};
36 this.configuration['parameters'].forEach(function(p){ 36 this.configuration['parameters'].forEach(function(p){
@@ -42,7 +42,7 @@ @@ -42,7 +42,7 @@
42 SpaceWeather.prototype.init = function(){ 42 SpaceWeather.prototype.init = function(){
43 "This is called by the inline bootstrap javascript code.\nThis ain't in the constructor because it might return a Promise later on.\n(for the loader, for example)"; 43 "This is called by the inline bootstrap javascript code.\nThis ain't in the constructor because it might return a Promise later on.\n(for the loader, for example)";
44 var started_at, stopped_at, this$ = this; 44 var started_at, stopped_at, this$ = this;
45 - started_at = moment().subtract(6, 'month').hours(0).minutes(0).seconds(0); 45 + started_at = moment().subtract(1, 'year').hours(0).minutes(0).seconds(0);
46 stopped_at = moment().add(1, 'week').hours(0).minutes(0).seconds(0); 46 stopped_at = moment().add(1, 'week').hours(0).minutes(0).seconds(0);
47 this.setStartAndStop(started_at, stopped_at); 47 this.setStartAndStop(started_at, stopped_at);
48 this.loadAndCreatePlots(started_at, stopped_at); 48 this.loadAndCreatePlots(started_at, stopped_at);
@@ -76,10 +76,61 @@ @@ -76,10 +76,61 @@
76 url = url.replace('<stopped_at>', stopped_at.format(API_TIME_FORMAT)); 76 url = url.replace('<stopped_at>', stopped_at.format(API_TIME_FORMAT));
77 return url; 77 return url;
78 }; 78 };
  79 + SpaceWeather.prototype.buildSampUrl = function(){
  80 + var ref$, started_at, stopped_at, targets, t, parameters, p, url;
  81 + ref$ = this.getDomain(), started_at = ref$[0], stopped_at = ref$[1];
  82 + targets = (function(){
  83 + var results$ = [];
  84 + for (t in this.targets) {
  85 + if (this.targets[t].active) {
  86 + results$.push(t);
  87 + }
  88 + }
  89 + return results$;
  90 + }.call(this)).sort().join('-');
  91 + parameters = (function(){
  92 + var results$ = [];
  93 + for (p in this.parameters) {
  94 + if (this.parameters[p].active) {
  95 + results$.push(p);
  96 + }
  97 + }
  98 + return results$;
  99 + }.call(this)).sort().join('-');
  100 + url = this.configuration['api']['samp'];
  101 + url = url.replace('<targets>', targets);
  102 + url = url.replace('<params>', parameters);
  103 + url = url.replace('<started_at>', started_at.format(API_TIME_FORMAT));
  104 + url = url.replace('<stopped_at>', stopped_at.format(API_TIME_FORMAT));
  105 + return url;
  106 + };
  107 + SpaceWeather.prototype.buildSampName = function(){
  108 + var ref$, started_at, stopped_at, targets, t;
  109 + ref$ = this.getDomain(), started_at = ref$[0], stopped_at = ref$[1];
  110 + targets = (function(){
  111 + var i$, ref$, len$, results$ = [];
  112 + for (i$ = 0, len$ = (ref$ = this.getEnabledTargets()).length; i$ < len$; ++i$) {
  113 + t = ref$[i$];
  114 + results$.push(t.name);
  115 + }
  116 + return results$;
  117 + }.call(this)).sort().join(', ');
  118 + return "Heliopropa for " + targets + " from " + started_at.format(API_TIME_FORMAT) + " to " + stopped_at.format(API_TIME_FORMAT) + ".";
  119 + };
79 SpaceWeather.prototype.addTarget = function(target){ 120 SpaceWeather.prototype.addTarget = function(target){
80 this.targets[target.slug] = target; 121 this.targets[target.slug] = target;
81 return this; 122 return this;
82 }; 123 };
  124 + SpaceWeather.prototype.getEnabledTargets = function(){
  125 + var slug, ref$, target, results$ = [];
  126 + for (slug in ref$ = this.targets) {
  127 + target = ref$[slug];
  128 + if (target.active) {
  129 + results$.push(target);
  130 + }
  131 + }
  132 + return results$;
  133 + };
83 SpaceWeather.prototype.enableTarget = function(target_slug){ 134 SpaceWeather.prototype.enableTarget = function(target_slug){
84 var this$ = this; 135 var this$ = this;
85 this.time_series.forEach(function(ts){ 136 this.time_series.forEach(function(ts){
@@ -270,6 +321,17 @@ @@ -270,6 +321,17 @@
270 }); 321 });
271 return this.time_series; 322 return this.time_series;
272 }; 323 };
  324 + SpaceWeather.prototype.getEnabledParameters = function(){
  325 + var i$, ref$, len$, p, slug, results$ = [];
  326 + for (i$ = 0, len$ = (ref$ = this.parameters).length; i$ < len$; ++i$) {
  327 + p = i$;
  328 + slug = ref$[i$];
  329 + if (p.active) {
  330 + results$.push(p);
  331 + }
  332 + }
  333 + return results$;
  334 + };
273 SpaceWeather.prototype.enableParameter = function(parameter_slug){ 335 SpaceWeather.prototype.enableParameter = function(parameter_slug){
274 var this$ = this; 336 var this$ = this;
275 if (!(parameter_slug in this.parameters)) { 337 if (!(parameter_slug in this.parameters)) {
web/static/js/swapp.ls
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 # templates, such as `home.html.jinja2`. 11 # templates, such as `home.html.jinja2`.
12 12
13 # Note: We use Promises and ES6 whenever relevant. 13 # Note: We use Promises and ES6 whenever relevant.
14 -# You also will need d3js v4 documentation : https://d3js.org/ 14 +# You also WILL NEED d3js v4 documentation : https://d3js.org/
15 # We're using a custom build of 4.9.1, one line changed, see d3-custom.js 15 # We're using a custom build of 4.9.1, one line changed, see d3-custom.js
16 # Event bubbling cannot trigger two rects unless we make an event dispatcher, 16 # Event bubbling cannot trigger two rects unless we make an event dispatcher,
17 # and d3's brush is stopping propagation, as it should by default. 17 # and d3's brush is stopping propagation, as it should by default.
@@ -56,13 +56,13 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE @@ -56,13 +56,13 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE
56 """ # HelioPropa by CDPP (mushed 'cause we need to escape backslashes) 56 """ # HelioPropa by CDPP (mushed 'cause we need to escape backslashes)
57 @targets = {} 57 @targets = {}
58 configs = [@configuration.targets[k] for k of @configuration.targets] 58 configs = [@configuration.targets[k] for k of @configuration.targets]
59 - configs.forEach((target_config) ~>  
60 - @targets[target_config.slug] = new Target(target_config.slug, target_config.name, target_config)  
61 - ) 59 + configs.forEach (target_config) ~>
  60 + @addTarget(new Target(target_config.slug, target_config.name, target_config))
  61 +
62 @parameters = {} 62 @parameters = {}
63 - @configuration['parameters'].forEach((p) ~>  
64 - @parameters[p['id']] = p  
65 - ) 63 + @configuration['parameters'].forEach (p) ~>
  64 + @parameters[p['id']] = p
  65 +
66 @orbiter = null # our Orbiter defined below 66 @orbiter = null # our Orbiter defined below
67 @time_series = [] # a List of TimeSeries objects 67 @time_series = [] # a List of TimeSeries objects
68 68
@@ -74,7 +74,7 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE @@ -74,7 +74,7 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE
74 """ 74 """
75 # Default time interval is from two weeks ago to one week ahead. 75 # Default time interval is from two weeks ago to one week ahead.
76 # We set the h/m/s to zero to benefit from a daily cache. 76 # We set the h/m/s to zero to benefit from a daily cache.
77 - started_at = moment().subtract(6, 'month').hours(0).minutes(0).seconds(0) 77 + started_at = moment().subtract(1, 'year').hours(0).minutes(0).seconds(0)
78 stopped_at = moment().add(1, 'week').hours(0).minutes(0).seconds(0) 78 stopped_at = moment().add(1, 'week').hours(0).minutes(0).seconds(0)
79 @setStartAndStop(started_at, stopped_at) 79 @setStartAndStop(started_at, stopped_at)
80 @loadAndCreatePlots(started_at, stopped_at) 80 @loadAndCreatePlots(started_at, stopped_at)
@@ -97,6 +97,22 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE @@ -97,6 +97,22 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE
97 url = url.replace('<stopped_at>', stopped_at.format(API_TIME_FORMAT)) 97 url = url.replace('<stopped_at>', stopped_at.format(API_TIME_FORMAT))
98 url 98 url
99 99
  100 + buildSampUrl: ->
  101 + [started_at, stopped_at] = @getDomain()
  102 + targets = [t for t of @targets when @targets[t].active].sort().join('-')
  103 + parameters = [p for p of @parameters when @parameters[p].active].sort().join('-')
  104 + url = @configuration['api']['samp']
  105 + url = url.replace('<targets>', targets)
  106 + url = url.replace('<params>', parameters)
  107 + url = url.replace('<started_at>', started_at.format(API_TIME_FORMAT))
  108 + url = url.replace('<stopped_at>', stopped_at.format(API_TIME_FORMAT))
  109 + url
  110 +
  111 + buildSampName: ->
  112 + [started_at, stopped_at] = @getDomain()
  113 + targets = [t.name for t in @getEnabledTargets()].sort().join(', ')
  114 + "Heliopropa for #{targets} from #{started_at.format(API_TIME_FORMAT)} to #{stopped_at.format(API_TIME_FORMAT)}."
  115 +
100 addTarget: (target) -> 116 addTarget: (target) ->
101 @targets[target.slug] = target 117 @targets[target.slug] = target
102 this 118 this
@@ -106,6 +122,9 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE @@ -106,6 +122,9 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE
106 # enableTarget(slug) 122 # enableTarget(slug)
107 # this 123 # this
108 124
  125 + getEnabledTargets: ->
  126 + [target for slug, target of @targets when target.active]
  127 +
109 enableTarget: (target_slug) -> 128 enableTarget: (target_slug) ->
110 @time_series.forEach((ts) ~> ts.show() if ts.target.slug == target_slug && @parameters[ts.parameter].active) 129 @time_series.forEach((ts) ~> ts.show() if ts.target.slug == target_slug && @parameters[ts.parameter].active)
111 @targets[target_slug].active = true 130 @targets[target_slug].active = true
@@ -237,6 +256,9 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE @@ -237,6 +256,9 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE
237 ) 256 )
238 @time_series 257 @time_series
239 258
  259 + getEnabledParameters: ->
  260 + [p for slug, p in @parameters when p.active]
  261 +
240 enableParameter: (parameter_slug) -> 262 enableParameter: (parameter_slug) ->
241 if parameter_slug not of @parameters then console.error("Unknown parameter #{parameter_slug}.") 263 if parameter_slug not of @parameters then console.error("Unknown parameter #{parameter_slug}.")
242 @parameters[parameter_slug].active = true 264 @parameters[parameter_slug].active = true
web/view/home.html.jinja2
@@ -118,10 +118,16 @@ @@ -118,10 +118,16 @@
118 <div class="mdl-grid"> 118 <div class="mdl-grid">
119 <div class="mdl-cell mdl-cell--4-col mdl-cell--8-col-tablet mdl-cell--4-col-phone"> 119 <div class="mdl-cell mdl-cell--4-col mdl-cell--8-col-tablet mdl-cell--4-col-phone">
120 <section id="orbits"></section> 120 <section id="orbits"></section>
121 - <button id="download" class="mdl-button mdl-button--raised mdl-button--primary"  
122 - title="Download the CSV raw data for each target in a tarball.">  
123 - Download  
124 - </button> 121 + <div class="plots-actions plots-buttons">
  122 + <button id="download" class="mdl-button mdl-button--raised mdl-button--primary"
  123 + title="Download the CSV raw data for each target in a tarball.">
  124 + Download
  125 + </button>
  126 + <button id="samp" class="samp mdl-button mdl-button--raised mdl-button--primary mdl-button--disabled"
  127 + title="Send the data to a connected SAMP hub.">
  128 + SAMP
  129 + </button>
  130 + </div>
125 </div> 131 </div>
126 <div class="mdl-cell mdl-cell--8-col mdl-cell--8-col-tablet mdl-cell--4-col-phone"> 132 <div class="mdl-cell mdl-cell--8-col mdl-cell--8-col-tablet mdl-cell--4-col-phone">
127 <section id="time_series"> 133 <section id="time_series">
@@ -234,10 +240,13 @@ @@ -234,10 +240,13 @@
234 animation-delay: .8s; 240 animation-delay: .8s;
235 } 241 }
236 242
237 - #download {  
238 - display: block; 243 + .plots-buttons {
  244 + text-align: center;
239 margin: 3em auto; 245 margin: 3em auto;
240 } 246 }
  247 + .plots-buttons button {
  248 + margin: auto 1em;
  249 + }
241 250
242 #time_series svg { 251 #time_series svg {
243 cursor: crosshair; 252 cursor: crosshair;
@@ -526,7 +535,8 @@ var configuration = { @@ -526,7 +535,8 @@ var configuration = {
526 orbits_container: '#orbits', 535 orbits_container: '#orbits',
527 api : { 536 api : {
528 'data_for_interval': "{{ request.url_root }}<target>_<started_at>_<stopped_at>.csv", 537 'data_for_interval': "{{ request.url_root }}<target>_<started_at>_<stopped_at>.csv",
529 - 'download': "{{ request.url_root }}<targets>_<started_at>_<stopped_at>.tar.gz" 538 + 'download': "{{ request.url_root }}<targets>_<started_at>_<stopped_at>.tar.gz",
  539 + 'samp': "{{ request.url_root }}<targets>_<params>_<started_at>_<stopped_at>.nc"
530 }, 540 },
531 sun: { 541 sun: {
532 img: '{{ static('img/sun_128.png') }}' 542 img: '{{ static('img/sun_128.png') }}'
@@ -655,4 +665,58 @@ jQuery().ready(function($){ @@ -655,4 +665,58 @@ jQuery().ready(function($){
655 665
656 }); 666 });
657 </script> 667 </script>
  668 +
  669 +{#### SAMP ###################################################################}
  670 +<script type="text/javascript">
  671 + jQuery().ready(function ($) {
  672 + // Flag to know when a hub is connected or not
  673 + var isConnected = false;
  674 +
  675 + // Show SAMP button(s) depending on whether the hub is available or not.
  676 + var onHubAvailability = function (isHubRunning) {
  677 + $(".samp").each(function (index, element) {
  678 + if (isHubRunning) {
  679 + isConnected = true;
  680 + $(element).removeClass('disabled mdl-button--disabled');
  681 + } else {
  682 + isConnected = false;
  683 + $(element).addClass('disabled mdl-button--disabled');
  684 + }
  685 + });
  686 + };
  687 +
  688 + // Update the document about the presence of any SAMP hub every 10 sec.
  689 + var connector = new samp.Connector("Sender");
  690 + connector.onHubAvailability(onHubAvailability, 10000);
  691 + window.onunload = function () {
  692 + connector.unregister();
  693 + };
  694 +
  695 + // Clicking on a SAMP button sends the CDF file to the connected hub.
  696 + $("#samp").click(function (event) {
  697 + event.stopPropagation();
  698 + if ($(this).hasClass('disabled')) { return; }
  699 + // pitfall : connector.connection is ALWAYS undefined here
  700 + if ( ! isConnected) { // so we use a bool flag instead
  701 + alert("We do not detect any connected SAMP hub.\n" +
  702 + "Wait some more, or try refreshing this page?");
  703 + return;
  704 + }
  705 + var name = sw.buildSampName();
  706 + var url = sw.buildSampUrl();
  707 + console.log(name, url);
  708 + connector.runWithConnection(function (connection) {
  709 + var msg = new samp.Message("table.load.cdf", {
  710 + "name": name,
  711 + "url": url // absolute URL required
  712 + });
  713 + connection.notifyAll([msg]);
  714 + }, function (error) {
  715 + var msg = 'Error: ' + error;
  716 + console.error(msg);
  717 + alert(msg); // let's yell at the user as well
  718 + });
  719 + });
  720 + });
  721 +</script>
658 {% endblock %} 722 {% endblock %}