~jstys-z/helioviewer.org/client5

« back to all changes in this revision

Viewing changes to install/org/helioviewer/db.py

  • Committer: Keith Hughitt
  • Date: 2011-05-26 19:28:41 UTC
  • mfrom: (402.1.667 hv)
  • Revision ID: keith.hughitt@nasa.gov-20110526192841-5xmuft9jsm52pzih
Helioviewer.org 2.2.0 Release

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# -*- coding: utf-8 -*-
2
 
import sys, os
 
2
"""Helioviewer.org installer database functions"""
 
3
import sys
 
4
import os
3
5
 
4
 
def setupDatabaseSchema(adminuser, adminpass, dbname, dbuser, dbpass, mysql):
5
 
    ''' Sets up Helioviewer.org database schema '''
 
6
def setup_database_schema(adminuser, adminpass, dbname, dbuser, dbpass, mysql):
 
7
    """Sets up Helioviewer.org database schema"""
6
8
    if mysql:
7
9
        import MySQLdb
8
10
        adaptor = MySQLdb
10
12
        import pgdb
11
13
        adaptor = pgdb
12
14
 
13
 
    createDB(adminuser, adminpass, dbname, dbuser, dbpass, mysql, adaptor)
 
15
    create_db(adminuser, adminpass, dbname, dbuser, dbpass, mysql, adaptor)
14
16
 
15
17
    # connect to helioviewer database
16
 
    cursor = getDatabaseCursor(dbname, dbuser, dbpass, mysql)
 
18
    cursor = get_db_cursor(dbname, dbuser, dbpass, mysql)
17
19
 
18
 
    createSourceTable(cursor)
19
 
    createObservatoryTable(cursor)
20
 
    createInstrumentTable(cursor)
21
 
    createDetectorTable(cursor)
22
 
    createMeasurementTable(cursor)
23
 
    createImageTable(cursor)
24
 
    createStatisticsTable(cursor)
25
 
    updateImageTableIndex(cursor)
 
20
    create_datasource_table(cursor)
 
21
    create_observatory_table(cursor)
 
22
    create_instrument_table(cursor)
 
23
    create_detector_table(cursor)
 
24
    create_measurement_table(cursor)
 
25
    create_image_table(cursor)
 
26
    create_screenshots_table(cursor)
 
27
    create_movies_table(cursor)
 
28
    create_movie_formats_table(cursor)
 
29
    create_youtube_table(cursor)
 
30
    create_statistics_table(cursor)
 
31
    update_image_table_index(cursor)
26
32
 
27
33
    return cursor
28
34
 
29
 
def getDatabaseCursor(dbname, dbuser, dbpass, mysql):
30
 
    ''' Creates a database connection '''
 
35
def get_db_cursor(dbname, dbuser, dbpass, mysql):
 
36
    """Creates a database connection"""
31
37
    if mysql:
32
38
        import MySQLdb
33
39
    else:
34
40
        import pgdb
35
41
    
36
42
    if mysql:
37
 
        db = MySQLdb.connect(use_unicode=True, charset = "utf8", host="localhost", db=dbname, user=dbuser, passwd=dbpass)
 
43
        db = MySQLdb.connect(use_unicode=True, charset = "utf8", 
 
44
                             host="localhost", db=dbname, user=dbuser, 
 
45
                             passwd=dbpass)
38
46
    else:
39
 
        db = pgdb.connect(use_unicode=True, charset = "utf8", database=dbname, user=dbuser, password=dbpass)
 
47
        db = pgdb.connect(use_unicode=True, charset = "utf8", database=dbname, 
 
48
                          user=dbuser, password=dbpass)
40
49
    
 
50
    db.autocommit(True)
41
51
    return db.cursor()
42
52
 
43
 
def checkDBInfo(adminuser, adminpass, mysql):
44
 
    ''' Validate database login information '''
 
53
def check_db_info(adminuser, adminpass, mysql):
 
54
    """Validate database login information"""
45
55
    try:
46
56
        if mysql:
47
 
            import MySQLdb
 
57
            try:
 
58
                import MySQLdb
 
59
            except ImportError as e:
 
60
                print(e)
 
61
                return False
48
62
            db = MySQLdb.connect(user=adminuser, passwd=adminpass)
49
63
        else:
50
64
            import pgdb
51
 
            db = pgdb.connect(database="postgres", user=adminuser, password=adminpass)
52
 
    except MySQLdb.Error, e:
53
 
        print e
 
65
            db = pgdb.connect(database="postgres", user=adminuser, 
 
66
                              password=adminpass)
 
67
    except MySQLdb.Error as e:
 
68
        print(e)
54
69
        return False
55
70
 
56
71
    db.close()
57
72
    return True
58
73
 
59
 
def createDB(adminuser, adminpass, dbname, dbuser, dbpass, mysql, adaptor):
60
 
    ''' Creates database
61
 
        TODO (2009/08/18) Catch error case when db already exists, and gracefully exit '''
 
74
def create_db(adminuser, adminpass, dbname, dbuser, dbpass, mysql, adaptor):
 
75
    """Creates Helioviewer database
 
76
    
 
77
    TODO (2009/08/18) Catch error when db already exists and gracefully exit
 
78
    """
 
79
    
 
80
    create_str = "CREATE DATABASE IF NOT EXISTS %s;" % dbname
 
81
    grant_str = "GRANT ALL ON %s.* TO '%s'@'localhost' IDENTIFIED BY '%s';" % (
 
82
                dbname, dbuser, dbpass)
 
83
    
62
84
    if mysql:
63
85
        try:
64
86
           db = adaptor.connect(user=adminuser, passwd=adminpass)
65
87
           cursor = db.cursor()
66
 
           cursor.execute("CREATE DATABASE IF NOT EXISTS %s;" % dbname)
67
 
           cursor.execute("GRANT ALL ON %s.* TO '%s'@'localhost' IDENTIFIED BY '%s';" % (dbname, dbuser, dbpass))
68
 
        except adaptor.Error, e:
69
 
            print "Error: " + e.args[1]
 
88
           cursor.execute(create_str)
 
89
           cursor.execute(grant_str)
 
90
        except adaptor.Error as e:
 
91
            print("Error: " + e.args[1])
70
92
            sys.exit(2)
71
93
    else:
72
94
        try:
73
 
            db = adaptor.connect(database="postgres", user=adminuser, password=adminpass)
 
95
            db = adaptor.connect(database="postgres", user=adminuser, 
 
96
                                 password=adminpass)
74
97
            cursor = db.cursor()
75
 
            cursor.execute("CREATE DATABASE IF NOT EXISTS %s;" % dbname)
76
 
            cursor.execute("GRANT ALL ON %s.* TO '%s'@'localhost' IDENTIFIED BY '%s';" % (dbname, dbuser, dbpass))
77
 
        except Exception, e:
78
 
            print "Error: " + e.args[1]
 
98
            cursor.execute(create_str)
 
99
            cursor.execute(grant_str)
 
100
        except Exception as e:
 
101
            print("Error: " + e.args[1])
79
102
            sys.exit(2)
80
103
 
81
104
    cursor.close()
82
105
 
83
 
def createImageTable(cursor):
 
106
def create_image_table(cursor):
 
107
    """Creates table to store image information"""
84
108
    sql = \
85
 
    '''CREATE TABLE `images` (
 
109
    """CREATE TABLE `images` (
86
110
      `id`            INT unsigned NOT NULL auto_increment,
87
111
      `filepath`      VARCHAR(255) NOT NULL,
88
112
      `filename`      VARCHAR(255) NOT NULL,
89
 
      `date`          datetime NOT NULL default '0000-00-00 00:00:00',
 
113
      `date`          datetime NOT NULL,
90
114
      `sourceId`    SMALLINT unsigned NOT NULL,
91
115
      PRIMARY KEY  (`id`), KEY `date_index` (`sourceId`,`date`) USING BTREE
92
 
    ) DEFAULT CHARSET=ascii;'''
 
116
    ) DEFAULT CHARSET=ascii;"""
93
117
    cursor.execute(sql)
94
118
 
95
 
def createSourceTable(cursor):
 
119
def create_datasource_table(cursor):
 
120
    """Creates a table with the known datasources"""
96
121
    cursor.execute(
97
 
    '''CREATE TABLE `datasources` (
 
122
    """CREATE TABLE `datasources` (
98
123
        `id`            SMALLINT unsigned NOT NULL,
99
124
        `name`          VARCHAR(127) NOT NULL,
100
125
        `description`   VARCHAR(255),
105
130
        `layeringOrder` TINYINT NOT NULL,
106
131
        `enabled`       BOOLEAN NOT NULL,
107
132
      PRIMARY KEY  (`id`)
108
 
    ) DEFAULT CHARSET=utf8;''')
 
133
    ) DEFAULT CHARSET=utf8;""")
109
134
 
110
 
    cursor.execute('''
 
135
    cursor.execute("""
111
136
    INSERT INTO `datasources` VALUES
112
137
        (0, 'EIT 171', 'SOHO EIT 171', 0, 0, 0, 2, 1, 0),
113
138
        (1, 'EIT 195', 'SOHO EIT 195', 0, 0, 0, 4, 1, 0),
128
153
        (16, 'AIA 1700', 'SDO AIA 1700',  2, 4, 5, 10, 1, 0),
129
154
        (17, 'AIA 4500', 'SDO AIA 4500',  2, 4, 5, 11, 1, 0),
130
155
        (18, 'HMI Int', 'SDO HMI Int', 2, 5, 6, 12, 1, 0),
131
 
        (19, 'HMI Mag', 'SDO HMI Mag', 2, 5, 6, 13, 1, 0);
132
 
    ''')
133
 
 
134
 
def createObservatoryTable(cursor):
135
 
    """ Creates table to store observatory information """
136
 
 
137
 
    cursor.execute('''
 
156
        (19, 'HMI Mag', 'SDO HMI Mag', 2, 5, 6, 13, 1, 0),
 
157
        (20, 'EUVI-A 171', 'STEREO A EUVI 171', 3, 6, 7, 2, 1, 0),
 
158
        (21, 'EUVI-A 195', 'STEREO A EUVI 195', 3, 6, 7, 4, 1, 0),
 
159
        (22, 'EUVI-A 284', 'STEREO A EUVI 284', 3, 6, 7, 6, 1, 0),
 
160
        (23, 'EUVI-A 304', 'STEREO A EUVI 304', 3, 6, 7, 7, 1, 0),
 
161
        (24, 'EUVI-B 171', 'STEREO B EUVI 171', 4, 6, 7, 2, 1, 0),
 
162
        (25, 'EUVI-B 195', 'STEREO B EUVI 195', 4, 6, 7, 4, 1, 0),
 
163
        (26, 'EUVI-B 284', 'STEREO B EUVI 284', 4, 6, 7, 6, 1, 0),
 
164
        (27, 'EUVI-B 304', 'STEREO B EUVI 304', 4, 6, 7, 7, 1, 0),
 
165
        (28, 'COR1-A', 'STEREO A COR1', 3, 6, 8, 14, 2, 0),
 
166
        (29, 'COR2-A', 'STEREO A COR2', 3, 6, 9, 14, 3, 0),
 
167
        (30, 'COR1-B', 'STEREO B COR1', 4, 6, 8, 14, 2, 0),
 
168
        (31, 'COR2-B', 'STEREO B COR2', 4, 6, 9, 14, 3, 0);
 
169
    """)
 
170
 
 
171
def create_observatory_table(cursor):
 
172
    """Creates table to store observatory information"""
 
173
 
 
174
    cursor.execute("""
138
175
    CREATE TABLE `observatories` (
139
176
      `id`          SMALLINT unsigned NOT NULL,
140
177
      `name`        VARCHAR(255) NOT NULL,
141
178
      `description` VARCHAR(255) NOT NULL,
142
179
       PRIMARY KEY (`id`)
143
 
    ) DEFAULT CHARSET=utf8;''')
 
180
    ) DEFAULT CHARSET=utf8;""")
144
181
 
145
 
    cursor.execute('''
 
182
    cursor.execute("""
146
183
    INSERT INTO `observatories` VALUES
147
184
        (0, 'SOHO', 'Solar and Heliospheric Observatory'),
148
185
        (1, 'TRACE', 'The Transition Region and Coronal Explorer'),
149
 
        (2, 'SDO', 'Solar Dynamics Observatory');        
150
 
    ''')
151
 
 
152
 
def createInstrumentTable(cursor):
153
 
    """ Creates table to store instrument information """
154
 
 
155
 
    cursor.execute('''
 
186
        (2, 'SDO', 'Solar Dynamics Observatory'),
 
187
        (3, 'STEREO_A', 'Solar Terrestrial Relations Observatory Ahead'),
 
188
        (4, 'STEREO_B', 'Solar Terrestrial Relations Observatory Behind');
 
189
    """)
 
190
 
 
191
def create_instrument_table(cursor):
 
192
    """Creates table to store instrument information"""
 
193
 
 
194
    cursor.execute("""
156
195
    CREATE TABLE `instruments` (
157
196
      `id`          SMALLINT unsigned NOT NULL,
158
197
      `name`        VARCHAR(255) NOT NULL,
159
198
      `description` VARCHAR(255) NOT NULL,
160
199
       PRIMARY KEY (`id`)
161
 
    ) DEFAULT CHARSET=utf8;''')
 
200
    ) DEFAULT CHARSET=utf8;""")
162
201
 
163
 
    cursor.execute('''
 
202
    cursor.execute("""
164
203
    INSERT INTO `instruments` VALUES
165
 
        (0, 'EIT',   'Extreme ultraviolet Imaging Telescope'),
166
 
        (1, 'LASCO', 'The Large Angle Spectrometric Coronagraph'),
167
 
        (2, 'MDI',   'Michelson Doppler Imager'),
168
 
        (3, 'TRACE', 'TRACE'),
169
 
        (4, 'AIA',   'Atmospheric Imaging Assembly'),
170
 
        (5, 'HMI',   'Helioseismic and Magnetic Imager');
171
 
    ''')
172
 
 
173
 
 
174
 
 
175
 
def createDetectorTable(cursor):
 
204
        (0, 'EIT',    'Extreme ultraviolet Imaging Telescope'),
 
205
        (1, 'LASCO',  'The Large Angle Spectrometric Coronagraph'),
 
206
        (2, 'MDI',    'Michelson Doppler Imager'),
 
207
        (3, 'TRACE',  'The Transition Region and Coronal Explorer'),
 
208
        (4, 'AIA',    'Atmospheric Imaging Assembly'),
 
209
        (5, 'HMI',    'Helioseismic and Magnetic Imager'),
 
210
        (6, 'SECCHI', 'Sun Earth Connection Coronal and Heliospheric Investigation');
 
211
    """)
 
212
 
 
213
 
 
214
 
 
215
def create_detector_table(cursor):
176
216
    """ Creates table to store detector information """
177
217
 
178
 
    cursor.execute('''
 
218
    cursor.execute("""
179
219
    CREATE TABLE `detectors` (
180
220
      `id`          SMALLINT unsigned NOT NULL,
181
221
      `name`        VARCHAR(255) NOT NULL,
182
222
      `description` VARCHAR(255) NOT NULL,
183
223
       PRIMARY KEY (`id`)
184
 
    ) DEFAULT CHARSET=utf8;''')
 
224
    ) DEFAULT CHARSET=utf8;""")
185
225
 
186
 
    cursor.execute('''
 
226
    cursor.execute("""
187
227
    INSERT INTO `detectors` VALUES
188
 
        (0, 'EIT',   'EIT'),
189
 
        (1, 'C2',    'LASCO C2'),
190
 
        (2, 'C3',    'LASCO C3'),
191
 
        (3, 'MDI',   'MDI'),
192
 
        (4, 'TRACE', 'TRACE'),
193
 
        (5, 'AIA',   'AIA'),
194
 
        (6, 'HMI',   'HMI');
195
 
    ''')
196
 
 
197
 
 
198
 
def createMeasurementTable(cursor):
199
 
    """ Creates table to store measurement information """
200
 
 
201
 
    cursor.execute('''
 
228
        (0, 'EIT',   'Extreme ultraviolet Imaging Telescope'),
 
229
        (1, 'C2',    'Coronograph 2'),
 
230
        (2, 'C3',    'Coronograph 3'),
 
231
        (3, 'MDI',   'Michelson Doppler Imager'),
 
232
        (4, 'TRACE', 'The Transition Region and Coronal Explorer'),
 
233
        (5, 'AIA',   'Atmospheric Imaging Assembly'),
 
234
        (6, 'HMI',   'Helioseismic and Magnetic Imager'),
 
235
        (7, 'EUVI',  'Extreme Ultraviolet Imager'),
 
236
        (8, 'COR1',  'Coronograph 1'),
 
237
        (9, 'COR2',  'Coronograph 2');
 
238
    """)
 
239
 
 
240
 
 
241
def create_measurement_table(cursor):
 
242
    """Creates table to store measurement information"""
 
243
 
 
244
    cursor.execute("""
202
245
    CREATE TABLE `measurements` (
203
246
      `id`          SMALLINT unsigned NOT NULL,
204
247
      `name`        VARCHAR(255) NOT NULL,
205
248
      `description` VARCHAR(255) NOT NULL,
206
249
      `units`       VARCHAR(20)  NOT NULL,
207
250
       PRIMARY KEY (`id`)
208
 
    ) DEFAULT CHARSET=utf8;''')
 
251
    ) DEFAULT CHARSET=utf8;""")
209
252
 
210
 
    cursor.execute(u'''
 
253
    # 2011/05/03: changed from u""" string for Python 3 compatability
 
254
    cursor.execute("""
211
255
    INSERT INTO `measurements` VALUES
212
256
        (0, '94', '94 Ångström extreme ultraviolet', 'Å'),
213
257
        (1, '131', '131 Ångström extreme ultraviolet', 'Å'),
223
267
        (11, '4500', '4500 Ångström extreme ultraviolet', 'Å'),
224
268
        (12, 'continuum', 'Intensitygram', 'DN'),
225
269
        (13, 'magnetogram', 'Magnetogram', 'Mx'),
226
 
        (14, 'white-light', 'White Light', 'DN');
227
 
    ''')
 
270
        (14, 'white-light', 'White Light', 'DN');""")
 
271
    
 
272
def create_movies_table(cursor):
 
273
    """Creates movie table
 
274
    
 
275
    Creates a simple table for storing information about movies built on
 
276
    Helioviewer.org.
 
277
    
 
278
    Note: Region of interest coordinates are stored in arc-seconds even though
 
279
    request is done in pixels in order to make it easier to find screenshots
 
280
    with similar ROIs regardless of scale.
 
281
    """
 
282
    cursor.execute("""
 
283
    CREATE TABLE `movies` (
 
284
      `id`                INT unsigned NOT NULL auto_increment,
 
285
      `timestamp`         TIMESTAMP DEFAULT CURRENT_TIMESTAMP, 
 
286
      `reqStartDate`      datetime NOT NULL,
 
287
      `reqEndDate`        datetime NOT NULL,
 
288
      `imageScale`        FLOAT NOT NULL,
 
289
      `regionOfInterest`  POLYGON NOT NULL,
 
290
      `maxFrames`         INT NOT NULL,
 
291
      `watermark`         BOOLEAN NOT NULL,
 
292
      `dataSourceString`  VARCHAR(255) NOT NULL,
 
293
      `dataSourceBitMask` BIGINT,
 
294
      `frameRate`         FLOAT,
 
295
      `startDate`         datetime,
 
296
      `endDate`           datetime,
 
297
      `numFrames`         INT,
 
298
      `width`             INT,
 
299
      `height`            INT,
 
300
      `procTime`          INT,
 
301
       PRIMARY KEY (`id`)
 
302
    ) DEFAULT CHARSET=utf8;""")
 
303
    
 
304
def create_movie_formats_table(cursor):
 
305
    """Creates movie formats table
 
306
    
 
307
    Creates a table to keep track of the processing status for each format 
 
308
    (mp4, web, etc) movie that needsto be created for a given movie request.
 
309
    """
 
310
    cursor.execute("""
 
311
    CREATE TABLE `movieFormats` (
 
312
      `id`                INT unsigned NOT NULL auto_increment,
 
313
      `movieId`           INT unsigned NOT NULL,
 
314
      `format`            VARCHAR(255) NOT NULL,
 
315
      `status`            VARCHAR(255) NOT NULL,
 
316
      `procTime`          INT,
 
317
       PRIMARY KEY (`id`)
 
318
    ) DEFAULT CHARSET=utf8;""")
 
319
    
 
320
def create_youtube_table(cursor):
 
321
    """Creates a table to track shared movie uploads.
 
322
    
 
323
    Creates table to keep track of movies that have been uploaded to YouTube 
 
324
    and shared with other Helioviewer users.
 
325
    """
 
326
    cursor.execute("""
 
327
    CREATE TABLE `youtube` (
 
328
      `id`          INT unsigned NOT NULL auto_increment,
 
329
      `movieId`     INT unsigned NOT NULL,
 
330
      `youtubeId`   VARCHAR(16) NOT NULL,
 
331
      `timestamp`   TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
 
332
      `title`       VARCHAR(100) NOT NULL,
 
333
      `description` VARCHAR(5000) NOT NULL,
 
334
      `keywords`    VARCHAR(500) NOT NULL,
 
335
      `shared`      BOOLEAN NOT NULL,
 
336
       PRIMARY KEY (`id`)
 
337
    ) DEFAULT CHARSET=utf8;""")
 
338
    
 
339
def create_screenshots_table(cursor):
 
340
    """Creates screenshot table
 
341
    
 
342
    Creates a simple table for storing information about screenshots built on
 
343
    Helioviewer.org 
 
344
    
 
345
    Note: Region of interest coordinates are stored in arc-seconds even though
 
346
    request is done in pixels in order to make it easier to find screenshots
 
347
    with similar ROIs regardless of scale.
 
348
    """
 
349
    
 
350
    cursor.execute("""
 
351
    CREATE TABLE `screenshots` (
 
352
      `id`                INT unsigned NOT NULL auto_increment,
 
353
      `timestamp`         TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
 
354
      `observationDate`   datetime NOT NULL,
 
355
      `imageScale`        FLOAT,
 
356
      `regionOfInterest`  POLYGON NOT NULL,
 
357
      `watermark`         BOOLEAN DEFAULT TRUE,
 
358
      `dataSourceString`  VARCHAR(255) NOT NULL,
 
359
      `dataSourceBitMask` BIGINT,
 
360
       PRIMARY KEY (`id`)
 
361
    ) DEFAULT CHARSET=utf8;""")
228
362
 
229
 
def createStatisticsTable(cursor):
230
 
    """ Creates a simple table for storing query statistics for selected types of requests """
231
 
    cursor.execute('''
 
363
def create_statistics_table(cursor):
 
364
    """Creates a table to keep query statistics
 
365
    
 
366
    Creates a simple table for storing query statistics for selected types of 
 
367
    requests
 
368
    """
 
369
    cursor.execute("""
232
370
    CREATE TABLE `statistics` (
233
371
      `id`          INT unsigned NOT NULL auto_increment,
234
372
      `timestamp`   TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
235
373
      `action`      VARCHAR(32)  NOT NULL,
236
374
       PRIMARY KEY (`id`)
237
 
    ) DEFAULT CHARSET=utf8;''')
 
375
    ) DEFAULT CHARSET=utf8;""")
238
376
    
239
377
 
240
 
def enableDataSource(cursor, sourceId):
241
 
    """ Marks a single datasource as enabled to signal that there is data for that source """
 
378
def enable_datasource(cursor, sourceId):
 
379
    """Enables datasource
 
380
    
 
381
    Marks a single datasource as enabled to signal that there is data for that
 
382
    source 
 
383
    """
242
384
    cursor.execute("UPDATE datasources SET enabled=1 WHERE id=%d;" % sourceId)
243
385
    
244
 
def updateImageTableIndex(cursor):
245
 
    """ Updates index on images table """
 
386
def update_image_table_index(cursor):
 
387
    """Updates index on images table"""
246
388
    cursor.execute("OPTIMIZE TABLE images;")
247
389
 
248
 
def getDataSources(cursor):
249
 
    ''' Returns a list of the known datasources '''
 
390
def get_datasources(cursor):
 
391
    """Returns a list of the known datasources"""
250
392
    __SOURCE_ID_IDX__ = 0
251
 
    __ENABLED_IDX__   = 1
252
 
    __OBS_NAME_IDX__  = 2
 
393
    __ENABLED_IDX__ = 1
 
394
    __OBS_NAME_IDX__ = 2
253
395
    __INST_NAME_IDX__ = 3
254
 
    __DET_NAME_IDX__  = 4
 
396
    __DET_NAME_IDX__ = 4
255
397
    __MEAS_NAME_IDX__ = 5
256
398
    
257
399
    sql = \
258
 
    ''' SELECT
 
400
    """ SELECT
259
401
            datasources.id as id,
260
402
            datasources.enabled as enabled,
261
403
            observatories.name as observatory,
263
405
            detectors.name as detector,
264
406
            measurements.name as measurement
265
407
        FROM datasources
266
 
            LEFT JOIN observatories ON datasources.observatoryId = observatories.id 
267
 
            LEFT JOIN instruments ON datasources.instrumentId = instruments.id 
268
 
            LEFT JOIN detectors ON datasources.detectorId = detectors.id 
269
 
            LEFT JOIN measurements ON datasources.measurementId = measurements.id;'''
 
408
            LEFT JOIN observatories
 
409
            ON datasources.observatoryId=observatories.id 
 
410
            LEFT JOIN instruments
 
411
            ON datasources.instrumentId=instruments.id 
 
412
            LEFT JOIN detectors
 
413
            ON datasources.detectorId=detectors.id 
 
414
            LEFT JOIN measurements
 
415
            ON datasources.measurementId=measurements.id;"""
270
416
 
271
417
    # Fetch available data-sources
272
418
    cursor.execute(sql)
277
423
    
278
424
    for source in results:
279
425
        # Image parameters
280
 
        obs     = source[__OBS_NAME_IDX__]
281
 
        inst    = source[__INST_NAME_IDX__]
282
 
        det     = source[__DET_NAME_IDX__]
283
 
        meas    = source[__MEAS_NAME_IDX__]
284
 
        id      = int(source[__SOURCE_ID_IDX__])
 
426
        obs = source[__OBS_NAME_IDX__]
 
427
        inst = source[__INST_NAME_IDX__]
 
428
        det = source[__DET_NAME_IDX__]
 
429
        meas = source[__MEAS_NAME_IDX__]
 
430
        id = int(source[__SOURCE_ID_IDX__])
285
431
        enabled = bool(source[__ENABLED_IDX__])
286
432
        
287
433
        # Build tree