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
|
#!/usr/bin/env python3
import logging
import platform
from dataclasses import dataclass
from typing import Callable, Optional
# Note: this module is fairly early loaded. Be aware of dependencies.
import config
from type.locations import Location
logger = logging.getLogger(__name__)
args = config.add_commandline_args(
f'Global Site Config ({__file__})',
'Args related to global site-specific configuration',
)
args.add_argument(
'--site_config_override_location',
default='NONE',
const='NONE',
nargs='?',
choices=['HOUSE', 'CABIN', 'NONE'],
help='Where are we, HOUSE, CABIN? Overrides standard detection code.',
)
@dataclass
class SiteConfig(object):
location_name: str
location: Location
network: str
network_netmask: str
network_router_ip: str
presence_location: Location
is_anyone_present: Callable
arper_minimum_device_count: int
arper_cache_file: str
def get_location_name():
"""
Where are we?
>>> location = get_location_name()
>>> location == 'HOUSE' or location == 'CABIN'
True
"""
return get_config().location_name
def get_location():
"""
Returns location as an enum instead of a string.
>>> from type.locations import Location
>>> location = get_location()
>>> location == Location.HOUSE or location == Location.CABIN
True
"""
return get_config().location
def is_anyone_present_wrapper(location: Location):
import base_presence
p = base_presence.PresenceDetection()
return p.is_anyone_in_location_now(location)
def other_location() -> str:
hostname = platform.node()
if '.house' in hostname:
location = 'CABIN'
elif '.cabin' in hostname:
location = 'HOUSE'
else:
raise Exception(f"{hostname} doesn't help me know where I'm running?!")
return location
def this_location() -> str:
hostname = platform.node()
if '.house' in hostname:
location = 'HOUSE'
elif '.cabin' in hostname:
location = 'CABIN'
else:
raise Exception(f"{hostname} doesn't help me know where I'm running?!")
return location
def get_config(location_override: Optional[str] = None):
"""
Get a configuration dataclass with information that is
site-specific including the current running location.
>>> cfg = get_config()
>>> cfg.location_name == 'HOUSE' or cfg.location_name == 'CABIN'
True
"""
if location_override is None:
try:
location_override = config.config['site_config_override_location']
except KeyError:
location_override = None
if location_override is None or location_override == 'NONE':
location = this_location()
else:
location = location_override
if location == 'HOUSE':
return SiteConfig(
location_name='HOUSE',
location=Location.HOUSE,
network='10.0.0.0/24',
network_netmask='255.255.255.0',
network_router_ip='10.0.0.1',
presence_location=Location.HOUSE,
is_anyone_present=lambda x=Location.HOUSE: is_anyone_present_wrapper(x),
arper_minimum_device_count=50,
arper_cache_file='/home/scott/cache/.arp_table_cache_house',
)
elif location == 'CABIN':
return SiteConfig(
location_name='CABIN',
location=Location.CABIN,
network='192.168.0.0/24',
network_netmask='255.255.255.0',
network_router_ip='192.168.0.1',
presence_location=Location.CABIN,
is_anyone_present=lambda x=Location.CABIN: is_anyone_present_wrapper(x),
arper_minimum_device_count=15,
arper_cache_file='/home/scott/cache/.arp_table_cache_cabin',
)
else:
raise Exception(f'Unknown site location: {location}')
if __name__ == '__main__':
import doctest
doctest.testmod()
|