Skip to content

Commit 8b4907c

Browse files
Merge pull request #85 from PortableProgrammer/dev
`LOGLEVEL` and `SLACK_CUSTOM_AVAILABLE_STATUS` fixes, minor linting.
2 parents 283314e + e45a521 commit 8b4907c

File tree

3 files changed

+60
-44
lines changed

3 files changed

+60
-44
lines changed

status-light/sources/collaboration/slack.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def get_user_presence(self) -> enum.Status:
5555
'Slack Exception while getting user presence: %s', ex.response['error'])
5656
logger.exception(ex)
5757
return_value = enum.Status.UNKNOWN
58-
except Exception as ex: # pylint: disable=broad-except
58+
except Exception as ex: # pylint: disable=broad-except
5959
logger.warning(
6060
'Exception while getting Slack user presence: %s', ex)
6161
logger.exception(ex)
@@ -80,7 +80,7 @@ def _get_user_info(self, client: WebClient) -> dict | None:
8080
'Slack Exception while getting user info: %s', ex.response['error'])
8181
logger.exception(ex)
8282
return None
83-
except Exception as ex: # pylint: disable=broad-except
83+
except Exception as ex: # pylint: disable=broad-except
8484
logger.warning('Exception while getting Slack user info: %s', ex)
8585
logger.exception(ex)
8686
return None
@@ -103,25 +103,35 @@ def _parse_custom_status(self, client: WebClient,
103103

104104
# For each of the Slack custom statuses, check them in reverse precedence order
105105
# Off, Available, Scheduled, Busy
106-
if self.custom_off_status and custom_status.startswith(tuple(self.custom_off_status)):
106+
if len(self.custom_off_status) > 0 and \
107+
custom_status.startswith(tuple(self.custom_off_status)):
108+
logger.debug(
109+
'Custom status matched custom_off_status: %s', custom_status)
107110
return_value = self.custom_off_status_map
108111

109-
if self.custom_available_status and \
112+
if len(self.custom_available_status) > 0 and \
110113
custom_status.startswith(tuple(self.custom_available_status)):
114+
logger.debug(
115+
'Custom status matched custom_available_status: %s', custom_status)
111116
return_value = self.custom_available_status_map
112117

113-
if self.custom_scheduled_status and \
118+
if len(self.custom_scheduled_status) > 0 and \
114119
custom_status.startswith(tuple(self.custom_scheduled_status)):
120+
logger.debug(
121+
'Custom status matched custom_scheduled_status: %s', custom_status)
115122
return_value = self.custom_scheduled_status_map
116123

117-
if self.custom_busy_status and \
124+
if len(self.custom_busy_status) > 0 and \
118125
custom_status.startswith(tuple(self.custom_busy_status)):
126+
logger.debug(
127+
'Custom status matched custom_busy_status: %s', custom_status)
119128
return_value = self.custom_busy_status_map
120129

121130
# Check for Huddle and Call
122131
if user_info['profile']['huddle_state'] == 'in_a_huddle' or \
123132
user_info['profile']['status_emoji'] == ':slack_call:':
124-
133+
logger.debug('Custom status indicates Huddle (%s) or Call (%s)',
134+
user_info['profile']['huddle_state'], custom_status)
125135
return_value = enum.Status.CALL
126136

127137
except (SystemExit, KeyboardInterrupt):
@@ -131,7 +141,7 @@ def _parse_custom_status(self, client: WebClient,
131141
'Slack Exception while parsing custom status: %s', ex.response['error'])
132142
logger.exception(ex)
133143
return_value = enum.Status.UNKNOWN
134-
except Exception as ex: # pylint: disable=broad-except
144+
except Exception as ex: # pylint: disable=broad-except
135145
logger.warning(
136146
'Exception while parsing Slack custom status: %s', ex)
137147
logger.exception(ex)

status-light/status-light.py

Lines changed: 41 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626

2727
class StatusLight:
2828
"""Provides a structured entry point for the Status-Light application"""
29+
# Instance Logger
30+
logger: logging.Logger = logging.getLogger('status-light')
31+
2932
# Instance Properties
3033
local_env = env.Environment()
3134
current_status: enum.Status = enum.Status.UNKNOWN
@@ -62,27 +65,30 @@ def init(self):
6265
self.local_env.get_log_level()]:
6366

6467
# We failed to gather some environment variables
65-
logger.error('Failed to find all environment variables!')
68+
self.logger.error('Failed to find all environment variables!')
6669
sys.exit(1)
6770

6871
# 23 - Make logging level configurable
69-
logger.info('Setting log level to %s', self.local_env.log_level.name)
70-
logger.setLevel(self.local_env.log_level.value)
72+
self.logger.info('Setting log level to %s', self.local_env.log_level.name)
73+
# Reset the root logger config to our epxected logging level
74+
logging.basicConfig(format='%(asctime)s %(name)s.%(funcName)s %(levelname)s: %(message)s',
75+
datefmt='[%Y-%m-%d %H:%M:%S]', level=self.local_env.log_level.value, force=True)
76+
self.logger.setLevel(self.local_env.log_level.value)
7177

7278
# Depending on the selected sources, get the environment
7379
if enum.StatusSource.WEBEX in self.local_env.selected_sources:
7480
if self.local_env.get_webex():
75-
logger.info('Requested Webex')
81+
self.logger.info('Requested Webex')
7682
self.webex_api.bot_id = self.local_env.webex_bot_id
7783
self.webex_api.person_id = self.local_env.webex_person_id
7884
else:
79-
logger.error(
85+
self.logger.error(
8086
'Requested Webex, but could not find all environment variables!')
8187
sys.exit(1)
8288

8389
if enum.StatusSource.SLACK in self.local_env.selected_sources:
8490
if self.local_env.get_slack():
85-
logger.info('Requested Slack')
91+
self.logger.info('Requested Slack')
8692
self.slack_api.user_id = self.local_env.slack_user_id
8793
self.slack_api.bot_token = self.local_env.slack_bot_token
8894
# 66 - Support Slack custom statuses
@@ -97,44 +103,44 @@ def init(self):
97103
self.slack_api.custom_scheduled_status_map = self.local_env.scheduled_status[
98104
0]
99105
else:
100-
logger.error(
106+
self.logger.error(
101107
'Requested Slack, but could not find all environment variables!')
102108
sys.exit(1)
103109

104110
if enum.StatusSource.OFFICE365 in self.local_env.selected_sources:
105111
if self.local_env.get_office():
106-
logger.info('Requested Office 365')
112+
self.logger.info('Requested Office 365')
107113
self.office_api.appID = self.local_env.office_app_id
108114
self.office_api.appSecret = self.local_env.office_app_secret
109115
self.office_api.tokenStore = self.local_env.office_token_store
110116
# 81 - Make calendar lookahead configurable
111117
self.office_api.lookahead = self.local_env.calendar_lookahead
112118
self.office_api.authenticate()
113119
else:
114-
logger.error(
120+
self.logger.error(
115121
'Requested Office 365, but could not find all environment variables!')
116122
sys.exit(1)
117123

118124
# 47 - Add Google support
119125
if enum.StatusSource.GOOGLE in self.local_env.selected_sources:
120126
if self.local_env.get_google():
121-
logger.info('Requested Google')
127+
self.logger.info('Requested Google')
122128
self.google_api.credentialStore = self.local_env.google_credential_store
123129
self.google_api.tokenStore = self.local_env.google_token_store
124130
# 81 - Make calendar lookahead configurable
125131
self.google_api.lookahead = self.local_env.calendar_lookahead
126132
else:
127-
logger.error(
133+
self.logger.error(
128134
'Requested Google, but could not find all environment variables!')
129135
sys.exit(1)
130136

131137
# Tuya
132138
self.light.device = self.local_env.tuya_device
133-
logger.debug('Retrieved TUYA_DEVICE variable: %s', self.light.device)
139+
self.logger.debug('Retrieved TUYA_DEVICE variable: %s', self.light.device)
134140
tuya_status = self.light.get_status()
135-
logger.debug('Found initial Tuya status: %s', tuya_status)
141+
self.logger.debug('Found initial Tuya status: %s', tuya_status)
136142
if not tuya_status:
137-
logger.error(
143+
self.logger.error(
138144
'Could not connect to Tuya device!')
139145
sys.exit(1)
140146

@@ -151,7 +157,7 @@ def run(self):
151157
self.local_env.active_hours_start,
152158
self.local_env.active_hours_end):
153159

154-
logger.debug('Within Active Hours, polling')
160+
self.logger.debug('Within Active Hours, polling')
155161

156162
# Reset the "outside of active hours" handler
157163
already_handled_inactive_hours = False
@@ -193,7 +199,7 @@ def run(self):
193199
google_status.name.lower())
194200

195201
# 74: Log enums as names, not values
196-
logger.debug(logger_string.lstrip().rstrip(' |'))
202+
self.logger.debug(logger_string.lstrip().rstrip(' |'))
197203

198204
# TODO: Now that we have more than one calendar-based status source,
199205
# build a real precedence module for these
@@ -204,7 +210,7 @@ def run(self):
204210
if (webex_status == enum.Status.UNKNOWN or
205211
webex_status in self.local_env.off_status):
206212
# 74: Log enums as names, not values
207-
logger.debug('Using slack_status: %s',
213+
self.logger.debug('Using slack_status: %s',
208214
slack_status.name.lower())
209215
# Fall through to Slack
210216
self.current_status = slack_status
@@ -214,15 +220,15 @@ def run(self):
214220
and (office_status not in self.local_env.off_status
215221
or google_status not in self.local_env.off_status):
216222

217-
logger.debug('Using calendar-based status')
223+
self.logger.debug('Using calendar-based status')
218224
# Office should take precedence over Google for now
219225
# 74: Log enums as names, not values
220226
if office_status != enum.Status.UNKNOWN:
221-
logger.debug('Using office_status: %s',
227+
self.logger.debug('Using office_status: %s',
222228
office_status.name.lower())
223229
self.current_status = office_status
224230
else:
225-
logger.debug('Using google_status: %s',
231+
self.logger.debug('Using google_status: %s',
226232
google_status.name.lower())
227233
self.current_status = google_status
228234

@@ -232,26 +238,26 @@ def run(self):
232238
status_changed = True
233239

234240
if status_changed:
235-
logger.info('Found new status: %s',
241+
self.logger.info('Found new status: %s',
236242
self.current_status.name.lower())
237243

238244
if not last_transition_result:
239-
logger.warning(
245+
self.logger.warning(
240246
'Last attempt to set status failed. Retrying.')
241247

242248
# If status changed this loop
243249
# 40: or the last transition failed,
244250
if status_changed or not last_transition_result:
245251
# 74: Log enums as names, not values
246-
logger.info('Transitioning to %s',
252+
self.logger.info('Transitioning to %s',
247253
self.current_status.name.lower())
248254
last_transition_result = self._transition_status()
249255

250256
else:
251-
logger.debug('Outside Active Hours, pausing')
257+
self.logger.debug('Outside Active Hours, pausing')
252258

253259
if not already_handled_inactive_hours:
254-
logger.info(
260+
self.logger.info(
255261
'Outside of active hours, transitioning to off')
256262
last_transition_result = self.light.off()
257263
self.last_status = enum.Status.UNKNOWN
@@ -264,14 +270,14 @@ def run(self):
264270
# Sleep for a few seconds
265271
time.sleep(self.local_env.sleep_seconds)
266272
except (SystemExit, KeyboardInterrupt) as ex:
267-
logger.info('%s received; shutting down...',
273+
self.logger.info('%s received; shutting down...',
268274
ex.__class__.__name__)
269275
self.should_continue = False
270276
except Exception as ex: # pylint: disable=broad-except
271-
logger.warning('Exception during main loop: %s', ex)
272-
logger.exception(ex)
277+
self.logger.warning('Exception during main loop: %s', ex)
278+
self.logger.exception(ex)
273279

274-
logger.debug('Turning light off')
280+
self.logger.debug('Turning light off')
275281
self.light.off()
276282

277283
def _transition_status(self) -> bool:
@@ -302,7 +308,7 @@ def _transition_status(self) -> bool:
302308
# just turn the light off and warn about it
303309
# 74: Log enums as names, not values
304310
else:
305-
logger.warning('Called with an invalid status: %s',
311+
self.logger.warning('Called with an invalid status: %s',
306312
self.current_status.name.lower())
307313
return_value = self.light.off()
308314

@@ -316,7 +322,7 @@ def _transition_status(self) -> bool:
316322
# Default to INFO level until we load the environment
317323
logging.basicConfig(format='%(asctime)s %(name)s.%(funcName)s %(levelname)s: %(message)s',
318324
datefmt='[%Y-%m-%d %H:%M:%S]', level=logging.INFO)
319-
logger: logging.Logger = logging.getLogger('status-light')
325+
global_logger: logging.Logger = logging.getLogger('status-light')
320326

321327

322328
def receive_signal(signal_number, frame): # pylint: disable=unused-argument
@@ -331,9 +337,9 @@ def receive_signal(signal_number, frame): # pylint: disable=unused-argument
331337
try:
332338
signal_name = signal.Signals(signal_number).name
333339
except ValueError as value_ex:
334-
logger.warning(
340+
global_logger.warning(
335341
'Exception encountered converting %s to signal.Signals: %s', signal_number, value_ex)
336-
logger.warning('Signal received: %s', signal_name)
342+
global_logger.warning('Signal received: %s', signal_name)
337343
status_light.should_continue = False
338344

339345

@@ -342,10 +348,10 @@ def receive_signal(signal_number, frame): # pylint: disable=unused-argument
342348

343349
def main():
344350
"""Provides the entry point for the application"""
345-
logger.info('Startup')
351+
global_logger.info('Startup')
346352
status_light.init()
347353
status_light.run()
348-
logger.info('Shutdown')
354+
global_logger.info('Shutdown')
349355

350356

351357
if __name__ == '__main__':

status-light/utility/env.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class Environment:
3737
# 66 - Add Slack custom status support
3838
slack_off_status: list[str] = [
3939
':no_entry: Out of Office', ':airplane:', ':palm_tree: Vacationing']
40-
slack_available_status: list[str] = ['']
40+
slack_available_status: list[str] = []
4141
slack_scheduled_status: list[str] = [':spiral_calendar_pad: In a meeting']
4242
slack_busy_status: list[str] = [
4343
':no_entry_sign:', ':no_entry: Do not Disturb']

0 commit comments

Comments
 (0)