diff --git a/.env b/.env new file mode 100644 index 0000000..f557f4f --- /dev/null +++ b/.env @@ -0,0 +1,6 @@ +SMTP_SERVER=mail.itdata-gera.de +SMTP_PORT=587 +SMTP_USER=serfling@itdata-gera.de +SMTP_PASSWORD="xPElLoyD,94,#" +FROM_EMAIL=serfling@itdata-gera.de +TO_EMAIL=serfling@itdata-gera.de diff --git a/LOG_imapsync/2024_08_29_11_09_24_721_serfling@itdata-gera.de_archiv@archiv.trendsetzer.eu.txt b/LOG_imapsync/2024_08_29_11_09_24_721_serfling@itdata-gera.de_archiv@archiv.trendsetzer.eu.txt deleted file mode 100644 index 2243768..0000000 --- a/LOG_imapsync/2024_08_29_11_09_24_721_serfling@itdata-gera.de_archiv@archiv.trendsetzer.eu.txt +++ /dev/null @@ -1,86 +0,0 @@ -Here is imapsync 2.229 on host imapsync, a linux system with 0.1/1.9 free GiB of RAM, 98.08% used by processes. -with Perl 5.36.0 and Mail::IMAPClient 3.43 -Transfer started at Donnerstag 29 August 2024-08-29 11:09:24 +0200 CEST -PID is 169155 my PPID is 169154 -Log file is LOG_imapsync/2024_08_29_11_09_24_721_serfling@itdata-gera.de_archiv@archiv.trendsetzer.eu.txt ( to change it, use --logfile path ; or use --nolog to turn off logging ) -Load is 0.55 0.44 0.58 2/511 on 1 cores -Current directory is /root/IMAP-Sync -Real user id is root (uid 0) -Effective user id is root (euid 0) -$RCSfile: imapsync,v $ $Revision: 2.229 $ $Date: 2022/09/14 18:08:24 $ -Command line used, run by /usr/bin/perl: -/usr/bin/imapsync --host1 mail.itdata-gera.de --user1 serfling@itdata-gera.de --password1 MASKED --host2 imap-sync-front-1 --user2 archiv@archiv.trendsetzer.eu --port2 143 --password2 MASKED -Temp directory is /tmp ( to change it use --tmpdir dirpath ) -kill -QUIT 169155 # special behavior: call to sub catch_exit -kill -TERM 169155 # special behavior: call to sub catch_exit -kill -INT 169155 # special behavior: call to sub catch_reconnect -kill -HUP 169155 # special behavior: call to sub catch_print -kill -USR1 169155 # special behavior: call to sub toggle_sleep -File /tmp/imapsync.pid does not exist -PID file is /tmp/imapsync.pid ( to change it, use --pidfile filepath ; to avoid it use --pidfile "" ) -Writing my PID 169155 in /tmp/imapsync.pid -Writing also my logfile name in /tmp/imapsync.pid : LOG_imapsync/2024_08_29_11_09_24_721_serfling@itdata-gera.de_archiv@archiv.trendsetzer.eu.txt -Modules version list ( use --no-modulesversion to turn off printing this Perl modules list ): -Authen::NTLM 1.09 -CGI 4.66 -Compress::Zlib 2.213 -Crypt::OpenSSL::RSA 0.33 -Data::Uniqid 0.12 -Digest::HMAC_MD5 1.04 -Digest::HMAC_SHA1 1.04 -Digest::MD5 2.58 -Encode 3.21 -Encode::IMAPUTF7 1.05 -File::Copy::Recursive 0.45 -File::Spec 3.84 -Getopt::Long 2.52 -HTML::Entities 3.81 -IO::Socket 1.55 -IO::Socket::INET 1.55 -IO::Socket::INET6 2.73 -IO::Socket::IP 0.41 -IO::Socket::SSL 2.088 -IO::Tee 0.65 -JSON 4.10 -JSON::WebToken 0.10 -LWP 6.77 -MIME::Base64 3.16 -Mail::IMAPClient 3.43 -Net::Ping 2.74 -Net::SSLeay 1.92 -Term::ReadKey 2.38 -Test::MockObject 1.20200122 -Time::HiRes 1.977 -URI::Escape 5.17 -Unicode::String 2.10 - -Info: will resync flags for already transferred messages. Use --noresyncflags to not resync flags. -Host1: probing ssl on port 993 ( use --nosslcheck to avoid this ssl probe ) -Host1: sslcheck detected open ssl port 993 so turning ssl on (use --nossl1 --notls1 to turn off SSL and TLS wizardry) -SSL debug mode level is --debugssl 1 (can be set from 0 meaning no debug to 4 meaning max debug) -Host1: SSL default mode is like --sslargs1 "SSL_verify_mode=0", meaning for host1 SSL_VERIFY_NONE, ie, do not check the server certificate. -Host1: Use --sslargs1 SSL_verify_mode=1 to have SSL_VERIFY_PEER, ie, check the server certificate. of host1 -Info: turned ON syncinternaldates, will set the internal dates (arrival dates) on host2 same as host1. -Host1: will try to use LOGIN authentication on host1 -Host2: will try to use LOGIN authentication on host2 -Host1: imap connection timeout is 120 seconds -Host2: imap connection timeout is 120 seconds -Host1: imap connection keepalive is on on host1. Use --nokeepalive1 to disable it. -Host2: imap connection keepalive is on on host2. Use --nokeepalive2 to disable it. -Host1: IMAP server [mail.itdata-gera.de] port [993] user [serfling@itdata-gera.de] -Host2: IMAP server [imap-sync-front-1] port [143] user [archiv@archiv.trendsetzer.eu] -Host1: connecting and login on host1 [mail.itdata-gera.de] port [993] with user [serfling@itdata-gera.de] -Host1 IP address: 49.13.56.197 Local IP address: 180.1.1.164 -Host1 banner: * OK [CAPABILITY IMAP4rev1 SASL-IR LOGIN-REFERRALS ID ENABLE IDLE LITERAL+ AUTH=PLAIN AUTH=LOGIN] Dovecot ready. -Host1 capability before authentication: IMAP4rev1 SASL-IR LOGIN-REFERRALS ID ENABLE IDLE LITERAL+ AUTH=PLAIN AUTH=LOGIN AUTH -Host1: mail.itdata-gera.de says it has CAPABILITY for AUTHENTICATE LOGIN -Host1: success login on [mail.itdata-gera.de] with user [serfling@itdata-gera.de] auth [LOGIN] or [LOGIN] -Host2: connecting and login on host2 [imap-sync-front-1] port [143] with user [archiv@archiv.trendsetzer.eu] -Host2 failure: can not open imap connection on host2 [imap-sync-front-1] with user [archiv@archiv.trendsetzer.eu]: Unable to connect to imap-sync-front-1: Invalid argument -++++ Listing 1 errors encountered during the sync ( avoid this listing with --noerrorsdump ). -Err 1/1: Host2 failure: can not open imap connection on host2 [imap-sync-front-1] with user [archiv@archiv.trendsetzer.eu]: Unable to connect to imap-sync-front-1: Invalid argument -The most frequent error is ERR_CONNECTION_FAILURE_HOST2. Check that host1 imap-sync-front-1 on port 143 is the right IMAP server to be contacted for your mailbox. -Exiting with return value 102 (EXIT_CONNECTION_FAILURE_HOST2) 1/50 nb_errors/max_errors PID 169155 -Removing pidfile /tmp/imapsync.pid -Disconnecting from host1 mail.itdata-gera.de user1 serfling@itdata-gera.de -Log file is LOG_imapsync/2024_08_29_11_09_24_721_serfling@itdata-gera.de_archiv@archiv.trendsetzer.eu.txt ( to change it, use --logfile filepath ; or use --nolog to turn off logging ) diff --git a/db/imapsync_results.db b/db/imapsync_results.db new file mode 100644 index 0000000..6cf7a7f Binary files /dev/null and b/db/imapsync_results.db differ diff --git a/docker-compose.yml b/docker-compose.yml index 3c99eec..ad04b99 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,160 +1,36 @@ services: - - redis: - image: redis:alpine + dovecot: + image: dovecot/dovecot restart: always - volumes: - - "/mailu/redis:/data" - depends_on: - - resolver - dns: - - 192.168.203.254 - - # Core services - front: - image: ${DOCKER_ORG:-ghcr.io/mailu}/${DOCKER_PREFIX:-}nginx:${MAILU_VERSION:-2024.06} - restart: always - env_file: mailu.env - logging: - driver: journald - options: - tag: mailu-front + networks: + - default ports: - - "80:80" - - "443:443" - - "25:25" - - "465:465" - - "587:587" - - "110:110" - - "995:995" - - "143:143" - - "993:993" - - "4190:4190" + - 143:143 + - 993:993 + volumes: + - vmail:/srv/mail + - /opt/dovecot/config:/etc/dovecot + - /opt/dovecot/passwd:/etc/dovecot/passwd + + roundcube: + image: roundcube/roundcubemail networks: - default - - webmail - volumes: - - "/mailu/certs:/certs" - - "/mailu/overrides/nginx:/overrides:ro" + ports: + - 80:80 + environment: + - ROUNDCUBEMAIL_DEFAULT_HOST=180.1.1.164 + - ROUNDCUBEMAIL_DEFAULT_PORT=143 depends_on: - - resolver - dns: - - 192.168.203.254 - - resolver: - image: ${DOCKER_ORG:-ghcr.io/mailu}/${DOCKER_PREFIX:-}unbound:${MAILU_VERSION:-2024.06} - env_file: mailu.env - logging: - driver: journald - options: - tag: mailu-resolver - restart: always - networks: - default: - ipv4_address: 192.168.203.254 - - admin: - image: ${DOCKER_ORG:-ghcr.io/mailu}/${DOCKER_PREFIX:-}admin:${MAILU_VERSION:-2024.06} - restart: always - env_file: mailu.env - logging: - driver: journald - options: - tag: mailu-admin - volumes: - - "/mailu/data:/data" - - "/mailu/dkim:/dkim" - depends_on: - - redis - - resolver - dns: - - 192.168.203.254 - - imap: - image: ${DOCKER_ORG:-ghcr.io/mailu}/${DOCKER_PREFIX:-}dovecot:${MAILU_VERSION:-2024.06} - restart: always - env_file: mailu.env - logging: - driver: journald - options: - tag: mailu-imap - volumes: - - "/mailu/mail:/mail" - - "/mailu/overrides/dovecot:/overrides:ro" - networks: - - default - depends_on: - - front - - resolver - dns: - - 192.168.203.254 - - smtp: - image: ${DOCKER_ORG:-ghcr.io/mailu}/${DOCKER_PREFIX:-}postfix:${MAILU_VERSION:-2024.06} - restart: always - env_file: mailu.env - logging: - driver: journald - options: - tag: mailu-smtp - volumes: - - "/mailu/mailqueue:/queue" - - "/mailu/overrides/postfix:/overrides:ro" - depends_on: - - front - - resolver - dns: - - 192.168.203.254 - - - - antispam: - image: ${DOCKER_ORG:-ghcr.io/mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-2024.06} - hostname: antispam - restart: always - env_file: mailu.env - logging: - driver: journald - options: - tag: mailu-antispam - networks: - - default - volumes: - - "/mailu/filter:/var/lib/rspamd" - - "/mailu/overrides/rspamd:/overrides:ro" - depends_on: - - front - - redis - - resolver - dns: - - 192.168.203.254 - - # Optional services - - - - # Webmail - webmail: - image: ${DOCKER_ORG:-ghcr.io/mailu}/${DOCKER_PREFIX:-}webmail:${MAILU_VERSION:-2024.06} - restart: always - env_file: mailu.env - logging: - driver: journald - options: - tag: mailu-webmail - volumes: - - "/mailu/webmail:/data" - - "/mailu/overrides/roundcube:/overrides:ro" - networks: - - webmail - depends_on: - - front + - dovecot imapsync: build: dockerfile: imapsync-dockerfile container_name: imapsync restart: always + volumes: + - /app/db:/root/IMAP-Sync/db logging: driver: journald options: @@ -162,8 +38,27 @@ services: networks: - default depends_on: - - front + - dovecot + streamlit: + build: + dockerfile: streamlit-dockerfile + container_name: streamlit + restart: always + volumes: + - /app/db:/root/IMAP-Sync/db + logging: + driver: journald + options: + tag: imapsync + networks: + - default + depends_on: + - dovecot + + +volumes: + vmail: networks: default: diff --git a/imapsync-dockerfile b/dockerfile/imapsync-dockerfile similarity index 82% rename from imapsync-dockerfile rename to dockerfile/imapsync-dockerfile index 25fd9bc..dfd7892 100644 --- a/imapsync-dockerfile +++ b/dockerfile/imapsync-dockerfile @@ -6,16 +6,16 @@ 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 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 +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 -WORKDIR ./imapsync +RUN ./imapsync RUN make install RUN mkdir /app WORKDIR /app/ -RUN git clone https://gitlab.stines.de/sebastian.serfling/IMAP-Sync.git . +COPY ../python_scripte/imapsync.py . CMD ["/bin/bash"] #RUN impasync-script \ No newline at end of file diff --git a/dockerfile/streamlit-dockerfile b/dockerfile/streamlit-dockerfile new file mode 100644 index 0000000..4fd1237 --- /dev/null +++ b/dockerfile/streamlit-dockerfile @@ -0,0 +1,23 @@ +# app/Dockerfile + +FROM python:3.9-slim + +WORKDIR /app + +RUN apt-get update && apt-get install -y \ + build-essential \ + curl \ + software-properties-common \ + 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 + +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/dovecot.conf new file mode 100644 index 0000000..4d5c067 --- /dev/null +++ b/dovecot/dovecot.conf @@ -0,0 +1,36 @@ +## You should mount /etc/dovecot if you want to +## manage this file + +mail_home=/srv/mail/%Lu +mail_location=sdbox:~/Mail +mail_uid=1000 +mail_gid=1000 + +protocols = imap pop3 submission sieve lmtp + +first_valid_uid = 1000 +last_valid_uid = 1000 + +passdb { + driver = passwd-file + args = /etc/dovecot/passwd +} +namespace { + inbox = yes + separator = / +} + +service lmtp { + inet_listener { + port = 24 + } +} + +listen = * + +log_path=/dev/stdout +info_log_path=/dev/stdout +debug_log_path=/dev/stdout + +auth_mechanisms = plain login +disable_plaintext_auth = no diff --git a/dovecot/passwd b/dovecot/passwd new file mode 100644 index 0000000..855dd47 --- /dev/null +++ b/dovecot/passwd @@ -0,0 +1 @@ +archiv@trendsetzer.eu:{PLAIN}Ln0m2YQZd23H54L5tCiyjIBWLEn8mk36v7KauqS8QFGzu:::::: \ No newline at end of file diff --git a/imapsync.py b/imapsync.py deleted file mode 100644 index b55c579..0000000 --- a/imapsync.py +++ /dev/null @@ -1,66 +0,0 @@ -import sys -import csv -import os -import requests -import socket -import subprocess -from pathlib import Path - - -csvfile = Path("user.csv") -host = "front" -port = 993 - - -# Mail Server aktiv ? -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: - print(f"Fehler beim Verbinden zu {host} auf Port {port}") ## --- E-Mail senden -finally: - sock.close() - - -# CSV vorhanden1 -try: - csvfile_path = csvfile.resolve(strict=True) -except FileNotFoundError: - print("not Found") - - -#CSV erste Zeile auslesen (domain;domain) -rows = [] -with open(csvfile, mode='r', newline='') as file: - reader = csv.reader(file, delimiter=";") - next(reader) - for row in reader: - rows.append(row) - for row in rows: - username = row[0] - password = row[1] - domain = row[2] - # Erstellen einer Liste für den Befehl und die Argumente - command = [ - "imapsync", - "--host1", domain, - "--user1", username, - "--password1", password, - "--host2", "front", - "--user2", "archiv@archiv.trendsetzer.eu", - "--port2","143", - "--password2", "S8jZT7Ke3gdzxV0QfsB19R1bNwR716M6yUJQ4az9Kr8EK" - # "--prefix2", f"Archiv/{username}/", # Verwende dynamisch den username im Zielordner - # "--regextrans2", "s/^(.*)$/\\${1}/", - ] - subprocess.run(command) - -# CSV laden -# User in CSV kontrollieren ob vorhanden -> User anlegen -# impasync für jeden User durchführen -> Doamin aus CSV laden domain1.de;domain2.de -# Wenn Anmeldung am User failed -> Email mit User an -> impasync@domain1.de -# Abschluss Ergbniss in SQLLite Datenbank schreiben -# Daily Report an -> impasync@domain1.de \ No newline at end of file diff --git a/mailu.env b/mailu.env deleted file mode 100644 index 1b651d9..0000000 --- a/mailu.env +++ /dev/null @@ -1,166 +0,0 @@ -# Mailu main configuration file -# -# This file is autogenerated by the configuration management wizard for compose flavor. -# For a detailed list of configuration variables, see the documentation at -# https://mailu.io - -################################### -# Common configuration variables -################################### - -# Set to a randomly generated 16 bytes string -SECRET_KEY=YZ6BKHDTZRSIZ4HT - -# Subnet of the docker network. This should not conflict with any networks to which your system is connected. (Internal and external!) -SUBNET=192.168.203.0/24 - -# Main mail domain -DOMAIN=archiv.trendsetzer.eu - -# Hostnames for this server, separated with commas -HOSTNAMES=archiv.trendsetzer.eu - -# Postmaster local part (will append the main mail domain) -POSTMASTER=admin - -# Choose how secure connections will behave (value: letsencrypt, cert, notls, mail, mail-letsencrypt) -TLS_FLAVOR=notls - -# Authentication rate limit per IP (per /24 on ipv4 and /48 on ipv6) -AUTH_RATELIMIT_IP=5/hour - -# Authentication rate limit per user (regardless of the source-IP) -AUTH_RATELIMIT_USER=50/day - -# Opt-out of statistics, replace with "True" to opt out -DISABLE_STATISTICS=True - -################################### -# Optional features -################################### - -# Expose the admin interface (value: true, false) -ADMIN=true - -# Choose which webmail to run if any (values: roundcube, snappymail, none). To enable this feature, recreate the docker-compose.yml file via setup. -WEBMAIL=snappymail - -# Expose the API interface (value: true, false) -API=true - -# Dav server implementation (value: radicale, none). To enable this feature, recreate the docker-compose.yml file via setup. -WEBDAV=none - -# Antivirus solution (value: clamav, none). To enable this feature, recreate the docker-compose.yml file via setup. -ANTIVIRUS=none - -# Scan Macros solution (value: true, false). To enable this feature, recreate the docker-compose.yml file via setup. -SCAN_MACROS=false - -################################### -# Mail settings -################################### - -# Message size limit in bytes -# Default: accept messages up to 50MB -# Max attachment size will be 33% smaller -MESSAGE_SIZE_LIMIT=50000000 - -# Message rate limit (per user) -MESSAGE_RATELIMIT=200/day - -# Networks granted relay permissions -# Use this with care, all hosts in this networks will be able to send mail without authentication! -RELAYNETS= - -# Will relay all outgoing mails if configured -RELAYHOST= - -# Enable fetchmail -FETCHMAIL_ENABLED=False - -# Fetchmail delay -FETCHMAIL_DELAY=600 - -# Recipient delimiter, character used to delimiter localpart from custom address part -RECIPIENT_DELIMITER=+ - -# DMARC rua and ruf email -DMARC_RUA=admin -DMARC_RUF=admin - -# Welcome email, enable and set a topic and body if you wish to send welcome -# emails to all users. -WELCOME=false -WELCOME_SUBJECT=Welcome to your new email account -WELCOME_BODY=Welcome to your new email account, if you can read this, then it is configured properly! - -# Maildir Compression -# choose compression-method, default: none (value: gz, bz2, zstd) -COMPRESSION= -# change compression-level, default: 6 (value: 1-9) -COMPRESSION_LEVEL= - -# IMAP full-text search is enabled by default. -# Set the following variable to off in order to disable the feature -# or a comma separated list of language codes to support -FULL_TEXT_SEARCH=de - -################################### -# Web settings -################################### - -# Path to redirect / to -WEBROOT_REDIRECT=/webmail - -# Path to the admin interface if enabled -WEB_ADMIN=/admin - -# Path to the webmail if enabled -WEB_WEBMAIL=/webmail - -# Path to the API interface if enabled -WEB_API=/api - -# Website name -SITENAME=Mailu - -# Linked Website URL -#WEBSITE=https://mailu.io - - - -################################### -# Advanced settings -################################### - -# Docker-compose project name, this will prepended to containers names. -COMPOSE_PROJECT_NAME=mailu - -# Number of rounds used by the password hashing scheme -CREDENTIAL_ROUNDS=12 - -# Header to take the real ip from -REAL_IP_HEADER= - -# IPs for nginx set_real_ip_from (CIDR list separated by commas) -REAL_IP_FROM= - -# choose wether mailu bounces (no) or rejects (yes) mail when recipient is unknown (value: yes, no) -REJECT_UNLISTED_RECIPIENT= - -# Log level threshold in start.py (value: CRITICAL, ERROR, WARNING, INFO, DEBUG, NOTSET) -LOG_LEVEL=INFO - -# Timezone for the Mailu containers. See this link for all possible values https://en.wikipedia.org/wiki/List_of_tz_database_time_zones -TZ=Etc/UTC - -# Default spam threshold used for new users -DEFAULT_SPAM_THRESHOLD=80 - -# API token required for authenticating to the RESTful API. -# This is a mandatory setting for using the RESTful API. -API_TOKEN=ID0UTNZ5L6JOYRUN2WRJL4VXLAJ97JKH - -# Whether tika should be enabled (scan/OCR email attachements). To enable this feature, recreate the docker-compose.yml file via setup. -FULL_TEXT_SEARCH_ATTACHMENTS= diff --git a/python_scripte/imapsync.py b/python_scripte/imapsync.py new file mode 100644 index 0000000..dcc99db --- /dev/null +++ b/python_scripte/imapsync.py @@ -0,0 +1,135 @@ +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 + +load_dotenv() + +# Define server details +host = "front" +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}") + +# 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 + 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() diff --git a/python_scripte/requirements.txt b/python_scripte/requirements.txt new file mode 100644 index 0000000..ba7ae87 --- /dev/null +++ b/python_scripte/requirements.txt @@ -0,0 +1,3 @@ +requests +pandas +streamlit \ No newline at end of file diff --git a/python_scripte/streamlit-app.py b/python_scripte/streamlit-app.py new file mode 100644 index 0000000..0a8db1e --- /dev/null +++ b/python_scripte/streamlit-app.py @@ -0,0 +1,122 @@ +import streamlit as st +import sqlite3 +import pandas as pd + +def fetch_data_from_db(db_path, table_name): + conn = sqlite3.connect(db_path) + query = f"SELECT * FROM {table_name}" + df = pd.read_sql_query(query, conn) + conn.close() + return df + +def insert_user_into_db(db_path, email, password, domain): + conn = sqlite3.connect(db_path) + cursor = conn.cursor() + cursor.execute(''' + INSERT INTO users (email, password, domain) + VALUES (?, ?, ?) + ''', (email, password, domain)) + conn.commit() + conn.close() + +def delete_user_from_db(db_path, email): + conn = sqlite3.connect(db_path) + cursor = conn.cursor() + cursor.execute(''' + DELETE FROM users WHERE email = ? + ''', (email,)) + conn.commit() + conn.close() + +def main(): + st.set_page_config(page_title="Archiv Manager") + st.title("IMAPSync Manager") + + db_path = "/app/db/imapsync_results.db" + + # Sidebar for navigation with buttons and unique keys + st.sidebar.title("Navigation") + add_user = st.sidebar.button("Add User", key="add_user_button") + 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 + ) + + # Use session state to keep track of the selected page + if 'page' not in st.session_state: + st.session_state.page = 'View Users' + + if add_user: + st.session_state.page = 'Add User' + elif view_users: + st.session_state.page = 'View Users' + elif delete_user: + st.session_state.page = 'Delete User' + + if st.session_state.page == "Add User": + st.header("Add a New User") + new_email = st.text_input("Email:") + new_password = st.text_input("Password:", type="password") + new_domain = st.text_input("Domain:") + + if st.button("Add User", key="submit_add_user"): + if new_email and new_password and new_domain: + insert_user_into_db(db_path, new_email, new_password, new_domain) + st.success(f"User {new_email} added successfully!") + else: + st.error("Please fill in all fields.") + + elif st.session_state.page == "View Users": + st.header("IMAPSync Users and Email Transfer Results") + + # Fetch users and email transfer data + users_df = fetch_data_from_db(db_path, "users") + results_df = fetch_data_from_db(db_path, "sync_results") + + if users_df.empty: + st.write("No user data available in the database.") + else: + emails = users_df['email'].unique().tolist() + emails.insert(0, "All") + selected_email = st.selectbox("Filter by Email:", options=emails) + + if selected_email == "All": + filtered_users_df = users_df + else: + filtered_users_df = users_df[users_df['email'] == selected_email] + + st.dataframe(filtered_users_df) + + # Display email transfer results if available + if not results_df.empty: + if selected_email == "All": + st.write("Email Transfer Results:") + st.dataframe(results_df) + else: + filtered_results_df = results_df[results_df['email'] == selected_email] + if not filtered_results_df.empty: + st.write(f"Email Transfer Results for {selected_email}:") + st.dataframe(filtered_results_df) + else: + st.write(f"No transfer data found for {selected_email}.") + else: + st.write("No email transfer results available.") + + elif st.session_state.page == "Delete User": + st.header("Delete a User") + + df = fetch_data_from_db(db_path, "users") + + if df.empty: + st.write("No data available in the database.") + else: + user_to_delete = st.selectbox("Select User to Delete:", df['email'].unique()) + + if st.button("Delete User", key="confirm_delete_user"): + delete_user_from_db(db_path, user_to_delete) + st.success(f"User {user_to_delete} deleted successfully!") + +if __name__ == "__main__": + main() diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 663bd1f..0000000 --- a/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -requests \ No newline at end of file diff --git a/user.csv b/user.csv deleted file mode 100644 index ebbdbc4..0000000 --- a/user.csv +++ /dev/null @@ -1,2 +0,0 @@ -Username;Password;Domain -serfling@itdata-gera.de;xPElLoyD,94,#;mail.itdata-gera.de \ No newline at end of file