UBS-Server / routes /mailtime.py
m-abdur2024's picture
Upload 40 files
0d3476b verified
raw
history blame contribute delete
No virus
5.06 kB
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
@app.route('/mailtime', methods=['POST'])
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)