""" AUTHOR: Khushal P Soonderji DATE: CREATED: Wed, 26th Nov, 2025 UPDATED: Wed, 26th Nov, 2025 OBJECTIVE: To achieve so-and-so-objective... REFERENCES: N/A DOWNLOADS: N/A """ # ***************************************************************************************************************** # ***** **** # *** IMPORT *** # ***** **** # ***************************************************************************************************************** # To make sibling directories accessible for imports: import sys sys.path.append(".") sys.path.append("..") # For system-level activities: import os import copy # To work with date and time: import time import datetime # To work with tabulate data: import pandas as pd # Cosec-related: from cosec_web.cosec_web import CosecWeb # TCAOFF-related: from helpers import tcaoff # My utils: from utils_v2.system import files from utils_v2.string import json from utils_v2.string import regex from utils_v2.date_time import date_time # To work with datatypes: from typing import List, Dict, Any from collections import defaultdict # To run a cron-like scheduler: from apscheduler.schedulers.background import BackgroundScheduler # Needed functions: from cron.reports import * # ***************************************************************************************************************** # ***** **** # *** MACROS / ONE-TIME INIT *** # ***** **** # ***************************************************************************************************************** # --- Nothing Yet # ***************************************************************************************************************** # ***** **** # *** VARIABLES *** # ***** **** # ***************************************************************************************************************** # --- Nothing Yet # ***************************************************************************************************************** # ***** **** # *** CLASSES *** # ***** **** # ***************************************************************************************************************** # --- Nothing Yet # ***************************************************************************************************************** # ***** **** # *** FUNCTIONS *** # ***** **** # ***************************************************************************************************************** def manual_attendance( cosec_creds: dict, tcaoff_creds: dict, target_date: date_time.datetime ) -> None: """ To mark yesterday's attendance. :param cosec_creds: The credentials to use to log into Matrix COSEC. :param tcaoff_creds: The credentials to use to log into TCAOFF. :param target_date: The date to sync attendance. :return: None. """ print("ATTENDANCE SYNC") # Try the whole process once: try: # Log in to TCAOFF: tcaoff.login(tcaoff_creds) # IN-OUT SUMMARY REPORT: try: # Get the previous day's In/Out Summary and then wait # for the driver's resources to get freed: success = get_in_out_summary( cosec_creds = cosec_creds, target_date = target_date, cache_file = prev_day_in_out_summary_cache_file ) # Sync data between Cosec and TCAOFF: if success: print("IN/OUT SUMMARY: Sync'ing with TCAOFF") sync_attendance_to_tcaoff( tcaoff_creds = tcaoff_creds, cosec_in_out_summary = json.from_file(prev_day_in_out_summary_cache_file), ) # If something goes wrong: except Exception as e: print("IN-OUT SUMMARY FETCH FAILED!") raise # Log out from TCAOFF: tcaoff.logout(tcaoff_creds) # If TCAOFF's login or logout fails: except Exception as e: print("REPORT CRON FAILED LOOP!") print("EXCEPTION:", e) tcaoff.logout(tcaoff_creds) # ***************************************************************************************************************** # ***** **** # *** MAIN PROGRAM *** # ***** **** # ***************************************************************************************************************** if __name__ == "__main__": import argparse parser = argparse.ArgumentParser(description = "Manual attendance sync. script.") parser.add_argument( "--from-date", help = "The date from which you want to sync attendance.", default = date_time.get_current_ist_date_time() ) parser.add_argument( "--to-date", help = "The date till when you want to sync attendance.", default = date_time.get_current_ist_date_time() ) args = parser.parse_args() args.from_date = date_time.parse_date_time(args.from_date, timezone = date_time.TIMEZONE_IST) args.to_date = date_time.parse_date_time(args.to_date, timezone = date_time.TIMEZONE_IST) if args.from_date > args.to_date: args.from_date, args.to_date = args.to_date, args.from_date print("From Date:", args.from_date) print(" To Date:", args.to_date) dates_list = [args.from_date] while args.from_date < args.to_date: args.from_date = args.from_date + datetime.timedelta(days = 1) dates_list.append(args.from_date) print(f"DATES ({len(dates_list)}):", dates_list) # Load the credentials: cosec_creds = json.from_file(cosec_creds_file) tcaoff_creds = json.from_file(tcaoff_creds_file) # Run the attendance for each specified date: for target_date in dates_list: print("TARGET DATE:", target_date) manual_attendance( cosec_creds = cosec_creds, tcaoff_creds = tcaoff_creds, target_date = date_time.parse_date_time( target_date, date_formats = [ "%Y%m%d", "%Y-%m-%d" ], ) + date_time.timedelta( hours = 23, minutes = 59 ) )