black shift
This commit is contained in:
@@ -30,46 +30,46 @@ T = TypeVar("T")
|
||||
|
||||
class EmailProcessingContext:
|
||||
"""Context manager for email processing that marks emails as unread if an error occurs."""
|
||||
|
||||
|
||||
def __init__(self, email_message, mark_as_read: bool = True):
|
||||
self.email_message = email_message
|
||||
self.mark_as_read = mark_as_read
|
||||
self.success = False
|
||||
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
if exc_type is not None or not self.success:
|
||||
# If an exception occurred or processing wasn't successful, mark as unread
|
||||
try:
|
||||
if hasattr(self.email_message, 'mark_as_unread'):
|
||||
if hasattr(self.email_message, "mark_as_unread"):
|
||||
self.email_message.mark_as_unread()
|
||||
print(f"[EMAIL_SERVICE] Marked email as UNREAD due to processing error: {exc_val if exc_val else 'Unknown error'}")
|
||||
print(
|
||||
f"[EMAIL_SERVICE] Marked email as UNREAD due to processing error: {exc_val if exc_val else 'Unknown error'}"
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"[EMAIL_SERVICE] Failed to mark email as unread: {str(e)}")
|
||||
elif self.mark_as_read:
|
||||
# If processing was successful and mark_as_read is True, ensure it's marked as read
|
||||
try:
|
||||
if hasattr(self.email_message, 'mark_as_read'):
|
||||
if hasattr(self.email_message, "mark_as_read"):
|
||||
self.email_message.mark_as_read()
|
||||
except Exception as e:
|
||||
print(f"[EMAIL_SERVICE] Failed to mark email as read: {str(e)}")
|
||||
return False # Don't suppress exceptions
|
||||
|
||||
|
||||
def publish_payload_to_redis(
|
||||
payload, filename: str, mail_info: dict
|
||||
) -> bool:
|
||||
def publish_payload_to_redis(payload, filename: str, mail_info: dict) -> bool:
|
||||
# Create message document
|
||||
# Use base64 encoding for binary payloads to ensure proper transmission
|
||||
if isinstance(payload, bytes):
|
||||
encoded_payload = base64.b64encode(payload).decode('utf-8')
|
||||
encoded_payload = base64.b64encode(payload).decode("utf-8")
|
||||
is_base64 = True
|
||||
else:
|
||||
encoded_payload = payload
|
||||
is_base64 = False
|
||||
|
||||
|
||||
message = {
|
||||
"filename": filename,
|
||||
"payload": encoded_payload,
|
||||
@@ -79,12 +79,14 @@ def publish_payload_to_redis(
|
||||
"uuid": str(uuid4()), # Use UUID
|
||||
**mail_info,
|
||||
}
|
||||
|
||||
|
||||
# Publish to Redis channel
|
||||
result = redis_pubsub.publisher.publish(REDIS_CHANNEL, message)
|
||||
|
||||
|
||||
if result.status:
|
||||
print(f"[EMAIL_SERVICE] Published message with filename: {filename} to channel: {REDIS_CHANNEL}")
|
||||
print(
|
||||
f"[EMAIL_SERVICE] Published message with filename: {filename} to channel: {REDIS_CHANNEL}"
|
||||
)
|
||||
return True
|
||||
else:
|
||||
print(f"[EMAIL_SERVICE] Publish error: {result.error}")
|
||||
@@ -126,7 +128,7 @@ def app():
|
||||
port = Config.EMAIL_PORT
|
||||
username = Config.EMAIL_USERNAME
|
||||
password = Config.EMAIL_PASSWORD
|
||||
|
||||
|
||||
box = EmailBox(host=host, port=port, username=username, password=password)
|
||||
if not box:
|
||||
return Exception("Mailbox not found")
|
||||
@@ -136,41 +138,51 @@ def app():
|
||||
filter_mail = OR(FROM(Config.MAILBOX), FROM(Config.MAIN_MAIL))
|
||||
filter_print = f"{Config.MAILBOX} & {Config.MAIN_MAIL}"
|
||||
|
||||
# Determine if this is the first run of the day
|
||||
# Determine if this is the first run of the day
|
||||
# Store last run date in a file
|
||||
last_run_file = "/tmp/email_service_last_run.json"
|
||||
current_date = datetime.now().strftime("%Y-%m-%d")
|
||||
days_to_check, full_check = 7, 90 # Default to 7 days
|
||||
|
||||
|
||||
try:
|
||||
if os.path.exists(last_run_file):
|
||||
with open(last_run_file, 'r') as f:
|
||||
with open(last_run_file, "r") as f:
|
||||
last_run_data = json.load(f)
|
||||
last_run_date = last_run_data.get('last_run_date')
|
||||
|
||||
last_run_date = last_run_data.get("last_run_date")
|
||||
|
||||
# If this is the first run of a new day, check 90 days
|
||||
if last_run_date != current_date:
|
||||
days_to_check = full_check
|
||||
print(f"[EMAIL_SERVICE] First run of the day. Checking emails from the past {days_to_check} days")
|
||||
print(
|
||||
f"[EMAIL_SERVICE] First run of the day. Checking emails from the past {days_to_check} days"
|
||||
)
|
||||
else:
|
||||
print(f"[EMAIL_SERVICE] Subsequent run today. Checking emails from the past {days_to_check} days")
|
||||
print(
|
||||
f"[EMAIL_SERVICE] Subsequent run today. Checking emails from the past {days_to_check} days"
|
||||
)
|
||||
else:
|
||||
# If no last run file exists, this is the first run ever - check 90 days
|
||||
days_to_check = full_check
|
||||
print(f"[EMAIL_SERVICE] First run detected. Checking emails from the past {days_to_check} days")
|
||||
print(
|
||||
f"[EMAIL_SERVICE] First run detected. Checking emails from the past {days_to_check} days"
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"[EMAIL_SERVICE] Error reading last run file: {str(e)}. Using default of {days_to_check} days")
|
||||
|
||||
print(
|
||||
f"[EMAIL_SERVICE] Error reading last run file: {str(e)}. Using default of {days_to_check} days"
|
||||
)
|
||||
|
||||
# Update the last run file
|
||||
try:
|
||||
with open(last_run_file, 'w') as f:
|
||||
json.dump({'last_run_date': current_date}, f)
|
||||
with open(last_run_file, "w") as f:
|
||||
json.dump({"last_run_date": current_date}, f)
|
||||
except Exception as e:
|
||||
print(f"[EMAIL_SERVICE] Error writing last run file: {str(e)}")
|
||||
|
||||
|
||||
# Calculate the date to check from
|
||||
check_since_date = (datetime.now() - timedelta(days=days_to_check)).strftime("%d-%b-%Y")
|
||||
|
||||
check_since_date = (datetime.now() - timedelta(days=days_to_check)).strftime(
|
||||
"%d-%b-%Y"
|
||||
)
|
||||
|
||||
for folder in mail_folders:
|
||||
if folder.name == "INBOX":
|
||||
# Search for emails since the calculated date
|
||||
@@ -184,27 +196,33 @@ def app():
|
||||
# Use context manager to handle errors and mark email as unread if needed
|
||||
with EmailProcessingContext(banks_mail) as ctx:
|
||||
try:
|
||||
headers = {k.lower(): v for k, v in banks_mail.headers.items()}
|
||||
headers = {
|
||||
k.lower(): v for k, v in banks_mail.headers.items()
|
||||
}
|
||||
mail_info = {
|
||||
"from": headers["from"],
|
||||
"to": headers["to"],
|
||||
"subject": headers["subject"],
|
||||
"date": str(headers["date"]),
|
||||
}
|
||||
|
||||
|
||||
# Process the email and publish to Redis
|
||||
success = read_email_and_publish_to_redis(
|
||||
email_message=email_message, mail_info=mail_info
|
||||
)
|
||||
|
||||
|
||||
# Set success flag for the context manager
|
||||
ctx.success = success
|
||||
|
||||
|
||||
if success:
|
||||
print(f"[EMAIL_SERVICE] Successfully processed email with subject: {mail_info['subject']}")
|
||||
print(
|
||||
f"[EMAIL_SERVICE] Successfully processed email with subject: {mail_info['subject']}"
|
||||
)
|
||||
else:
|
||||
print(f"[EMAIL_SERVICE] No matching attachments found in email with subject: {mail_info['subject']}")
|
||||
|
||||
print(
|
||||
f"[EMAIL_SERVICE] No matching attachments found in email with subject: {mail_info['subject']}"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
print(f"[EMAIL_SERVICE] Error processing email: {str(e)}")
|
||||
# The context manager will mark the email as unread
|
||||
@@ -213,8 +231,8 @@ def app():
|
||||
if __name__ == "__main__":
|
||||
print("=== Starting Email Service with Redis Pub/Sub ===")
|
||||
print(f"Publishing to channel: {REDIS_CHANNEL}")
|
||||
time.sleep(20) # Wait for 20 seconds to other services to kick in
|
||||
|
||||
time.sleep(20) # Wait for 20 seconds to other services to kick in
|
||||
|
||||
while True:
|
||||
print("\n[EMAIL_SERVICE] Checking for new emails...")
|
||||
app()
|
||||
|
||||
Reference in New Issue
Block a user