#!/usr/bin/env python3
# encoding: utf-8
"""
Refactored attendance tracking CGI script.
This script parses Apache access logs to track computer lab attendance.
"""
import os
import sys
import cgi
import json
from datetime import datetime
# Add the parent directory to the path to import our modules
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from attendance_app.log_parser import get_log_files, parse_log_files
from attendance_app.database import SQLiteUserDatabase
from attendance_app.processor import AttendanceProcessor
from attendance_app.excel_output import ExcelGenerator
def parse_form_parameters(form):
"""
Parse CGI form parameters.
Args:
form: CGI FieldStorage object
Returns:
Dictionary with parsed parameters
"""
params = {
'date': form.getvalue('date'),
'from': form.getvalue('from'),
'to': form.getvalue('to'),
'excel': 'excel' in form,
'rooms': {
'GRL': 'GRL' in form,
'ML1': 'ML1' in form,
'ML2': 'ML2' in form,
'IML': 'IML' in form,
'IML-A': 'IML-A' in form,
'IML-B': 'IML-B' in form,
}
}
return params
def main():
"""Main CGI entry point."""
# Determine log directory based on test mode
if sys.argv[-1] == "--test":
logdir = "./"
db_path = "./kguid_test.sqlite3" # Use test DB in test mode
template_path = "./attendancebook_template.xlsx"
else:
logdir = "/var/log/httpd/"
db_path = "/var/www/etc/kguid.sqlite3"
template_path = "./attendancebook_template.xlsx"
# Parse form parameters
form = cgi.FieldStorage()
params = parse_form_parameters(form)
# Parse date/time parameters
try:
from_time = datetime.strptime(
params['date'] + " " + params['from'],
"%Y/%m/%d %H:%M"
)
to_time = datetime.strptime(
params['date'] + " " + params['to'],
"%Y/%m/%d %H:%M"
)
except (ValueError, TypeError) as e:
print("Content-Type: text/plain")
print("Status: 400 Bad Request")
print("")
print(f"Invalid date/time parameters: {e}")
return
# Get relevant log files
logfiles = get_log_files(logdir, from_time)
# Parse log files
db = parse_log_files(logdir, logfiles)
# Process attendance records
with SQLiteUserDatabase(db_path) as user_db:
processor = AttendanceProcessor(user_db.lookup_user)
records = processor.process_events(db, from_time, to_time)
# Output results
if not params['excel']:
# JSON output
print("Content-Type: application/json")
print("")
json.dump(records, sys.stdout)
else:
# Excel output
try:
# Add openpyxl to path if in production
if sys.argv[-1] != "--test":
sys.path.append("/home/tkuro/.local/lib/python3.9/site-packages/")
generator = ExcelGenerator(template_path)
temp_file = generator.generate(records, from_time, to_time, params['rooms'])
# Send Excel file
filename = "attendancebook" + from_time.strftime("%Y%m%d%H%M") + ".xlsx"
with open(temp_file, "rb") as f:
finfo = os.stat(temp_file)
sys.stdout.buffer.write(
b"Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\n"
)
sys.stdout.buffer.write(
f'Content-Disposition: attachment; filename="{filename}"\n'.encode("ascii")
)
sys.stdout.buffer.write(
f'Content-Length: {finfo.st_size}\n\n'.encode("ascii")
)
sys.stdout.buffer.write(f.read())
# Clean up temp file
os.unlink(temp_file)
except ImportError as e:
print("Content-Type: text/plain")
print("Status: 500 Internal Server Error")
print("")
print(f"Excel generation not available: {e}")
except Exception as e:
print("Content-Type: text/plain")
print("Status: 500 Internal Server Error")
print("")
print(f"Error generating Excel: {e}")
if __name__ == "__main__":
main()