Coverage for mapology/countries_razor.py: 60.00%

48 statements  

« prev     ^ index     » next       coverage.py v7.4.1, created at 2024-02-04 20:27:38 +00:00

1"""Occam's razor for countries data set of the natural earth project.""" 

2 

3import copy 

4import json 

5import logging 

6import os 

7import pathlib 

8import sys 

9from typing import List, Union, no_type_check 

10 

11ENCODING = 'utf-8' 

12 

13APP_ALIAS = 'mapology' 

14APP_ENV = APP_ALIAS.upper() 

15DEBUG = bool(os.getenv(f'{APP_ENV}_DEBUG', '')) 

16log = logging.getLogger() # Temporary refactoring: module level logger 

17LOG_FOLDER = pathlib.Path('logs') 

18LOG_FILE = f'{APP_ALIAS}.log' 

19LOG_PATH = pathlib.Path(LOG_FOLDER, LOG_FILE) if LOG_FOLDER.is_dir() else pathlib.Path(LOG_FILE) 

20LOG_LEVEL = logging.INFO 

21 

22 

23@no_type_check 

24def init_logger(name=None, level=None): 

25 """Initialize module level logger""" 

26 global log # pylint: disable=global-statement 

27 

28 log_format = { 

29 'format': '%(asctime)s.%(msecs)03d %(levelname)s [%(name)s]: %(message)s', 

30 'datefmt': '%Y-%m-%dT%H:%M:%S', 

31 # 'filename': LOG_PATH, 

32 'level': LOG_LEVEL if level is None else level, 

33 } 

34 logging.basicConfig(**log_format) 

35 log = logging.getLogger(APP_ENV if name is None else name) 

36 log.propagate = True 

37 

38 

39init_logger(name=APP_ENV, level=logging.DEBUG if DEBUG else None) 

40 

41COUNTRY_STORE = pathlib.Path('country-store.json') 

42COUNTRY_GEOJSON_FRAME = { 

43 'type': 'FeatureCollection', 

44 'name': 'ne_110m_ad_0_ctrs', 

45 'crs': {'type': 'name', 'properties': {'name': 'urn:ogc:def:crs:OGC:1.3:CRS84'}}, 

46 'features': [], 

47} 

48 

49KEPT_PROPS = ( 

50 'featurecla', 

51 'TYPE', 

52 'ADMIN', 

53 'NAME', 

54 'NAME_LONG', 

55 'ABBREV', 

56 'FORMAL_EN', 

57 'NAME_SORT', 

58 'POP_EST', 

59 'POP_YEAR', 

60 'GDP_MD', 

61 'GDP_YEAR', 

62 'ECONOMY', 

63 'INCOME_GRP', 

64 'ISO_A2_EH', 

65 'ISO_A3_EH', 

66 'ISO_N3_EH', 

67 'CONTINENT', 

68 'REGION_UN', 

69 'SUBREGION', 

70 'WIKIDATAID', 

71 'NAME_DE', 

72 'NAME_EN', 

73 'NAME_ES', 

74 'NAME_FR', 

75 'NAME_IT', 

76) 

77 

78 

79def main(argv: Union[List[str], None] = None) -> int: 

80 """Drive the shaving.""" 

81 argv = sys.argv[1:] if argv is None else argv 

82 if len(argv) != 1: 82 ↛ 86line 82 didn't jump to line 86, because the condition on line 82 was never false

83 print('usage: mapology shave countries-to-be-shaved-geo.json-file') 

84 return 2 

85 

86 rococo_path = argv[0] 

87 log.info('Shaving country level data of %s' % rococo_path) 

88 country_store = copy.deepcopy(COUNTRY_GEOJSON_FRAME) 

89 with open(rococo_path, 'rt', encoding=ENCODING) as handle: 

90 rococo = json.load(handle) 

91 

92 log.info('Loaded %d countries' % len(rococo['features'])) 

93 for feature_complete in rococo['features']: 

94 feature = copy.deepcopy(feature_complete) 

95 kept_props = {k: v for k, v in feature['properties'].items() if k in KEPT_PROPS} 

96 feature['properties'] = kept_props 

97 country_store['features'].append(feature) # type: ignore 

98 

99 with open(COUNTRY_STORE, 'wt', encoding=ENCODING) as handle: 

100 json.dump(country_store, handle, indent=1) 

101 

102 log.info('Wrote shaved country level data to conuntry store at %s' % COUNTRY_STORE) 

103 return 0 

104 

105 

106if __name__ == '__main__': 106 ↛ 107line 106 didn't jump to line 107, because the condition on line 106 was never true

107 sys.exit(main(sys.argv[1:]))