diff --git a/__pycache__/app.cpython-313.pyc b/__pycache__/app.cpython-313.pyc new file mode 100644 index 0000000..911c414 Binary files /dev/null and b/__pycache__/app.cpython-313.pyc differ diff --git a/app.py b/app.py index 46f6810..0203a95 100644 --- a/app.py +++ b/app.py @@ -31,7 +31,6 @@ login_manager = LoginManager(app) login_manager.login_view = 'login' # MODELE BAZY DANYCH - class User(UserMixin, db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), unique=True, nullable=False) @@ -45,7 +44,6 @@ class User(UserMixin, db.Model): def check_password(self, password): return check_password_hash(self.password_hash, password) - class Device(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(120)) @@ -62,7 +60,6 @@ class Device(db.Model): use_ssl = db.Column(db.Boolean, default=False) # Czy używać SSL? ssl_insecure = db.Column(db.Boolean, default=False) # Jeśli True – nie weryfikować certyfikatu SSL user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) - class Settings(db.Model): id = db.Column(db.Integer, primary_key=True) pushover_user_key = db.Column(db.String(255)) @@ -73,16 +70,17 @@ class Settings(db.Model): smtp_username = db.Column(db.String(255)) smtp_password = db.Column(db.String(255)) email_notifications_enabled = db.Column(db.Boolean, default=False) - check_interval = db.Column(db.Integer, default=60) # interwał sprawdzania w sekundach - log_retention_days = db.Column(db.Integer, default=30) # nowe pole – retencja logów w dniach + check_interval = db.Column(db.Integer, default=60) + log_retention_days = db.Column(db.Integer, default=30) + recipient_email = db.Column(db.String(120)) user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False, unique=True) - class Log(db.Model): id = db.Column(db.Integer, primary_key=True) timestamp = db.Column(db.DateTime, default=datetime.utcnow) message = db.Column(db.Text) device_id = db.Column(db.Integer, db.ForeignKey('device.id')) user_id = db.Column(db.Integer, db.ForeignKey('user.id')) + device = db.relationship('Device', backref='logs') # Inicjalizacja bazy (utworzyć bazę przy pierwszym uruchomieniu) with app.app_context(): @@ -110,21 +108,21 @@ def send_pushover_notification(user, message): print("Błąd przy wysyłaniu powiadomienia Pushover:", e) def send_email_notification(user, subject, message): - # Sprawdzamy, czy ustawienia e-mail są poprawnie skonfigurowane if not user.settings or not user.settings.email_notifications_enabled or not user.settings.smtp_server: return try: - # Uzyskujemy sformatowaną treść e-maila html_body = get_email_template(subject, message) msg = MIMEText(html_body, 'html') msg["Subject"] = subject msg["From"] = user.settings.smtp_username - msg["To"] = user.email + # Używamy adresu z ustawień, jeśli został podany, lub domyślnie adresu z profilu użytkownika + to_email = user.settings.recipient_email if user.settings.recipient_email else user.email + msg["To"] = to_email s = smtplib.SMTP(user.settings.smtp_server, user.settings.smtp_port) s.starttls() s.login(user.settings.smtp_username, user.settings.smtp_password) - s.sendmail(user.settings.smtp_username, [user.email], msg.as_string()) + s.sendmail(user.settings.smtp_username, [to_email], msg.as_string()) s.quit() app.logger.debug("E-mail wysłany pomyślnie") except Exception as e: @@ -271,7 +269,9 @@ def check_all_devices(): device.current_firmware = current_firmware db.session.commit() # Zapis do tabeli logów - log_entry = Log(message=result, device_id=device.id, user_id=device.user_id) + #log_entry = Log(message=result, device_id=device.id, user_id=device.user_id) + log_message = f"Urządzenie {device.name or device.ip} - {result}" + log_entry = Log(message=log_message, device_id=device.id, user_id=device.user_id) db.session.add(log_entry) db.session.commit() # Powiadomienia, jeśli dostępna aktualizacja @@ -487,27 +487,29 @@ def settings(): user_settings.smtp_username = request.form.get('smtp_username') user_settings.smtp_password = request.form.get('smtp_password') user_settings.email_notifications_enabled = bool(request.form.get('email_notifications_enabled')) + # Aktualizacja adresu e-mail odbiorcy (może być inny niż email z profilu) + user_settings.recipient_email = request.form.get('recipient_email') # Aktualizacja interwału sprawdzania interval = request.form.get('check_interval') user_settings.check_interval = int(interval) if interval else 60 # Aktualizacja retencji logów retention = request.form.get('log_retention_days') user_settings.log_retention_days = int(retention) if retention else 30 - + db.session.commit() - - # Aktualizacja interwału zadania scheduler'a, jeśli masz takie zadanie + try: scheduler.reschedule_job("check_all_devices", trigger="interval", seconds=user_settings.check_interval) app.logger.debug(f"Scheduler rescheduled with new interval: {user_settings.check_interval} seconds") except Exception as e: app.logger.error(f"Error rescheduling job: {e}") - + flash("Ustawienia zapisane.") return redirect(url_for('settings')) return render_template('settings.html', settings=user_settings) + @app.route('/device//edit', methods=['GET', 'POST']) @login_required def edit_device(device_id): @@ -529,7 +531,6 @@ def edit_device(device_id): return redirect(url_for('devices')) return render_template('edit_device.html', device=device) - @app.route('/device//force_check') @login_required def force_check(device_id): @@ -581,8 +582,6 @@ def update_device(device_id): flash(f"Błąd podczas aktualizacji: {e}") return redirect(url_for('device_detail', device_id=device.id)) - - @app.route('/device//update_firmware', methods=['POST']) @login_required def update_firmware(device_id): @@ -641,6 +640,24 @@ def reset_password(): return redirect(url_for('reset_password')) return render_template('reset_password.html') +@app.route('/logs/clean', methods=['POST']) +@login_required +def clean_logs(): + days = request.form.get('days') + if not days: + flash("Podaj liczbę dni.") + return redirect(url_for('logs')) + try: + days = int(days) + except ValueError: + flash("Niepoprawna wartość dni.") + return redirect(url_for('logs')) + cutoff = datetime.utcnow() - timedelta(days=days) + num_deleted = Log.query.filter(Log.user_id == current_user.id, Log.timestamp < cutoff).delete() + db.session.commit() + flash(f"Usunięto {num_deleted} logów starszych niż {days} dni.") + return redirect(url_for('logs')) + # Zamknięcie harmonogramu przy zatrzymaniu aplikacji atexit.register(lambda: scheduler.shutdown()) diff --git a/instance/database.db b/instance/database.db new file mode 100644 index 0000000..6c69bc2 Binary files /dev/null and b/instance/database.db differ diff --git a/requirements.txt b/requirements.txt index 77bdbf0..c4a8411 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,5 +4,4 @@ Flask-Login APScheduler librouteros requests -gunicorn -requests \ No newline at end of file +waitress \ No newline at end of file diff --git a/routeros_update.service b/routeros_update.service new file mode 100644 index 0000000..c546e3f --- /dev/null +++ b/routeros_update.service @@ -0,0 +1,14 @@ +[Unit] +Description=RouterOS Update Waitress Service +After=network.target + +[Service] +#User=routeros +#Group=routeros +WorkingDirectory=/opt/routeros_update +ExecStart=/opt/routeros_update/venv/bin/python3 /opt/routeros_update/run_waitress.py +Restart=always +Environment=PYTHONUNBUFFERED=1 + +[Install] +WantedBy=multi-user.target diff --git a/run_waitress.py b/run_waitress.py new file mode 100644 index 0000000..130f934 --- /dev/null +++ b/run_waitress.py @@ -0,0 +1,9 @@ +from waitress import serve +from app import app, scheduler, clean_old_logs +import atexit + +with app.app_context(): + scheduler.add_job(func=clean_old_logs, trigger="interval", days=1) + atexit.register(lambda: scheduler.shutdown()) + +serve(app, host='0.0.0.0', port=5582, ident='', threads=4) diff --git a/templates/logs.html b/templates/logs.html index 0c55026..06b695f 100644 --- a/templates/logs.html +++ b/templates/logs.html @@ -2,6 +2,18 @@ {% block title %}Logi - Aplikacja Updatera{% endblock %} {% block content %}

Logi

+ +
+

Usuń logi starsze niż podana liczba dni

+
+
+ + +
+ +
+
+
@@ -30,4 +42,5 @@ {% endfor %}
+ {% endblock %} diff --git a/templates/settings.html b/templates/settings.html index eeab883..d500a5d 100644 --- a/templates/settings.html +++ b/templates/settings.html @@ -46,12 +46,18 @@ - +
+ E-mail odbiorcy powiadomień +
+ + +
+
Interwał sprawdzania
- - + +