Coverage for mapology/indexer.py: 38.69%
103 statements
« prev ^ index » next coverage.py v7.4.1, created at 2024-02-04 20:27:38 +00:00
« prev ^ index » next coverage.py v7.4.1, created at 2024-02-04 20:27:38 +00:00
1#! /usr/bin/env python
2"""Generate index page for the rendered prefix trees."""
3import json
4import os
5import pathlib
6import sys
7from typing import Collection, Dict, List, Union
9import mapology.db as db
10import mapology.template_loader as template
11from mapology import BASE_URL, ENCODING, FOOTER_HTML, FS_PREFIX_PATH, LIB_PATH, PATH_NAV, log
13FeatureDict = Dict[str, Collection[str]]
14PHeaderDict = Dict[str, Collection[str]]
15PFeatureDict = Dict[str, Collection[str]]
17HTML_TEMPLATE = os.getenv('GEO_INDEX_HTML_TEMPLATE', '')
18HTML_TEMPLATE_IS_EXTERNAL = bool(HTML_TEMPLATE)
19if not HTML_TEMPLATE: 19 ↛ 22line 19 didn't jump to line 22, because the condition on line 19 was never false
20 HTML_TEMPLATE = 'prefix_index_template.html'
22AIRP = 'airport'
23RUNW = 'runways'
24FREQ = 'frequencies'
25LOCA = 'localizers'
26GLID = 'glideslopes'
28CC_HINT = 'CC_HINT'
29City = 'City'
30CITY = City.upper()
31ICAO = 'ICAO'
32IC_PREFIX = 'IC_PREFIX'
33ITEM = 'ITEM'
34KIND = 'KIND'
35PATH = 'PATH'
36BASE_URL_TARGET = 'BASE_URL'
37ANCHOR = 'ANCHOR'
38TEXT = 'TEXT'
39URL = 'URL'
40ZOOM = 'ZOOM'
41DEFAULT_ZOOM = 1
42FOOTER_HTML_KEY = 'FOOTER_HTML'
43LIB_PATH_KEY = 'LIB_PATH'
45icao = 'icao_lower'
46ic_prefix_token = 'ic_prefix_lower' # nosec B105
47LAT_LON = 'LAT_LON'
48cc_page = 'cc_page'
49Cc_page = 'Cc_page'
51ATTRIBUTION = f'{KIND} {ITEM} of '
53# GOOGLE_MAPS_URL = f'https://www.google.com/maps/search/?api=1&query={{lat}}%2c{{lon}}' # Map + pin Documented
54GOOGLE_MAPS_URL = 'https://maps.google.com/maps?t=k&q=loc:{lat}+{lon}' # Sat + pin Undocumented
57def main(argv: Union[List[str], None] = None) -> int:
58 """Drive the derivation."""
59 argv = sys.argv[1:] if argv is None else argv
60 if argv: 60 ↛ 64line 60 didn't jump to line 64, because the condition on line 60 was never false
61 print('usage: mapology index')
62 return 2
64 store_index = db.load_index('store')
65 table_index = db.load_index('table')
66 apt_search_index = db.load_index('apt_search')
68 prefixes = sorted(table_index.keys())
69 row_slot_set = set(prefix[0] for prefix in prefixes)
70 col_slot_set = set(prefix[1] for prefix in prefixes)
71 columns = sorted(col_slot_set)
72 rows = sorted(row_slot_set)
74 table = {f'{k}{j}': '<td> </td>' for k in rows for j in columns}
75 log.debug('I\\C |' + ' | '.join(columns))
76 for row in rows:
77 log.debug(row)
79 regions, total_airports = 0, 0
80 for prefix in store_index:
81 with open(store_index[prefix], 'rt', encoding=ENCODING) as handle:
82 prefix_store = json.load(handle)
84 with open(table_index[prefix], 'rt', encoding=ENCODING) as handle:
85 table_store = json.load(handle)
87 regions += 1
88 count = len(prefix_store['features'])
89 total_airports += count
90 region_name = table_store['name']
91 table[prefix] = f'<td><a href="{prefix}/" class="nd" title="{region_name}">{count}</a></td>'
93 tr_pad = 12
94 sp = ' '
95 th_pad = tr_pad + 2
96 data_cols = [f'{sp * tr_pad}<tr>', f'{sp * th_pad}<th>I\\C</th>']
97 for col in columns:
98 data_cols.append(f'{sp * th_pad}<th>{col}</th>')
99 data_cols.append(f'{sp * tr_pad}</tr>')
101 data_rows = []
102 for k in rows:
103 row = [f'<tr><th>{k}</th>']
104 for j in columns:
105 row.append(table[f'{k}{j}'])
106 row.append('\n')
107 data_rows.append(''.join(row))
109 html_dict = {
110 ANCHOR: 'prefix/',
111 LIB_PATH_KEY: LIB_PATH,
112 PATH: PATH_NAV,
113 LAT_LON: '0, 0',
114 ZOOM: str(DEFAULT_ZOOM),
115 BASE_URL_TARGET: BASE_URL,
116 'NUMBER_REGIONS': str(regions),
117 'TOTAL_AIRPORTS': str(total_airports),
118 FOOTER_HTML_KEY: FOOTER_HTML,
119 'DATA_COLS': '\n'.join(data_cols),
120 'DATA_ROWS': ''.join(data_rows),
121 }
122 html_page = template.load_html(HTML_TEMPLATE, HTML_TEMPLATE_IS_EXTERNAL)
123 for key, replacement in html_dict.items():
124 html_page = html_page.replace(key, replacement)
126 html_path = pathlib.Path(FS_PREFIX_PATH, 'index.html')
127 with open(html_path, 'wt', encoding=ENCODING) as html_handle:
128 html_handle.write(html_page)
130 search_index = []
131 for prefix in apt_search_index:
132 with open(apt_search_index[prefix], 'rt', encoding=ENCODING) as handle:
133 search_index.append(json.load(handle))
135 search_index_path = pathlib.Path('apt-search-index.json')
136 with open(search_index_path, 'wt', encoding=ENCODING) as handle:
137 json.dump(search_index, handle, indent=2)
139 return 0
142if __name__ == '__main__': 142 ↛ 143line 142 didn't jump to line 143, because the condition on line 142 was never true
143 sys.exit(main(sys.argv[1:]))