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()