This file is indexed.

/usr/share/games/fgo/src/config.py is in fgo 1.3.1-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
"""This module process data from ~/.fgo folder."""

import os
import gzip
import gettext
import codecs
from Tkinter import IntVar, StringVar

from constants import *


class Config:

    """Read/write and store all data from config files."""

    def __init__(self):

        self.ai_path = ''        # Path to FG_ROOT/AI directory.
        self.aircraft_dir = ''   # Path to FG_ROOT/Aircraft directory.
        self.apt_path = ''       # Path to FG_ROOT/Airports/apt.dat.gz file.
        self.metar_path = ''     # Path to FG_ROOT/Airports/metar.dat.gz file.

        self.aircraft_list = []  # List of aircraft names.
        self.aircraft_path = []  # List of paths to each aircraft.
        self.airport_icao = []   # List of ICAO codes for each airport.
        self.airport_name = []   # List of airport names.
        self.airport_rwy = []    # List of runways present in each airport.
        self.scenario_list = []  # List of selected scenarios.
        # List of all aircraft carriers found in AI scenario folder.
        # Each entry format is:
        # ["ship's name", "parking position"... , "scenario's name"]
        self.carrier_list = []

        self.settings = []  # List of all settings read from config file.
        self.text = ''  # String to be shown in command line options window.

        self.aircraft = StringVar()
        self.airport = StringVar()
        self.apt_data_source = IntVar()
        self.carrier = StringVar()
        self.FG_bin = StringVar()
        self.FG_root = StringVar()
        self.FG_scenery = StringVar()
        self.FG_working_dir = StringVar()
        self.filtredAptList = IntVar()
        self.language = StringVar()
        self.park = StringVar()
        self.rwy = StringVar()
        self.scenario = StringVar()
        self.TS = IntVar()
        self.TS_bin = StringVar()
        self.TS_port = StringVar()
        self.TS_scenery = StringVar()
        self.window_geometry = StringVar()

        self.dictionary = {'--aircraft='       : self.aircraft,
                           '--airport='        : self.airport,
                           '--fg-root='        : self.FG_root,
                           '--fg-scenery='     : self.FG_scenery,
                           '--carrier='        : self.carrier,
                           '--parkpos='        : self.park,
                           '--runway='         : self.rwy,
                           'AI_SCENARIOS='     : self.scenario,
                           'APT_DATA_SOURCE='  : self.apt_data_source,
                           'FG_BIN='           : self.FG_bin,
                           'FG_WORKING_DIR='   : self.FG_working_dir,
                           # Obsolete keyword, should be removed in the future.
                           'HOME_DIR='         : self.FG_working_dir,
                           'FILTER_APT_LIST='  : self.filtredAptList,
                           'LANG='             : self.language,
                           'TERRASYNC='        : self.TS,
                           'TERRASYNC_BIN='    : self.TS_bin,
                           'TERRASYNC_PORT='   : self.TS_port,
                           'TERRASYNC_SCENERY=': self.TS_scenery,
                           'WINDOW_GEOMETRY='  : self.window_geometry}

        self._createConfDirectory()
        self.update(first_run=True)

    def makeInstalledAptList(self):
#        if self.apt_data_source:
#            airports = self._findInstalledApt2()
#        else:
#            airports = self._findInstalledApt()

        airports = self._findInstalledApt()

        s = '\n'.join(airports)
        fout = open(INSTALLED_APT, 'w')
        fout.writelines(s)
        fout.close()

    def readCoord(self):
        """Read coordinates list (makes new one if non exists).

        Return dictionary of ICAO codes and its coordinates.

        """
        try:
            # Make new file.
            if not os.path.exists(APT):
                self._makeApt()

            res = {}
            fin = open(APT)

            for line in fin:
                line = line.strip().split('=')
                icao = line[0]
                # Read coordinates.
                coords_line = line[-1].split(';')
                coords = (float(coords_line[0]), float(coords_line[1]))
                res[icao] = coords

            fin.close()
            return res

        except IOError:
            return None

    def readMetarDat(self):
        """Fetch METAR station list from metar.dat.gz file"""
        try:
            fin = gzip.open(self.metar_path)
            res = []
            for line in fin:
                if not line.startswith('#'):
                    line = line.strip()
                    res.append(line)
            fin.close()
            return res
        except IOError:
            return ['IOError']

    def rebuildApt(self):
        """Rebuild apt file."""
        self._makeApt()

    def update(self, path=None, first_run=False):
        """Read config file and update variables.

        path is a path to different than default config file
        first_run specifies if TS_checkbutton and filtered airports list
        will be updated.

        """
        del self.settings
        del self.text
        del self.aircraft_dir
        del self.apt_path
        del self.ai_path
        del self.metar_path
        del self.aircraft_list
        del self.aircraft_path
        del self.airport_icao
        del self.airport_name
        del self.airport_rwy
        del self.scenario_list
        del self.carrier_list

        self.aircraft.set(DEFAULT_AIRCRAFT)
        self.airport.set(DEFAULT_AIRPORT)
        self.apt_data_source.set(0)
        self.carrier.set('None')
        self.FG_bin.set('')
        self.FG_root.set('')
        self.FG_scenery.set('')
        self.FG_working_dir.set('')
        self.language.set('')
        self.park.set('None')
        self.rwy.set('Default')
        self.scenario.set('')
        self.TS_bin.set('')
        self.TS_port.set('')
        self.TS_scenery.set('')
        if first_run:
            self.TS.set(0)
            self.filtredAptList.set(0)

        self.settings = self._read(path)
        self.text = self._makeText()

        for line in self.settings:
            cut = line.find('=') + 1

            if cut:
                name = line[:cut]
                value = line[cut:]

                if value:
                    if name in self.dictionary:
                        if name == 'FILTER_APT_LIST=' and not first_run:
                            pass
                        elif name == 'TERRASYNC=' and not first_run:
                            pass
                        else:
                            var = self.dictionary[name]
                            var.set(value)

        self.aircraft_dir = os.path.join(self.FG_root.get(), AIRCRAFT_DIR)

        self.apt_path = os.path.join(self.FG_root.get(), APT_DAT)
        self.ai_path = os.path.join(self.FG_root.get(), AI_DIR)
        self.metar_path = os.path.join(self.FG_root.get(), METAR_DAT)

        self.aircraft_list, self.aircraft_path = self._readAircraft()
        self.scenario_list, self.carrier_list = self._readScenarios()
        self.updateAptLists()

        self._setLanguage(self.language.get())

    def updateAptLists(self):
        self.airport_icao, self.airport_name, self.airport_rwy = \
                                                                self._readApt()

    def write(self, text, path=None):
        """Write options to a file.

        text argument should be a content of text window
        path is a path to different than default config file.

        """
        if not path:
            path = CONFIG
        options = []
        keys = self.dictionary.keys()
        keys.sort()
        # Text
        processed_text = []
        text = text.split('\n')

        for line in text:
            line = line.strip()
            cut = line.find('=') + 1

            if cut:
                name = line[:cut]
                value = line[cut:]
            else:
                name = ''

            if name in keys:
                self.dictionary[name].set(value)
            else:
                if line != CUT_LINE:
                    processed_text.append(line)

        processed_text = '\n'.join(processed_text)

        for k in keys:
            v = self.dictionary[k]
            if v.get() not in ('Default', 'None'):
                # Obsolete keyword, should be removed in the future.
                if k != 'HOME_DIR=':
                    options.append(k + unicode(v.get()))

        s = '\n'.join(options)

        config_out = codecs.open(path, 'w', 'utf-8')
        config_out.write(s + '\n' + CUT_LINE + '\n')
        config_out.write(processed_text)
        config_out.close()

#    def _findInstalledApt(self):
#        """Walk thru all scenery, and find installed airports.
#
#        Return names of btg.gz files that are shorter than five characters.
#
#        """
#        airport_dict = {}
#        sceneries = self.FG_scenery.get().split(':')
#
#        for scenery in sceneries:
#            path = os.path.join(scenery, 'Terrain')
#            if os.path.exists(path):
#                tree = os.walk(path)
#
#                for i in tree:
#                    if i[2]:
#                        for file in i[2]:
#                            file = file.split('.')
#                            try:
#                                if len(file[0]) <= 4 and \
#                                   file[1] == 'btg' and \
#                                   file[2] == 'gz':
#                                    airport_dict[file[0]] = None
#                            except IndexError:
#                                pass
#
#        res = airport_dict.keys()
#        res.sort()
#
#        return res

    def _findInstalledApt(self):
        """Walk thru all scenery and find installed airports.

        Take geographic coordinates from directories names and compare them
        with airports coordinates in apt file.

        The result is a list of matching airports.

        """
        coord_dict = {}
        sceneries = self.FG_scenery.get().split(':')

        for scenery in sceneries:
            path = os.path.join(scenery, 'Terrain')
            if os.path.exists(path):
                for dir in os.listdir(path):
                    p = os.path.join(path, dir)
                    for coords in os.listdir(p):
                        converted = self._stringToCoordinates(coords)
                        coord_dict[converted] = None

        apt_coords = self.readCoord()
        coords = coord_dict.keys()
        res = {}
        for k, v in apt_coords.items():
            for c in coords:
                if v[0] > c[0][0] and v[0] < c[0][1] and \
                   v[1] > c[1][0] and v[1] < c[1][1]:
                    res[k] = None

        res = res.keys()
        res.sort()
        return res

    def _calculateRange(self, coordinates):
        c = coordinates
        if c.startswith('s') or c.startswith('w'):
            c = int(c[1:]) * (-1)
            return c, c + 1
        else:
            c = int(c[1:])
            return c, c + 1

    def _createConfDirectory(self):
        """Create config directory if non exists."""
        if not os.path.exists(DATA_DIR):
            os.mkdir(DATA_DIR)

    def _makeApt(self):
        """Build apt database from apt.dat.gz"""
        if os.path.exists(self.apt_path):
            L = []
            fin = gzip.open(self.apt_path)

            entry = ''
            lat, lon = 0.0, 0.0
            runway_count = 0
            for line in fin:
                # apt.dat is apparently using iso-8859-1 coding,
                # so we need to decode it to unicode.
                line = line.decode('iso-8859-1').encode('utf-8')
                code = line[:2]
                # Find ICAO and airport name.
                if code in ('1 ', '16', '17'):
                    e = line.strip().split()
                    name = [e[4], ' '.join(e[5:])]
                    name = '='.join(name)
                    entry = name
                # Find runways.
                elif code == '10':
                    e = line.strip().split()
                    if e[3] != 'xxx':
                        rwy = e[3]
                        if rwy.endswith('x'):
                            rwy = rwy[:-1]
                        entry += ('=' + rwy)
                    if e[3] != 'xxx':
                        lat += float(e[1])
                        lon += float(e[2])
                        runway_count += 1

                if line == '\n' and entry:
                    lat = lat / runway_count
                    lon = lon / runway_count
                    coords = ';'.join([str(lat), str(lon)])
                    entry = '='.join([entry, coords])
                    L.append(entry)

                    lat, lon = 0.0, 0.0
                    runway_count = 0

            fin.close()
            L.sort()
            fin = open(APT, 'w')
            for i in L:
                fin.write(str(i) + '\n')
            fin.close()

    def _makeText(self):
        """Filter config file entries to be shown in text window."""
        L = []

        for line in self.settings:
            cut = line.find('=') + 1

            if cut:
                name = line[:cut]
                value = line[cut:]

                if name not in self.dictionary:
                    L.append(name + value)

            else:
                L.append(line)

        return '\n'.join(L)

    def _read(self, path=None):
        """Read config file"""
        res = []
        if not path:
            path = CONFIG
        # Use default config if no regular config exists.
        if not os.path.exists(path):
            # Find currently used language.
            try:
                lang_code = gettext.translation(MESSAGES, LOCALE_DIR).info()['language']
            except IOError:
                lang_code = 'en'
            path = os.path.join(DEFAULT_CONFIG_DIR, lang_code)
            if not os.path.isfile(path):
                lang_code = 'en'
                path = os.path.join(DEFAULT_CONFIG_DIR, lang_code)
            # Load presets if exists.
            try:
                presets = codecs.open(PRESETS, encoding='utf-8')
                for line in presets:
                    line = line.strip()
                    if not line.startswith('#'):
                        res.append(line)
                presets.close()
            except IOError:
                pass

        try:
            config_in = codecs.open(path, encoding='utf-8')
            for line in config_in:
                line = line.strip()
                if line != CUT_LINE:
                    res.append(line)
            config_in.close()
            return res
        except IOError:
            return ['']

    def _readAircraft(self):
        """Walk through Aircraft directory and return two sorted lists:
        list of aircraft names and list of paths to them."""
        try:
            n, p = [], []

            for d in os.listdir(self.aircraft_dir):
                path = os.path.join(self.aircraft_dir, d)
                if os.path.isdir(path):
                    for f in os.listdir(path):
                        if f[-8:] == '-set.xml':
                        # Dirty and ugly hack to prevent carrier-set.xml in
                        # seahawk directory to be attached to the aircraft list.
                            if path[-7:] == 'seahawk'\
                            and f == 'carrier-set.xml':
                                pass
                            else:
                                name = f[:-8]
                                n.append([name.lower(), name, path])

            n.sort()

            for i in range(len(n)):
                p.append(n[i][2])
                n[i] = n[i][1]

            return n, p

        except OSError:
            return [''], []

    def _readApt(self):
        """Read apt list (makes new one if non exists).

        Return tuple of three lists:
        airports ICAO codes, airports names, airports runways

        Take a note that those lists are synchronized - each list holds
        information about the same airport at given index.

        """
        try:
            # Make new file.
            if not os.path.exists(APT):
                self._makeApt()

            icao, name, rwy = [], [], []
            fin = open(APT)

            if self.filtredAptList.get():
                installed_apt = self._readInstalledAptList()
                for line in fin:
                    line = line.strip().split('=')
                    if line[0] in installed_apt:
                        installed_apt.remove(line[0])
                        icao.append(line[0])
                        name.append(line[1])
#                        # Make runway list if "apt data source"
#                        # is set to: Standard.
#                        if not self.apt_data_source.get():
                        rwy_list = []
                        for i in line[2:-1]:
                            rwy_list.append(i)
                        rwy_list.sort()
                        rwy.append(rwy_list)

            else:
                for line in fin:
                    line = line.strip().split('=')
                    icao.append(line[0])
                    name.append(line[1])
#                    # Make runway list if "apt data source"
#                    # is set to: Standard.
#                    if not self.apt_data_source.get():
                    rwy_list = []
                    for i in line[2:-1]:
                        rwy_list.append(i)
                    rwy_list.sort()
                    rwy.append(rwy_list)

            fin.close()
            return icao, name, rwy

        except IOError:
            return [], [], []

    def _readInstalledAptList(self):
        """Read locally installed airport list.

        Make new one if non exists.

        """
        if not os.path.exists(INSTALLED_APT):
            self.makeInstalledAptList()

        res = []
        fin = open(INSTALLED_APT)
        for line in fin:
            icao = line.strip()
            res.append(icao)
        fin.close()

        return res

    def _readScenarios(self):
        """Walk through AI scenarios and read carrier data.

        Return list of all scenarios and carrier data list

        """
        try:
            carriers = []
            scenarios = []
            L = []
            is_carrier = False

            for f in os.listdir(self.ai_path):
                path = os.path.join(self.ai_path, f)

                if os.path.isfile(path):
                    if f.lower().endswith('xml'):
                        scenarios.append(f[:-4])
                        fin = open(path)

                        for line in fin:
                            line = line.strip()
                            if '<type>' in line.lower():
                                typ = line[6:-7]
                                if typ.lower() == 'carrier':
                                    is_carrier = True
                                    L = []
                            if '</entry>' in line.lower():
                                if L:
                                    L.append(f[:-4])
                                    carriers.append(L)
                                L = []
                                is_carrier = False
                            if is_carrier:
                                if '<name>' in line.lower():
                                    L.append(line[6:-7])
                        fin.close()
            carriers.sort()
            scenarios.sort()
            return scenarios, carriers

        except OSError:
            return [], []

    def _setLanguage(self, lang):
        # Initialize provided language...
        try:
            L = gettext.translation(MESSAGES, LOCALE_DIR, languages=[lang])
            L.install()
        # ...or fallback to system default.
        except:
            gettext.install(MESSAGES, LOCALE_DIR)

    def _stringToCoordinates(self, coordinates):
        """Convert geo coordinates to decimal format."""
        lat = coordinates[4:]
        lon = coordinates[:4]

        lat_range = self._calculateRange(lat)
        lon_range = self._calculateRange(lon)
        return lat_range, lon_range