diff --git a/db/empty.db b/db/empty.db new file mode 100644 index 0000000..1ea2efb Binary files /dev/null and b/db/empty.db differ diff --git a/db/imapsync_results.db b/db/imapsync_results.db index 6cf7a7f..a524bb4 100644 Binary files a/db/imapsync_results.db and b/db/imapsync_results.db differ diff --git a/docker-compose.yml b/docker-compose.yml index ad04b99..212861f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,8 +9,8 @@ services: - 993:993 volumes: - vmail:/srv/mail - - /opt/dovecot/config:/etc/dovecot - - /opt/dovecot/passwd:/etc/dovecot/passwd + - ./dovecot/config:/etc/dovecot + - ./dovecot/passwd:/etc/dovecot/passwd roundcube: image: roundcube/roundcubemail @@ -19,22 +19,21 @@ services: ports: - 80:80 environment: - - ROUNDCUBEMAIL_DEFAULT_HOST=180.1.1.164 + - ROUNDCUBEMAIL_DEFAULT_HOST=dovecot - ROUNDCUBEMAIL_DEFAULT_PORT=143 depends_on: - dovecot imapsync: build: - dockerfile: imapsync-dockerfile + dockerfile: ./dockerfile/imapsync-dockerfile container_name: imapsync restart: always + expose: + - 993 + - 143 volumes: - - /app/db:/root/IMAP-Sync/db - logging: - driver: journald - options: - tag: imapsync + - ./db:/app/db networks: - default depends_on: @@ -42,11 +41,13 @@ services: streamlit: build: - dockerfile: streamlit-dockerfile + dockerfile: ./dockerfile/streamlit-dockerfile container_name: streamlit restart: always + ports: + - 81:80 volumes: - - /app/db:/root/IMAP-Sync/db + - ./db:/app/db logging: driver: journald options: diff --git a/dockerfile/imapsync-dockerfile b/dockerfile/imapsync-dockerfile index dfd7892..a3297ba 100644 --- a/dockerfile/imapsync-dockerfile +++ b/dockerfile/imapsync-dockerfile @@ -3,19 +3,20 @@ FROM debian:latest RUN apt update RUN apt upgrade -y RUN apt install -y git make gcc -RUN apt install -y apt-file cpanminus libc6-dev libssl-dev python3 python3-pip +RUN apt install -y apt-file cpanminus libc6-dev libssl-dev python3 python3-pip python3-dotenv RUN apt install -y libperl-dev zlib1g-dev libnet-ssleay-perl RUN cpanm App::cpanminus Authen::NTLM CGI Compress::Zlib Crypt::OpenSSL::RSA Data::Dumper Data::Uniqid Dist::CheckConflicts Encode Encode::IMAPUTF7 File::Copy::Recursive File::Tail IO::Socket::INET IO::Socket::INET6 IO::Socket::SSL IO::Tee JSON JSON::WebToken LWP::UserAgent Mail::IMAPClient Module::ScanDeps PAR::Packer Pod::Usage Readonly Regexp::Common Sys::MemInfo Term::ReadKey Test::MockObject Test::More Test::Pod Unicode::String; exit 0 RUN apt install -y libproc-processtable-perl python3-requests iputils-ping WORKDIR /usr/local/src RUN echo PWD RUN git clone https://github.com/imapsync/imapsync.git -RUN ./imapsync +WORKDIR ./imapsync RUN make install RUN mkdir /app WORKDIR /app/ COPY ../python_scripte/imapsync.py . -CMD ["/bin/bash"] +COPY ../python_scripte/.env . +ENTRYPOINT [ "python3", "/app/imapsync.py" ] #RUN impasync-script \ No newline at end of file diff --git a/dockerfile/streamlit-dockerfile b/dockerfile/streamlit-dockerfile index 4fd1237..2019b79 100644 --- a/dockerfile/streamlit-dockerfile +++ b/dockerfile/streamlit-dockerfile @@ -11,13 +11,13 @@ RUN apt-get update && apt-get install -y \ git \ && rm -rf /var/lib/apt/lists/* -COPY ../python_scripte/streamlit-app.py /app/ -COPY ../python_scripte/requirements.txt /app/ - RUN pip3 install -r /app/requirements.txt EXPOSE 80 +COPY ../python_scripte/streamlit-app.py /app/ +COPY ../python_scripte/requirements.txt /app/ + HEALTHCHECK CMD curl --fail http://localhost:80/_stcore/health ENTRYPOINT ["streamlit", "run", "/app/streamlit-app.py", "--server.port=80", "--server.address=0.0.0.0"] \ No newline at end of file diff --git a/dovecot/dovecot.conf b/dovecot/config/dovecot.conf similarity index 100% rename from dovecot/dovecot.conf rename to dovecot/config/dovecot.conf diff --git a/dovecot/config/passwd b/dovecot/config/passwd new file mode 100755 index 0000000..e69de29 diff --git a/.env b/python_scripte/.env similarity index 100% rename from .env rename to python_scripte/.env diff --git a/python_scripte/imapsync.py b/python_scripte/imapsync.py index dcc99db..f796f9d 100644 --- a/python_scripte/imapsync.py +++ b/python_scripte/imapsync.py @@ -7,11 +7,12 @@ 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 = "front" +host = "180.1.1.164" port = 993 # Function to send an email notification @@ -37,99 +38,112 @@ def send_email(subject, body, to_email): except Exception as e: print(f"Failed to send email: {e}") -# 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 -except Exception as e: - print(f"Fehler beim Verbinden zu {host} auf Port {port}: {e}") # --- E-Mail senden -finally: - sock.close() - -# Prepare SQLite database connection -db_path = "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 -) -''') - -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 - local_part = username.split('@')[0] - - # Command for imapsync - command = [ - "imapsync", - "--host1", domain, - "--user1", username, - "--password1", password, - "--host2", "180.1.1.164", - "--user2", "archiv@archiv.trendsetzer.eu", - "--password2", "pass", - "--subfolder2", f"{local_part}", - "--regextrans2", "s/^(.*)$/\\1/", - "--nolog" - ] - - # Run the command and capture the output +# Start the infinite loop +while True: try: - result = subprocess.run(command, capture_output=True, text=True) - output = result.stdout + # 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() - # 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')) + # Prepare SQLite database connection + db_path = "/app/db/imapsync_results.db" + conn = sqlite3.connect(db_path) + cursor = conn.cursor() - # 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) - current_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + # 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 + ) + ''') + + 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 + local_part = username.split('@')[0] + print(f"User: {username} running.") + # Command for imapsync + command = [ + "imapsync", + "--host1", domain, + "--user1", username, + "--password1", password, + "--host2", "180.1.1.164", + "--user2", "archiv@trendsetzer.eu", + "--password2", "Ln0m2YQZd23H54L5tCiyjIBWLEn8mk36v7KauqS8QFGzu", + "--subfolder2", f"{local_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 + + # 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')) + + # 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) + 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) + VALUES (?, ?, ?) + ''', (username, transferred_count, current_date)) + conn.commit() + print(f"Data inserted for {username}: {transferred_count} messages on {current_date}") + break + else: + print(f"No 'Messages transferred' line found for {username}.") + except Exception as e: + print(f"Error running imapsync for {username}: {e}") + + # Close database connection + conn.close() - # Insert result into SQLite database - cursor.execute(''' - INSERT INTO sync_results (email, messages_transferred, date) - VALUES (?, ?, ?) - ''', (username, transferred_count, current_date)) - conn.commit() - print(f"Data inserted for {username}: {transferred_count} messages on {current_date}") - break - else: - print(f"No 'Messages transferred' line found for {username}.") except Exception as e: - print(f"Error running imapsync for {username}: {e}") + print(f"An error occurred during the loop execution: {e}") -# Close database connection -conn.close() + # Sleep for 5 minutes before the next iteration + print("Sleep 5 minutes") + time.sleep(300) diff --git a/python_scripte/streamlit-app.py b/python_scripte/streamlit-app.py index 0a8db1e..e1c37fe 100644 --- a/python_scripte/streamlit-app.py +++ b/python_scripte/streamlit-app.py @@ -40,7 +40,7 @@ def main(): view_users = st.sidebar.button("View Users", key="view_users_button") delete_user = st.sidebar.button("Delete User", key="delete_user_button") st.sidebar.markdown( - '', + '', unsafe_allow_html=True )