1#!/usr/bin/env python3
  2
  3"""Utilities for processing the satellite information data structure.
  4Obsolete: use satellite.py instead
  5"""
  6
  7import fnmatch
  8from collections import OrderedDict
  9
 10from chart.common.util import nvl
 11from chart.common.decorators import memoized
 12from chart.common.iterators import firstof
 13from chart.common.xml import load_xml
 14from chart.project import settings
 15from chart.common.xml import parsechildstr
 16from chart.common.xml import parsechilddatetime
 17from chart.common.xml import parsechildtimedelta
 18from chart.common.xml import parsechildbool
 19
 20
 21@memoized
 22def satellites():
 23    """A bit of a hack.
 24    Originally `satellites` was a hard coded dictionary.
 25    To change to XML we simply write this function which returns a dictionary based on the XML
 26    file.
 27    """
 28
 29    result = OrderedDict()
 30
 31    for sat_elem in load_xml(settings.SATELLITES).findall('satellite'):
 32        result[parsechildstr(sat_elem, 'scid')] = {
 33            'name': parsechildstr(sat_elem, 'name'),
 34            'operational': parsechildbool(sat_elem, 'operational', True),
 35            'visible': parsechildbool(sat_elem, 'visible', True),
 36            'has_ext_hktm': parsechildbool(sat_elem, 'has-ext-hktm', False),
 37            'launch_date': parsechilddatetime(sat_elem, 'launch-date', None),
 38            # 'orbital': parsechildbool(sat_elem, 'orbital'),
 39            # 'instruments': par
 40            'orbit_duration': parsechildtimedelta(sat_elem, 'orbit-duration', None),
 41            # 'processing_frequency': parsechildtimedelta(sat_elem, 'processing_frequency', None)
 42            }
 43
 44    return result
 45
 46
 47def is_scid(scid):
 48    """Is `scid` a valid scid? If true, returns the correct SCID"""
 49
 50    if scid.upper() in satellites():
 51        return scid.upper()
 52
 53    else:
 54        return False
 55
 56
 57# def uses_orbits(scid):
 58# return satellites()[scid]['orbital']
 59
 60
 61# @memoized
 62# def processing_frequency(scid):
 63#     """Return a natural frequency for a satellite - either an orbit or an hour.
 64#     TBD: Check if this is actually used.
 65#     """
 66
 67#     for s in satellites():
 68#         if s['scid'] == scid:
 69#             return s['processing_frequency']
 70
 71
 72def get_scids(glob=None, operational=None, visible=None):
 73    """Return a generator yielding a list of scids, with an optional wildcard filter.
 74    If `operational` is not None, filter for that value.
 75
 76    >> print list(get_scids())  # doctest: +ELLIPSIS
 77    [...'M02'...'N18'...'N19'...]
 78
 79    >> print list(get_scids('N*'))
 80    ['N18', 'N19']
 81
 82    """
 83
 84    return list(firstof(get_satellites(glob, operational, visible)))
 85
 86
 87def get_satellites(glob=None, operational=None, visible=None):
 88    """Return a generator that yields tuples of (`scid`, `info`) where `info`
 89    is a dictionary of information from `satellites`.
 90    Glob is a comma separated of search terms with wildcard expansion.
 91    """
 92
 93    for name, info in satellites().items():
 94        if glob is not None:
 95            match = False
 96            for term in glob.split(','):
 97                if fnmatch.fnmatchcase(name, term):
 98                    match = True
 99
100            if not match:
101                continue
102
103        if operational is not None and info['operational'] != operational:
104            continue
105
106        if visible is not None and info['visible'] != visible:
107            continue
108
109        yield name, info
110
111
112@memoized
113def get_orbit_duration(sid, default=None):
114    """Return nominal orbit duration of scid."""
115    # obsolete, remove, use sid.satellite.orbit_duration instead
116    if sid.satellite is not None:
117        return sid.satellite.orbit_duration
118
119    else:
120        return default
121
122    # if sid in satellites():
123        # return nvl(satellites()[sid]['orbit_duration'], default)
124
125    # else:
126        # return default
127
128
129def get_launch_date(scid):
130    """Return the launch date for satellite `scid`, or None if not yet launched."""
131    return satellites()[scid]['launch_date']
132
133
134def main():
135    """Command line entry point."""
136    def test_get_scids(args):
137        """allow: common/scid.py get_scids 'M02'
138        """
139        search = args.scid
140        if search is None:
141            search = args.params[0]
142
143        for scid in get_scids(search):
144            print(scid)
145
146    from chart.common.args import ArgumentParser
147    actions = {'get_scids': test_get_scids}
148    parser = ArgumentParser()
149    parser.add_argument('--scid', '-s',
150                        type=ArgumentParser.scid)
151    parser.add_argument('action',
152                        choices=list(actions.keys()))
153    parser.add_argument('params', nargs='*')
154    args = parser.parse_args()
155    actions[args.action](args)
156
157if __name__ == '__main__':
158    main()