Small bug fixes in attachment handling

This commit is contained in:
bwaide 2025-02-11 09:09:25 +01:00
parent 7ef2cfc299
commit 59da191fa3
3 changed files with 29 additions and 5 deletions

View File

@ -7,6 +7,7 @@ import hashlib
from email.utils import parsedate_to_datetime from email.utils import parsedate_to_datetime
from pathlib import Path from pathlib import Path
from datetime import datetime from datetime import datetime
import re
from config import get_config from config import get_config
from stats import add_statistic from stats import add_statistic
@ -53,6 +54,26 @@ def should_extract_attachment(part):
return file_ext in ATTACHMENT_WHITELIST and file_size < MAX_ATTACHMENT_SIZE and file_size > MIN_ATTACHMENT_SIZE return file_ext in ATTACHMENT_WHITELIST and file_size < MAX_ATTACHMENT_SIZE and file_size > MIN_ATTACHMENT_SIZE
# Helper function to sanitize filenames
def make_filename_safe(filename):
"""
Sanitizes a filename by:
- Removing any "file://" prefix.
- Replacing characters not allowed on most systems (< > : " / \ | ? *) with an underscore.
- Stripping leading/trailing whitespace.
Args:
filename (str): The original filename.
Returns:
str: A safe filename.
"""
# Remove any URL scheme if present
filename = filename.replace("file://", "")
# Replace illegal characters with underscore
safe_filename = re.sub(r'[<>:"/\\|?*]', '_', filename)
return safe_filename.strip()
def save_attachment(part, email_date_str): def save_attachment(part, email_date_str):
""" """
Save an extracted attachment to disk in a month-based folder (e.g., "2023_10") Save an extracted attachment to disk in a month-based folder (e.g., "2023_10")
@ -70,8 +91,9 @@ def save_attachment(part, email_date_str):
if not filename: if not filename:
return None return None
# Normalize the filename to remove trailing query strings etc. # Normalize the filename (if you have a normalize_filename function, otherwise, use the safe version)
filename = normalize_filename(filename) # Here we simply sanitize the filename.
filename = make_filename_safe(filename)
# Strip extra quotes from the date string, if present. # Strip extra quotes from the date string, if present.
date_str = email_date_str.strip('"') date_str = email_date_str.strip('"')
@ -81,7 +103,6 @@ def save_attachment(part, email_date_str):
email_date = parsedate_to_datetime(date_str) email_date = parsedate_to_datetime(date_str)
except Exception as e: except Exception as e:
try: try:
# Fallback: try using datetime.strptime with the appropriate format.
email_date = datetime.strptime(date_str, "%d-%b-%Y %H:%M:%S %z") email_date = datetime.strptime(date_str, "%d-%b-%Y %H:%M:%S %z")
except Exception as e2: except Exception as e2:
print(f"Date parsing failed for: {date_str}") print(f"Date parsing failed for: {date_str}")

View File

@ -27,7 +27,7 @@
}, },
"archive_folder": "Archive", "archive_folder": "Archive",
"folder_prefix": "INBOX.", "folder_prefix": "INBOX.",
"root_folder": "[Gmail]/All Mail", "root_folder": "[Gmail]/Alle Nachrichten",
"labels_as_flagged": [ "labels_as_flagged": [
"Important", "Important",
"[Gmail]/Important", "[Gmail]/Important",

View File

@ -10,6 +10,9 @@ from dotenv import load_dotenv
from tqdm import tqdm from tqdm import tqdm
import shlex import shlex
import socket
import ssl # For _ssl.SSLError
from config import logger from config import logger
from config import get_config from config import get_config
@ -198,7 +201,7 @@ def reconnect_imap(server, email, password, max_retries=5):
conn.login(email, password) conn.login(email, password)
logger.debug(f"Reconnected successfully to {server}") logger.debug(f"Reconnected successfully to {server}")
return conn return conn
except imaplib.IMAP4.abort as e: except (imaplib.IMAP4.abort, socket.error, ssl.SSLError) as e:
logger.debug(f"Reconnect attempt {attempt + 1} failed: {e}") logger.debug(f"Reconnect attempt {attempt + 1} failed: {e}")
time.sleep(2 ** attempt) # Exponential backoff time.sleep(2 ** attempt) # Exponential backoff
attempt += 1 attempt += 1