Commit 853c81545d4552d8ec044b1ab7c4b56f1c8f2225

Authored by Nathanael Jourdane
1 parent 34cf0b45

Init start/stop date fields according to services tMin and tMax

js/app/controllers/EpnTapModule.js
... ... @@ -48,7 +48,7 @@ Ext.define('amdaDesktop.EpnTapModule', {
48 48 this.targetNameCB.setRawValue(filter['targetName'])
49 49 this.productTypeCB.select(filter['productType'])
50 50 if (this.servicesStore.count() > 0) {
51   - this.getServices()
  51 + this.updateNbResults()
52 52 }
53 53 } else {
54 54 this.servicesStore.each(function (record) {
... ... @@ -75,7 +75,7 @@ Ext.define('amdaDesktop.EpnTapModule', {
75 75  
76 76 addListeners: function () {
77 77 this.servicesStore.on('load', function () {
78   - this.getServices()
  78 + this.updateNbResults()
79 79 }, this)
80 80  
81 81 this.servicesGrid.on('cellclick', function (grid, td, cellIndex, record) {
... ... @@ -83,7 +83,7 @@ Ext.define('amdaDesktop.EpnTapModule', {
83 83 }, this)
84 84  
85 85 this.getBtn.on('click', function () {
86   - this.getServices()
  86 + this.updateNbResults()
87 87 }, this)
88 88 },
89 89  
... ... @@ -94,14 +94,16 @@ Ext.define('amdaDesktop.EpnTapModule', {
94 94 /**
95 95 Triggered when the 'Get results' button is clicked.
96 96 */
97   - getServices: function () {
  97 + updateNbResults: function () {
98 98 /* global loadMask */
99 99 loadMask.show()
100 100  
101 101 const targetName = this.targetNameCB.rawValue
102 102 const productTypes = this.productTypeCB.value.join(';')
103   - const timeMin = Ext.Date.format(this.timeSelector.getStartTime(), 'd/m/Y H:i:s')
104   - const timeMax = Ext.Date.format(this.timeSelector.getStopTime(), 'd/m/Y H:i:s')
  103 + const initTMin = this.timeSelector.getStartTime()
  104 + const initTMax = this.timeSelector.getStopTime()
  105 + const initTMinStr = Ext.Date.format(initTMin, 'd/m/Y H:i:s')
  106 + const initTMaxStr = Ext.Date.format(initTMax, 'd/m/Y H:i:s')
105 107  
106 108 this.servicesStore.each(function (record) {
107 109 record.set('nb_results', -1)
... ... @@ -115,21 +117,21 @@ Ext.define('amdaDesktop.EpnTapModule', {
115 117 method: 'GET',
116 118 headers: {'Content-Type': 'application/json'},
117 119 params: {
118   - 'action': 'getNbResults',
  120 + 'action': 'updateNbResults',
119 121 'serviceId': record.data['id'],
120 122 'url': record.data['access_url'],
121 123 'tableName': record.data['table_name'],
122 124 'targetNames': targetName,
123 125 'productTypes': productTypes,
124   - 'timeMin': timeMin,
125   - 'timeMax': timeMax
  126 + 'timeMin': initTMinStr,
  127 + 'timeMax': initTMaxStr
126 128 },
127 129 // timeout: 3000,
128 130 success: function (response, options) {
129 131 const record = ss.getById(options.params['serviceId'])
130 132 // noinspection JSValidateTypes
131 133 const responseObj = Ext.decode(response.responseText)
132   - this.updateService(record, responseObj['success'] ? responseObj['data'] : -2, responseObj['msg'])
  134 + this.updateService(record, responseObj['success'] ? responseObj['data'] : {'nbRes': -2}, responseObj['msg'], initTMin, initTMax)
133 135 },
134 136 failure: function (response, options) {
135 137 const record = ss.getById(options.params['serviceId'])
... ... @@ -143,9 +145,29 @@ Ext.define('amdaDesktop.EpnTapModule', {
143 145 /**
144 146 Update the nb_result field of the services store (see `EpnTapUI.servicesStore`), according to the field values in `serviceFilterPanel`.
145 147 */
146   - updateService: function (record, nbRes, info) {
147   - record.set('nb_results', nbRes)
  148 + updateService: function (record, data, info, timeMin, timeMax) {
  149 + record.set('nb_results', data['nbRes'])
  150 + record.set('time_min', data['tMin'])
  151 + record.set('time_max', data['tMax'])
148 152 record.set('info', info)
  153 +
  154 + const tMinService = Ext.Date.parse(data['tMin'], 'd/m/Y H:i:s')
  155 + const tMaxService = Ext.Date.parse(data['tMax'], 'd/m/Y H:i:s')
  156 +
  157 + if(tMinService !== null && (this.servicesStore.tMin === null || tMinService < this.servicesStore.tMin)) {
  158 + this.servicesStore.tMin = tMinService
  159 + if(timeMin === null) {
  160 + this.timeSelector.setStartTime(this.servicesStore.tMin)
  161 + }
  162 + }
  163 +
  164 + if(tMaxService !== null && (this.servicesStore.tMax === null || tMaxService > this.servicesStore.tMax)) {
  165 + this.servicesStore.tMax = tMaxService
  166 + if(timeMax === null) {
  167 + this.timeSelector.setStopTime(this.servicesStore.tMax)
  168 + }
  169 + }
  170 +
149 171 this.servicesStore.sort()
150 172 loadMask.hide()
151 173 },
... ...
js/app/views/EpnTapUI.js
... ... @@ -100,6 +100,8 @@ This list is used to fill the `servicesGrid` table, which is updated by `EpnTapM
100 100 Ext.create('Ext.data.Store', {
101 101 storeId: 'servicesStore',
102 102 autoLoad: true,
  103 + tMin: null,
  104 + tMax: null,
103 105 fields: [
104 106 {name: 'id', type: 'string'},
105 107 {name: 'short_name', type: 'string'},
... ... @@ -114,7 +116,9 @@ Ext.create(&#39;Ext.data.Store&#39;, {
114 116 {name: 'created', type: 'date', dateFormat: 'c'},
115 117 {name: 'updated', type: 'date', dateFormat: 'c'},
116 118 {name: 'nb_results', type: 'integer'},
117   - {name: 'info', type: 'string'}
  119 + {name: 'info', type: 'string'},
  120 + {name: 'time_min', type: 'string'},
  121 + {name: 'time_max', type: 'string'}
118 122 ],
119 123 proxy: {
120 124 type: 'ajax',
... ... @@ -243,6 +247,7 @@ Ext.define(&#39;App.util.Format&#39;, {
243 247 const sData = Ext.util.Format.sanitizeData(data)
244 248 const infoColor = sData['nb_results'] === -2 ? 'IndianRed' : 'green'
245 249 const info = sData.info.length > 0 ? '<p style="color:' + infoColor + '">' + sData.info + '</p>' : ''
  250 + const timeInfo = sData['time_min'] !== '-' || sData['time_min'] !== '-' ? '<p>Time period: from ' + sData['time_min'] + ' to ' + sData['time_min'] + '</p>' : ''
246 251  
247 252 const colums = ['short_name', 'res_title', 'ivoid', 'access_url', 'table_name', 'content_type', 'creator_seq', 'content_level', 'reference_url', 'created', 'updated']
248 253 // noinspection ES6ConvertVarToLetConst
... ... @@ -254,7 +259,7 @@ Ext.define(&#39;App.util.Format&#39;, {
254 259 details += '<li><b>' + Ext.util.Format.prettify(colums[cKey]) + '</b>: ' + val + '</li>'
255 260 }
256 261 }
257   - return info + '<ul>' + details + '</ul>'
  262 + return info + timeInfo + '<ul>' + details + '</ul>'
258 263 },
259 264 'service.text': function (data, metadata, record) {
260 265 const serviceName = Ext.util.Format.prettify(data.replace('.epn_core' , ''))
... ...
js/app/views/IntervalUI.js
... ... @@ -71,6 +71,18 @@ Ext.define(&#39;amdaUI.IntervalUI&#39;, {
71 71  
72 72 this.updateDuration();
73 73 },
  74 + setStartTime: function(startTime) {
  75 + var form = this.findParentByType('form').getForm();
  76 + var startField = form.findField('startDate');
  77 + startField.setValue(startTime);
  78 + this.updateDuration();
  79 + },
  80 + setStopTime: function(stopTime) {
  81 + var form = this.findParentByType('form').getForm();
  82 + var stopField = form.findField('stopDate');
  83 + stopField.setValue(stopTime);
  84 + this.updateDuration();
  85 + },
74 86  
75 87 /**
76 88 Get the start time field value.
... ...
php/epntap.php
... ... @@ -12,8 +12,8 @@ switch ($action) {
12 12 case 'getServices':
13 13 $response = getServices();
14 14 break;
15   - case 'getNbResults':
16   - $response = getNbResults();
  15 + case 'updateNbResults':
  16 + $response = updateNbResults();
17 17 break;
18 18 case 'getGranules':
19 19 $response = getGranules();
... ... @@ -64,6 +64,7 @@ function resolver() {
64 64 }
65 65  
66 66 function request($access_url, $query) {
  67 + error_log($query);
67 68 $votMgr = new VOTableMgr;
68 69 $params = 'FORMAT=votable&LANG=ADQL&REQUEST=doQuery';
69 70 $url = $access_url . '/sync?' . $params . '&QUERY=' . urlencode(preg_replace('/\s+/', ' ', $query)); // remove also multiple whitespaces
... ... @@ -93,68 +94,80 @@ function getServices() {
93 94 AND 1=ivo_nocasematch(detail_value, 'ivo://vopdc.obspm/std/EpnCore%') AND table_name LIKE '%.epn_core' ORDER BY short_name, table_name";
94 95  
95 96 $regNumber = 0;
  97 + $r = [];
  98 + $lastErrorMessage = null;
96 99 for(; $regNumber<count($registriesURL) ; $regNumber++) {
97   - $response = request($registriesURL[$regNumber], $query);
98   - if($response['success']) {
  100 + $r = request($registriesURL[$regNumber], $query);
  101 + if($r['success']) {
99 102 // Add several other parameters and remove AMDA
100   - for($j=0 ; $j<count($response['data']) ; $j++) {
101   - $response['data'][$j]['id'] = generateServiceId($response['data'][$j]);
102   - $response['data'][$j]['nb_results'] = -1;
103   - $response['data'][$j]['info'] = 'Please make a query.';
104   - if($response['data'][$j]['id'] == 'cdpp/amda/amdadb') {
105   - array_splice($response['data'], $j, 1);
  103 + for($j=0 ; $j<count($r['data']) ; $j++) {
  104 + $r['data'][$j]['id'] = generateServiceId($r['data'][$j]);
  105 + $r['data'][$j]['nb_results'] = -1;
  106 + $r['data'][$j]['info'] = 'Please make a query.';
  107 + if($r['data'][$j]['id'] == 'cdpp/amda/amdadb') {
  108 + array_splice($r['data'], $j, 1);
106 109 $j-=1;
107 110 }
108 111 }
109   - if(isset($lastErrorMesage)) {
110   - $response['msg'] = $lastErrorMesage;
  112 + if(!is_null($lastErrorMessage)) {
  113 + $r['msg'] = $lastErrorMessage;
111 114 }
112 115 break;
113 116 } else {
114   - $lastErrorMesage = 'Last tried registry (' . $registriesURL[$regNumber] . ') returned this error: ' . $response['msg'] . '.';
  117 + $lastErrorMesage = 'Last tried registry (' . $registriesURL[$regNumber] . ') returned this error: ' . $r['msg'] . '.';
115 118 }
116 119 }
117   - if(!$response['success']) {
118   - $response['msg'] = 'Can not access any of these registries: ' . implode(', ', $registriesURL) . ', last error message is ' . $lastErrorMesage;
  120 +
  121 + if(!$r['success']) {
  122 + $r['msg'] = 'Can not access any of these registries: ' . implode(', ', $registriesURL) . ', last error message is ' . $lastErrorMessage;
119 123 }
120   - return $response;
  124 + return $r;
121 125 }
122 126  
123   -function getNbResults() {
  127 +function updateNbResults() {
124 128 $p = getParams(['url', 'tableName', 'targetNames', 'productTypes', 'timeMin', 'timeMax']);
125   - $query = "SELECT COUNT(*) AS nb_rows FROM " . $p['tableName'] . createFilter($p['targetNames'], $p['productTypes'], $p['timeMin'], $p['timeMax']);
126   - $response = request($p['url'], $query);
127   - if($response['success']) {
128   - $response['success'] = false;
129   - $response['msg'] = 'The service returned a bad value, can not get the number of results.';
130   - if(count($response['data']) < 1) {
131   - error_log('getNbResults error: Too few returned raws.');
132   - } else if(count($response['data']) > 1) {
133   - error_log('getNbResults error: Too many returned raws.');
134   - } else if(!array_key_exists(0, $response['data'])) {
135   - error_log('getNbResults error: cant find raw item 0');
136   - } else if(is_null($response['data'][0])) {
137   - error_log('getNbResults error: The returned raw is null.');
138   - } else if(!array_key_exists("nb_rows", $response['data'][0])) {
139   - error_log('getNbResults error: cant find nb_rows.');
140   - } else if(!is_numeric($response['data'][0]['nb_rows'])) {
141   - error_log('getNbResults error: The returned value is not a number.');
  129 + $select = "SELECT COUNT(*) AS nb_res, min(time_min) as time_min, max(time_max) as time_max";
  130 + $from = "FROM " . $p['tableName'];
  131 + $where = createFilter($p['targetNames'], $p['productTypes'], $p['timeMin'], $p['timeMax']);
  132 + $r = request($p['url'], "$select $from $where");
  133 + if($r['success']) {
  134 + $r['success'] = false;
  135 + $r['msg'] = 'The service returned a bad value, can not get the number of results.';
  136 +
  137 + if(count($r['data']) < 1) {
  138 + error_log('updateNbResults error: Too few returned rows.');
  139 + } else if(count($r['data']) > 1) {
  140 + error_log('updateNbResults error: Too many returned rows.');
  141 + } else if(!array_key_exists(0, $r['data'])) {
  142 + error_log('updateNbResults error: cant find raw item 0');
  143 +
  144 + } else if(is_null($r['data'][0])) {
  145 + error_log('updateNbResults error: The returned raw is null.');
  146 + } else if(!array_key_exists("nb_res", $r['data'][0])) {
  147 + var_dump($r['data'][0]);
  148 + error_log('updateNbResults error: cant find nb_res value in the row: ' . json_encode($r['data'][0]));
  149 + } else if(!is_numeric($r['data'][0]['nb_res'])) {
  150 + error_log('updateNbResults error: The returned value is not a number.');
142 151 } else {
143   - $response['success'] = true;
144   - $response['data'] = (int)($response['data'][0]['nb_rows']);
145   - $response['msg'] = 'The service returned ' . ($response['data'] == 0 ? 'no' : $response['data']) . ' result' . ($response['data'] > 1 ? 's' : '') . ' for the given query.';
  152 + $r['success'] = true;
  153 + $r['data'] = [
  154 + 'nbRes' => (int)($r['data'][0]['nb_res']),
  155 + 'tMin' => JDToDate($r['data'][0]['time_min']),
  156 + 'tMax' => JDToDate($r['data'][0]['time_max'])
  157 + ];
  158 + $r['msg'] = 'The service returned ' . ($r['data']['nbRes'] == 0 ? 'no' : $r['data']['nbRes']) . ' result' . ($r['data']['nbRes'] > 1 ? 's' : '') . ' for the given query.';
146 159 }
147 160 }
148   - return $response;
  161 + return $r;
149 162 }
150 163  
151 164 function getGranules() {
152 165 $p = getParams(['url', 'tableName', 'sort', 'dir', 'targetNames', 'productTypes', 'timeMin', 'timeMax', 'start', 'limit', 'nbRes']);
153   - $sort = is_null($p['sort']) ? 'granule_uid ASC' : ($p['sort'] . ' ' . $p['dir']);
154   - $filter = createFilter($p['targetNames'], $p['productTypes'], $p['timeMin'], $p['timeMax']);
155   - $query = "SELECT TOP " . $p['limit'] . " * FROM " . $p['tableName'] . " $filter ORDER BY $sort OFFSET " . $p['start'];
156   - // error_log('getGranules query: ' . $query);
157   - $response = request($p['url'], $query);
  166 + $select = "SELECT TOP " . $p['limit'] . " *";
  167 + $from = "FROM " . $p['tableName'];
  168 + $where = createFilter($p['targetNames'], $p['productTypes'], $p['timeMin'], $p['timeMax']);
  169 + $order = "ORDER BY " . is_null($p['sort']) ? 'granule_uid ASC' : ($p['sort'] . ' ' . $p['dir']) . " OFFSET " . $p['start'];
  170 + $response = request($p['url'], "$select $from $where $order");
158 171 if($response['success']) {
159 172 $visibleColumns = ['granule_gid', 'obs_id', 'dataproduct_type', 'time_min', 'time_max', 'instrument_name', 'processing_level', 'access_estsize', 'thumbnail_url', 'access_url']; // rest are hidden
160 173 $names = ['granule_gid' => 'GID', 'dataproduct_type' => 'Type', 'processing_level' => 'Proc. lvl', 'access_estsize' => 'Size', 'access_url' => 'URL']; // default: pretty printed key name
... ... @@ -201,7 +214,7 @@ function createFilter($targetNames, $productTypes, $timeMin, $timeMax) {
201 214 if($timeMax) {
202 215 array_push($filter, "time_min <= " . dateToJD($timeMax));
203 216 }
204   - return (count($filter) > 0 ? ' WHERE ' . join(' AND ', $filter) : '');
  217 + return (count($filter) > 0 ? 'WHERE ' . join(' AND ', $filter) : '');
205 218 }
206 219  
207 220 /* Generate a unique service identifier from the service ivoid and the table name. */
... ... @@ -213,4 +226,19 @@ function dateToJD($gregorian_date) {
213 226 list($day, $month, $year, $hours, $minutes, $seconds) = preg_split('/[\s\/:]+/', $gregorian_date);
214 227 return GregorianToJD($month, $day, $year) + $hours/24 + $minutes/(24*60) + $seconds/(24*60*60);
215 228 }
216   -?>
  229 +
  230 +function JDToDate($julianDay) {
  231 + if(is_numeric($julianDay)) {
  232 + $jd = floatval($julianDay);
  233 + $t = fmod($jd - floor($jd) + 0.5, 1);
  234 + $h = floor($t*24);
  235 + $m = floor($t*24*60 - $h*60);
  236 + $s = floor($t*24*60*60 - $h*60*60 - $m*60);
  237 + $d = explode('/', jdtogregorian(floor($jd)));
  238 + $date = sprintf("%02d", $d[1]) . '/' . sprintf("%02d", $d[0]) . '/' . sprintf("%02d", $d[2]);
  239 + $time = sprintf("%02d", $h) . ':' . sprintf("%02d", $m) . ':' . sprintf("%02d", $s);
  240 + return $date . ' ' . $time;
  241 + } else {
  242 + return '-';
  243 + }
  244 +}
... ...