171 lines
6.3 KiB
Python
171 lines
6.3 KiB
Python
import sys
|
|
import socket
|
|
import subprocess
|
|
import sqlite3
|
|
from datetime import datetime
|
|
import smtplib
|
|
import os
|
|
from email.message import EmailMessage
|
|
from dotenv import load_dotenv
|
|
import time # Import time module for sleep functionality
|
|
|
|
load_dotenv()
|
|
|
|
# Define server details
|
|
host = "imap.strato.de"
|
|
port = 993
|
|
|
|
# Function to send an email notification
|
|
def send_email(subject, body, to_email):
|
|
smtp_server = os.getenv('SMTP_SERVER')
|
|
smtp_port = int(os.getenv('SMTP_PORT', 587))
|
|
smtp_user = os.getenv('SMTP_USER')
|
|
smtp_password = os.getenv('SMTP_PASSWORD')
|
|
from_email = os.getenv('FROM_EMAIL')
|
|
|
|
msg = EmailMessage()
|
|
msg.set_content(body)
|
|
msg['Subject'] = subject
|
|
msg['From'] = from_email
|
|
msg['To'] = to_email
|
|
|
|
try:
|
|
with smtplib.SMTP(smtp_server, smtp_port) as server:
|
|
server.starttls()
|
|
server.login(smtp_user, smtp_password)
|
|
server.send_message(msg)
|
|
print(f"Error notification sent to {to_email}")
|
|
except Exception as e:
|
|
print(f"Failed to send email: {e}")
|
|
|
|
# Start the infinite loop
|
|
while True:
|
|
try:
|
|
# Check if mail server is active
|
|
try:
|
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
sock.settimeout(1)
|
|
result = sock.connect_ex((host, port))
|
|
if result != 0:
|
|
print(f"Fehler beim Verbinden zu {host} auf Port {port}") # --- E-Mail senden
|
|
send_email("Server Connection Error", f"Fehler beim Verbinden zu {host} auf Port {port}", os.getenv('TO_EMAIL'))
|
|
except Exception as e:
|
|
print(f"Fehler beim Verbinden zu {host} auf Port {port}: {e}") # --- E-Mail senden
|
|
send_email("Server Connection Error", f"Fehler beim Verbinden zu {host} auf Port {port}: {e}", os.getenv('TO_EMAIL'))
|
|
finally:
|
|
sock.close()
|
|
|
|
# Prepare SQLite database connection
|
|
db_path = "/app/db/imapsync_results.db"
|
|
conn = sqlite3.connect(db_path)
|
|
cursor = conn.cursor()
|
|
|
|
# Create tables if not exists
|
|
cursor.execute('''
|
|
CREATE TABLE IF NOT EXISTS sync_results (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
email TEXT,
|
|
messages_transferred INTEGER,
|
|
date TEXT,
|
|
auth_failed INTEGER DEFAULT 0
|
|
)
|
|
''')
|
|
|
|
cursor.execute('''
|
|
CREATE TABLE IF NOT EXISTS users (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
email TEXT UNIQUE,
|
|
password TEXT,
|
|
domain TEXT
|
|
)
|
|
''')
|
|
|
|
# Fetch user data from the SQLite database
|
|
cursor.execute("SELECT email, password, domain FROM users")
|
|
users = cursor.fetchall()
|
|
|
|
if not users:
|
|
print("No users found in the database.")
|
|
sys.exit(1)
|
|
|
|
# Process each user
|
|
for user in users:
|
|
username, password, domain = user
|
|
domain_part = username.split('@')[1]
|
|
user_part = username.split('@')[0]
|
|
archiv_mail = os.getenv('ARCHIV_MAIL')
|
|
archiv_server = os.getenv('ARCHIV_SERVER')
|
|
|
|
print(f"User: {username} running.")
|
|
|
|
# Check if the user previously had an authentication failure
|
|
cursor.execute("SELECT auth_failed FROM sync_results WHERE email = ? ORDER BY date DESC LIMIT 1", (username,))
|
|
result = cursor.fetchone()
|
|
if result and result[0] == 1:
|
|
print(f"Skipping {username} due to previous authentication failure.")
|
|
# continue # Skip this user due to previous authentication failure
|
|
|
|
# Command for imapsync
|
|
command = [
|
|
"imapsync",
|
|
"--host1", domain,
|
|
"--user1", username,
|
|
"--password1", password,
|
|
"--host2", f"{archiv_server}",
|
|
"--user2", f"{archiv_mail}",
|
|
"--password2", "Ln0m2YQZd23H54L5tCiyjIBWLEn8mk36v7KauqS8QFGzu",
|
|
"--subfolder2", f"{domain_part}/{user_part}",
|
|
"--regextrans2", "s/^(.*)$/\\1/",
|
|
"--log",
|
|
"--notls2"
|
|
]
|
|
|
|
# Run the command and capture the output
|
|
try:
|
|
result = subprocess.run(command, capture_output=True, text=True)
|
|
output = result.stdout
|
|
|
|
# Initialize variables
|
|
auth_failed = 0
|
|
transferred_count = 0
|
|
|
|
# Check for EXIT_AUTHENTICATION_FAILURE_USER error
|
|
if "EXIT_AUTHENTICATION_FAILURE_USER" in output:
|
|
subject = f"Authentication Failure for {username}"
|
|
body = f"An authentication failure occurred for user {username} during IMAP sync."
|
|
send_email(subject, body, os.getenv('TO_EMAIL'))
|
|
auth_failed = 1 # Mark authentication failure
|
|
|
|
# Find and extract the "Messages transferred" line
|
|
for line in output.splitlines():
|
|
if "Messages transferred" in line:
|
|
transferred_messages = line.split(":")[-1].strip()
|
|
transferred_count = int(transferred_messages)
|
|
break
|
|
|
|
# Insert into the database if messages were transferred or if there was an auth failure
|
|
if transferred_count > 0 or auth_failed == 1:
|
|
current_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
|
|
# Insert result into SQLite database
|
|
cursor.execute('''
|
|
INSERT INTO sync_results (email, messages_transferred, date, auth_failed)
|
|
VALUES (?, ?, ?, ?)
|
|
''', (username, transferred_count, current_date, auth_failed))
|
|
conn.commit()
|
|
print(f"Data inserted for {username}: {transferred_count} messages on {current_date}")
|
|
else:
|
|
print(f"No messages transferred for {username}.")
|
|
except Exception as e:
|
|
print(f"Error running imapsync for {username}: {e}")
|
|
|
|
# Close database connection
|
|
conn.close()
|
|
|
|
except Exception as e:
|
|
print(f"An error occurred during the loop execution: {e}")
|
|
|
|
# Sleep for 5 minutes before the next iteration
|
|
print("Sleep 5 minutes")
|
|
time.sleep(300)
|