Spaces:
Sleeping
Sleeping
import json | |
import logging | |
from datetime import datetime, timedelta | |
from flask import request, jsonify | |
from dateutil import parser, tz | |
from routes import app | |
logger = logging.getLogger(__name__) | |
def get_next_working_time(dt, work_start_hour, work_end_hour): | |
while True: | |
if dt.weekday() >= 5: | |
# Weekend, move to next working day | |
dt += timedelta(days=1) | |
dt = dt.replace(hour=work_start_hour, minute=0, second=0, microsecond=0) | |
else: | |
work_start = dt.replace(hour=work_start_hour, minute=0, second=0, microsecond=0) | |
work_end = dt.replace(hour=work_end_hour, minute=0, second=0, microsecond=0) | |
if dt < work_start: | |
return work_start | |
elif dt >= work_end: | |
# After working hours, move to next day | |
dt += timedelta(days=1) | |
dt = dt.replace(hour=work_start_hour, minute=0, second=0, microsecond=0) | |
else: | |
# During working hours | |
return dt | |
def compute_working_seconds(start_dt, end_dt, work_start_hour, work_end_hour): | |
if start_dt >= end_dt: | |
return 0 | |
total_seconds = 0 | |
current_dt = start_dt | |
while current_dt < end_dt: | |
if current_dt.weekday() >= 5: | |
# Weekend, move to next working day | |
current_dt += timedelta(days=1) | |
current_dt = current_dt.replace(hour=work_start_hour, minute=0, second=0, microsecond=0) | |
continue | |
work_start = current_dt.replace(hour=work_start_hour, minute=0, second=0, microsecond=0) | |
work_end = current_dt.replace(hour=work_end_hour, minute=0, second=0, microsecond=0) | |
if current_dt < work_start: | |
current_dt = work_start | |
if current_dt >= work_end: | |
# Move to next working day | |
current_dt += timedelta(days=1) | |
continue | |
period_end = min(work_end, end_dt) | |
total_seconds += (period_end - current_dt).total_seconds() | |
current_dt = period_end | |
return total_seconds | |
def get_base_subject(subject): | |
while subject.startswith("RE: "): | |
subject = subject[4:] | |
return subject | |
def mail_time(): | |
data = request.get_json() | |
logging.info("Data received for evaluation: {}".format(data)) | |
users = {} | |
for user in data.get("users", []): | |
name = user["name"] | |
office_hours = user["officeHours"] | |
users[name] = { | |
"name": name, | |
"timezone": office_hours["timeZone"], | |
"start_hour": office_hours["start"], | |
"end_hour": office_hours["end"], | |
"response_times": [] | |
} | |
# Build threads based on base subjects | |
threads = {} | |
for email in data.get("emails", []): | |
subject = email["subject"] | |
base_subject = get_base_subject(subject) | |
if base_subject not in threads: | |
threads[base_subject] = [] | |
email['parsed_time'] = parser.isoparse(email['timeSent']) | |
threads[base_subject].append(email) | |
# Process emails in threads | |
for thread_emails in threads.values(): | |
# Sort emails by parsed_time | |
thread_emails.sort(key=lambda e: e['parsed_time']) | |
for i in range(1, len(thread_emails)): | |
current_email = thread_emails[i] | |
previous_email = thread_emails[i - 1] | |
sender = current_email['sender'] | |
sender_info = users[sender] | |
sender_tz = tz.gettz(sender_info['timezone']) | |
# Time when sender received the previous email, in sender's timezone | |
previous_email_time = previous_email['parsed_time'].astimezone(sender_tz) | |
# Time when sender sent the reply, in sender's timezone | |
current_email_time = current_email['parsed_time'].astimezone(sender_tz) | |
work_start_hour = sender_info['start_hour'] | |
work_end_hour = sender_info['end_hour'] | |
# Adjusted start time: when sender could start responding | |
adjusted_start_time = get_next_working_time(previous_email_time, work_start_hour, work_end_hour) | |
# Compute working seconds between adjusted_start_time and current_email_time | |
working_seconds = compute_working_seconds(adjusted_start_time, current_email_time, work_start_hour, work_end_hour) | |
sender_info['response_times'].append(working_seconds) | |
# Compute average response times | |
result = {} | |
for user_name, user_info in users.items(): | |
response_times = user_info['response_times'] | |
if response_times: | |
avg_response_time = sum(response_times) / len(response_times) | |
else: | |
avg_response_time = 0 | |
avg_response_time = int(round(avg_response_time)) | |
result[user_name] = avg_response_time | |
logging.info("Computed result: {}".format(result)) | |
return jsonify(result) | |