diff --git a/2-nomad-config/teamsstatus.nomad.hcl b/2-nomad-config/teamsstatus.nomad.hcl deleted file mode 100644 index cc1e38f..0000000 --- a/2-nomad-config/teamsstatus.nomad.hcl +++ /dev/null @@ -1,345 +0,0 @@ -job "teamsstatus" { - group "app" { - task "teamsstatus" { - driver = "docker" - - config { - image = "python:3.11-slim" - command = "/local/start.sh" - } - - # Template for the startup script - template { - data = <&1 -EOF - destination = "local/start.sh" - perms = "755" - } - - # Template for the token cache - template { - data = "{{ with nomadVar \"nomad/jobs/teamsstatus\" }}{{ .token_cache_json }}{{ end }}" - destination = "local/token_cache.json" - } - - # Template for the Python script - template { - data = <", - "contentType": "text", - } - }, - "expirationDateTime": { - "dateTime": expiration_date_time, - "timeZone": time_zone - }, - } - - headers = { - 'Authorization': f'Bearer {access_token}', - 'Content-Type': 'application/json' - } - - logging.debug(f"Setting status message for user {user_id}") - - response = requests.post(url, json=payload, headers=headers) - - if response.status_code == 200: - logging.info(f"Teams status message set to: {status_message}") - return True - else: - logging.error(f"Failed to set Teams status message: {response.status_code}") - return False - -def _load_segments(): - """Load the journey segments from embedded data into memory""" - global _segments - if _segments: # Already loaded - return - - aest = timezone(timedelta(hours=10)) - - for line in JOURNEY_DATA.split('\n')[1:]: # Skip header - day, start_time, end_time, start_dist, end_dist, start_loc, end_loc = line.strip().split('\t') - - # Convert day and times to datetime in AEST - day_start = datetime.strptime(f"{day} {start_time}", "%d/%m/%Y %H:%M:%S").replace(tzinfo=aest) - day_end = datetime.strptime(f"{day} {end_time}", "%d/%m/%Y %H:%M:%S").replace(tzinfo=aest) - - # Extract the numeric distance values - start_dist = int(start_dist.rstrip('km')) - end_dist = int(end_dist.rstrip('km')) - - _segments.append({ - 'start_time': day_start, - 'end_time': day_end, - 'start_dist': start_dist, - 'end_dist': end_dist, - 'start_location': start_loc, - 'end_location': end_loc - }) - -def get_trip_info(target_datetime): - """Determine the distance travelled and locations for the current datetime.""" - if target_datetime.tzinfo is None: - raise ValueError("target_datetime must be timezone-aware") - - # Ensure data is loaded - _load_segments() - - # Before journey starts - if not _segments or target_datetime < _segments[0]['start_time']: - start_loc = end_loc = _segments[0]['start_location'] - return (0, start_loc, end_loc) - - # During journey - for i, segment in enumerate(_segments): - # If target is before this segment starts - if target_datetime < segment['start_time']: - prev_segment = _segments[i-1] - return (prev_segment['end_dist'], prev_segment['end_location'], prev_segment['end_location']) - - # If target is during this segment, interpolate - if segment['start_time'] <= target_datetime <= segment['end_time']: - # Calculate what fraction of the segment has elapsed - total_seconds = (segment['end_time'] - segment['start_time']).total_seconds() - elapsed_seconds = (target_datetime - segment['start_time']).total_seconds() - fraction = elapsed_seconds / total_seconds - - # Interpolate the distance - distance_delta = segment['end_dist'] - segment['start_dist'] - current_dist = segment['start_dist'] + int(distance_delta * fraction) - return (current_dist, segment['start_location'], segment['end_location']) - - # Between segments - if i < len(_segments) - 1: - next_segment = _segments[i + 1] - if segment['end_time'] < target_datetime < next_segment['start_time']: - return (segment['end_dist'], segment['end_location'], segment['end_location']) - - # After journey ends - return (_segments[-1]['end_dist'], _segments[-1]['end_location'], _segments[-1]['end_location']) - -def build_message(distance, start_loc, end_loc): - """Build the status message based on distance and locations""" - message = "On leave" - if distance > 13144: - message += f", driving my EV back from WA" - elif distance > 2118: - message += f", driving my EV around WA" - elif distance > 0: - message += f", driving my EV to WA" - - if distance > 0: - distance += random.randint(-5, 5) - message += f", {distance}kms travelled so far" - if start_loc != end_loc: - message += f", next stop {end_loc}" - else: - message += f", near {start_loc}" - - message += ", returning July 21st. Contacts {CIM: Grant Gorfine, Inserts: Daniel Pate, DevOps: Rob Duncan, else: Andrian Zubovic}" - return message - -def main(): - test_mode = False # Set to True to run in test mode - time_scale = 1 # 1/600 # Set to 1/60 to run at 1 second per minute, 1 for normal speed - - # Set start time to 7:30 AM AEST (UTC+10) on June 8th, 2025 - aest = timezone(timedelta(hours=10)) - start_time = datetime.now(aest) - date_offset = datetime(2025, 6, 8, 7, 30, 0, tzinfo=aest) - start_time - - if test_mode: - logging.info("Running in test mode - status messages will not actually be set") - - app = get_msal_app(client_id = "e6cda941-949f-495e-88f5-10eb45ffa0e7") - - last_token_refresh = 0 - # Token refresh interval (60 minutes in seconds) - TOKEN_REFRESH_INTERVAL = int(60 * 60) # Scale the 1 hour refresh interval - - old_distance = -1 - while True: - try: - # Check if we need to refresh the token - current_time = time.time() - if current_time - last_token_refresh >= TOKEN_REFRESH_INTERVAL or last_token_refresh == 0: - logging.info("Acquiring/refreshing access token...") - access_token = acquire_token(app, scope = ["https://graph.microsoft.com/Presence.ReadWrite"]) - if not access_token: - logging.error("Failed to acquire token") - exit(1) - last_token_refresh = current_time - logging.info("Token successfully refreshed") - - # Set the status message - now = datetime.now(aest) # Get current time in AEST - if time_scale != 1: - # Adjust the current time based on the time scale - now = start_time + (now - start_time) / time_scale - now += date_offset # Adjust to the target start time - distance, start_loc, end_loc = get_trip_info(now) # We only need distance for comparison - if distance != old_distance: - message = build_message(distance, start_loc, end_loc) - timestamp = now.strftime("%Y-%m-%d %H:%M:%S %Z") - if not test_mode: - logging.info(f"[{timestamp}] Message: {message}") - success = set_teams_status_message( - access_token = access_token, - user_id = "1b625872-d8a8-42f4-b237-dfa6d8062360", - status_message = message, - ) - else: - logging.info(f"[TEST MODE] [{timestamp}] Message: {message}") - success = True - else: - logging.debug("Status message has not changed, skipping update") - success = True - old_distance = distance - - if success: - wait_time = 900 * time_scale # Scale the 15 minute wait time - logging.debug(f"Waiting {wait_time} seconds before updating status message again...") - time.sleep(wait_time) - else: - last_token_refresh = 0 # Reset token refresh time on failure - except KeyboardInterrupt: - logging.info("Status update interrupted by user. Exiting...") - break - except Exception as e: - logging.error(f"An error occurred: {e}") - time.sleep(300) # Wait 5 minutes before retrying - - return 0 - -if __name__ == "__main__": - exit(main()) - -EOF - destination = "local/teamsstatus_standalone.py" - } - - resources { - cpu = 500 - memory = 256 - } - } - - restart { - attempts = 3 - interval = "5m" - delay = "15s" - mode = "fail" - } - } -} diff --git a/2-nomad-config/teamsstatus.tf b/2-nomad-config/teamsstatus.tf deleted file mode 100644 index 4510c3a..0000000 --- a/2-nomad-config/teamsstatus.tf +++ /dev/null @@ -1,12 +0,0 @@ -# Disabled - -# resource "nomad_job" "teamsstatus" { -# jobspec = file("${path.module}/teamsstatus.nomad.hcl") -# } - -# resource "nomad_variable" "teamsstatus" { -# path = "nomad/jobs/teamsstatus" -# items = { -# token_cache_json = file("${path.module}/token_cache.json") -# } -# }