Compare commits
10 Commits
9835da0bf6
...
333a200bf7
| Author | SHA1 | Date | |
|---|---|---|---|
| 333a200bf7 | |||
| ab5dc04c73 | |||
| b24febb8a8 | |||
| 909ed6cf34 | |||
| 381897a016 | |||
| cd5e55d44a | |||
| f61b3beee1 | |||
| 418da3e307 | |||
| 7d63964d24 | |||
| f961d1141a |
63
check_sslcerts/checksslcerts.sh
Normal file
63
check_sslcerts/checksslcerts.sh
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
## crontab
|
||||||
|
## 0 4 * * * bash /data/scripts/sslcerts/create_sites.sh > /data/scripts/sslcerts/sites.txt
|
||||||
|
## 0 5 * * * bash /data/scripts/sslcerts/checksslcerts.sh 2>&1 > /tmp/checksslcert.log
|
||||||
|
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
sites=$(cat /data/scripts/sslcerts/sites.txt)
|
||||||
|
|
||||||
|
export SITE_SSL_PORT="443"
|
||||||
|
|
||||||
|
for site in `echo $sites`
|
||||||
|
do
|
||||||
|
export SITE_URL=$site
|
||||||
|
|
||||||
|
notAfter=$(/usr/bin/openssl s_client -connect ${SITE_URL}:${SITE_SSL_PORT} \
|
||||||
|
-servername ${SITE_URL} 2> /dev/null | /usr/bin/openssl x509 -noout -dates | grep notAfter)
|
||||||
|
|
||||||
|
not_after=$(echo "$notAfter" | cut -d= -f2-)
|
||||||
|
|
||||||
|
now_ts=$(date +%s)
|
||||||
|
expiry_ts=$(date -d "$not_after" +%s)
|
||||||
|
diff_sec=$((expiry_ts - now_ts))
|
||||||
|
diff_days=$((diff_sec / 86400))
|
||||||
|
|
||||||
|
if [ "$not_after" != "" ]
|
||||||
|
then
|
||||||
|
if [ "$diff_days" -lt 14 ]
|
||||||
|
then
|
||||||
|
echo "send warning für $site ($diff_days)"
|
||||||
|
url="https://msg.rproxy.conet-services.de/message.php"
|
||||||
|
# JSON-Daten für den POST-Request
|
||||||
|
json_data=$(cat <<EOF
|
||||||
|
{
|
||||||
|
"msg": "Certificate for $site is about to expire in $diff_days day(s)",
|
||||||
|
"subject": "Certificate expiration warning",
|
||||||
|
"x_conet_src": "conetadm@conlxscript1:/data/scripts/sslcerts/checksslcerts.sh",
|
||||||
|
"from_descr": "CONET Monitoring",
|
||||||
|
"from_email": "noreply@conet-services.de",
|
||||||
|
"to_email": "help@conet.de",
|
||||||
|
"reply_mail": "support-con@tasks.conet.de"
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
# Senden der POST-Anfrage mit curl
|
||||||
|
response=$(curl -s -X POST $url \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "$json_data"
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf "%02d days" "$diff_days"
|
||||||
|
echo -n "@"
|
||||||
|
printf "%30s" "$not_after"
|
||||||
|
echo -n ":"
|
||||||
|
printf "%40s\n" "$site"
|
||||||
|
echo "delete from sslcerts where cn='$site'" | /usr/bin/mysql -u conetadm -p'Conet12#' -Dscripts
|
||||||
|
echo "INSERT INTO sslcerts (expiration, datestring, cn) VALUES ('$diff_days', '$not_after', '$site') ON DUPLICATE KEY UPDATE cn = VALUES(cn);" | /usr/bin/mysql -u conetadm -p'Conet12#' -Dscripts
|
||||||
|
else
|
||||||
|
echo "cannot get certificate from $site"
|
||||||
|
fi
|
||||||
|
done
|
||||||
14
check_sslcerts/create_sites.sh
Normal file
14
check_sslcerts/create_sites.sh
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
domains="conet-services.de tenoc.de hosting-ffm.de bankhaus-scheich.de"
|
||||||
|
|
||||||
|
for domain in `echo $domains`
|
||||||
|
do
|
||||||
|
curl -s "https://crt.sh/?q=%25.$domain&output=json" \
|
||||||
|
| grep -oE '"name_value":"[^"]+"' \
|
||||||
|
| cut -d':' -f2 \
|
||||||
|
| tr -d '"' \
|
||||||
|
| sed 's/\\n.*//' \
|
||||||
|
| grep -v '\*' \
|
||||||
|
| sort -u
|
||||||
|
done
|
||||||
5
check_sslcerts/sites.txt
Normal file
5
check_sslcerts/sites.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
andregeissler.de
|
||||||
|
|
||||||
|
agserver.de
|
||||||
|
cloud.agserver.de
|
||||||
|
|
||||||
593
json_msg_2_mail/complete
Normal file
593
json_msg_2_mail/complete
Normal file
@@ -0,0 +1,593 @@
|
|||||||
|
CREATE TABLE message (
|
||||||
|
id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
msg TEXT NULL,
|
||||||
|
subject VARCHAR(255) NULL,
|
||||||
|
x_conet_src VARCHAR(255) NULL,
|
||||||
|
in_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
sent TINYINT(1) NULL DEFAULT 0,
|
||||||
|
from_descr VARCHAR(255) NULL,
|
||||||
|
from_email VARCHAR(255) NULL,
|
||||||
|
to_descr VARCHAR(255) NULL,
|
||||||
|
to_email VARCHAR(255) NULL,
|
||||||
|
reply_mail VARCHAR(255) NULL,
|
||||||
|
sent_time TIMESTAMP NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
DELIMITER //
|
||||||
|
|
||||||
|
CREATE TRIGGER update_sent_time
|
||||||
|
BEFORE UPDATE ON message
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
IF NEW.sent <> OLD.sent THEN
|
||||||
|
IF NEW.sent = TRUE THEN
|
||||||
|
SET NEW.sent_time = CURRENT_TIMESTAMP;
|
||||||
|
ELSE
|
||||||
|
SET NEW.sent_time = NULL;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
//
|
||||||
|
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
|
##########################################################################################
|
||||||
|
|
||||||
|
{
|
||||||
|
"msg": "Hallo Welt",
|
||||||
|
"subject": "Test",
|
||||||
|
"x_conet_src": "app_42",
|
||||||
|
"from_descr": "Max Mustermann",
|
||||||
|
"from_email": "max@example.com",
|
||||||
|
"to_descr": "Lisa Beispiel",
|
||||||
|
"to_email": "lisa@example.com",
|
||||||
|
"reply_mail": "antwort@example.com"
|
||||||
|
}
|
||||||
|
|
||||||
|
##########################################################################################
|
||||||
|
pip install requests
|
||||||
|
########################################################################################## send_message.py
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
|
||||||
|
url = "http://yourserver.com/api/message.php" # ändere das auf deine URL
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
"msg": "Hallo Welt",
|
||||||
|
"subject": "Test",
|
||||||
|
"x_conet_src": "app_42",
|
||||||
|
"from_descr": "Max Mustermann",
|
||||||
|
"from_email": "max@example.com",
|
||||||
|
"to_descr": "Lisa Beispiel",
|
||||||
|
"to_email": "lisa@example.com",
|
||||||
|
"reply_mail": "antwort@example.com"
|
||||||
|
}
|
||||||
|
|
||||||
|
headers = {"Content-Type": "application/json"}
|
||||||
|
|
||||||
|
response = requests.post(url, data=json.dumps(payload), headers=headers)
|
||||||
|
|
||||||
|
print(f"Status: {response.status_code}")
|
||||||
|
print(f"Antwort: {response.text}")
|
||||||
|
|
||||||
|
##########################################################################################
|
||||||
|
cpan LWP::UserAgent JSON
|
||||||
|
########################################################################################## send_message.pl
|
||||||
|
#!/usr/bin/perl
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use LWP::UserAgent;
|
||||||
|
use JSON;
|
||||||
|
|
||||||
|
my $url = 'http://yourserver.com/api/message.php'; # anpassen!
|
||||||
|
|
||||||
|
my %data = (
|
||||||
|
msg => "Hallo Welt",
|
||||||
|
subject => "Test",
|
||||||
|
x_conet_src => "app_42",
|
||||||
|
from_descr => "Max Mustermann",
|
||||||
|
from_email => "max@example.com",
|
||||||
|
to_descr => "Lisa Beispiel",
|
||||||
|
to_email => "lisa@example.com",
|
||||||
|
reply_mail => "antwort@example.com"
|
||||||
|
);
|
||||||
|
|
||||||
|
my $json = encode_json(\%data);
|
||||||
|
|
||||||
|
my $ua = LWP::UserAgent->new;
|
||||||
|
my $response = $ua->post(
|
||||||
|
$url,
|
||||||
|
'Content-Type' => 'application/json',
|
||||||
|
Content => $json
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($response->is_success) {
|
||||||
|
print "Antwort: " . $response->decoded_content . "\n";
|
||||||
|
} else {
|
||||||
|
die "Fehler: " . $response->status_line;
|
||||||
|
}
|
||||||
|
|
||||||
|
########################################################################################## /var/www/html/api/message.php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// Ganz oben im PHP-Skript, vor allem anderen:
|
||||||
|
header("Access-Control-Allow-Origin: *");
|
||||||
|
header("Content-Type: application/json");
|
||||||
|
|
||||||
|
// DB-Zugangsdaten
|
||||||
|
$host = 'localhost';
|
||||||
|
$db = 'deine_datenbank';
|
||||||
|
$user = 'dein_user';
|
||||||
|
$pass = 'dein_passwort';
|
||||||
|
$charset = 'utf8mb4';
|
||||||
|
|
||||||
|
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
|
||||||
|
$options = [
|
||||||
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||||
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||||
|
PDO::ATTR_EMULATE_PREPARES => false,
|
||||||
|
];
|
||||||
|
|
||||||
|
// Verbindung aufbauen
|
||||||
|
try {
|
||||||
|
$pdo = new PDO($dsn, $user, $pass, $options);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode(["error" => "Verbindung fehlgeschlagen: " . $e->getMessage()]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// JSON-Daten einlesen
|
||||||
|
$input = file_get_contents("php://input");
|
||||||
|
$data = json_decode($input, true);
|
||||||
|
|
||||||
|
// Pflichtfelder prüfen
|
||||||
|
$required = ['msg', 'subject', 'x_conet_src', 'from_descr', 'from_email', 'to_descr', 'to_email', 'reply_mail'];
|
||||||
|
foreach ($required as $field) {
|
||||||
|
if (!isset($data[$field])) {
|
||||||
|
http_response_code(400);
|
||||||
|
echo json_encode(["error" => "Feld fehlt: $field"]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Einfügen
|
||||||
|
try {
|
||||||
|
$sql = "INSERT INTO message (
|
||||||
|
msg, subject, x_conet_src,
|
||||||
|
from_descr, from_email,
|
||||||
|
to_descr, to_email, reply_mail
|
||||||
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
|
||||||
|
$stmt = $pdo->prepare($sql);
|
||||||
|
$stmt->execute([
|
||||||
|
$data['msg'],
|
||||||
|
$data['subject'],
|
||||||
|
$data['x_conet_src'],
|
||||||
|
$data['from_descr'],
|
||||||
|
$data['from_email'],
|
||||||
|
$data['to_descr'],
|
||||||
|
$data['to_email'],
|
||||||
|
$data['reply_mail']
|
||||||
|
]);
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
"success" => true,
|
||||||
|
"inserted_id" => $pdo->lastInsertId()
|
||||||
|
]);
|
||||||
|
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode(["error" => $e->getMessage()]);
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
########################################################################################## send_message.sh
|
||||||
|
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# URL des PHP-Servers
|
||||||
|
url="http://yourserver.com/api/message.php"
|
||||||
|
|
||||||
|
# JSON-Daten für den POST-Request
|
||||||
|
json_data=$(cat <<EOF
|
||||||
|
{
|
||||||
|
"msg": "Hallo Welt",
|
||||||
|
"subject": "Test",
|
||||||
|
"x_conet_src": "app_42",
|
||||||
|
"from_descr": "Max Mustermann",
|
||||||
|
"from_email": "max@example.com",
|
||||||
|
"to_descr": "Lisa Beispiel",
|
||||||
|
"to_email": "lisa@example.com",
|
||||||
|
"reply_mail": "antwort@example.com"
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
|
||||||
|
# Senden der POST-Anfrage mit curl
|
||||||
|
response=$(curl -s -X POST $url \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "$json_data")
|
||||||
|
|
||||||
|
# Ausgabe der Antwort
|
||||||
|
echo "Antwort des Servers:"
|
||||||
|
echo "$response"
|
||||||
|
|
||||||
|
########################################################################################## /var/www/html/api/message.php
|
||||||
|
|
||||||
|
<?php
|
||||||
|
// DB-Zugangsdaten
|
||||||
|
$host = 'localhost';
|
||||||
|
$db = 'deine_datenbank';
|
||||||
|
$user = 'dein_user';
|
||||||
|
$pass = 'dein_passwort';
|
||||||
|
$charset = 'utf8mb4';
|
||||||
|
|
||||||
|
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
|
||||||
|
$options = [
|
||||||
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||||
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||||
|
PDO::ATTR_EMULATE_PREPARES => false,
|
||||||
|
];
|
||||||
|
|
||||||
|
// Verbindung aufbauen
|
||||||
|
try {
|
||||||
|
$pdo = new PDO($dsn, $user, $pass, $options);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode(["error" => "Verbindung fehlgeschlagen: " . $e->getMessage()]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CORS und Content-Type für JSON-Response
|
||||||
|
header("Access-Control-Allow-Origin: *");
|
||||||
|
header("Content-Type: application/json");
|
||||||
|
|
||||||
|
// Methode prüfen (GET oder POST)
|
||||||
|
$method = $_SERVER['REQUEST_METHOD'];
|
||||||
|
|
||||||
|
if ($method == 'POST') {
|
||||||
|
// JSON-Daten einlesen
|
||||||
|
$input = file_get_contents("php://input");
|
||||||
|
$data = json_decode($input, true);
|
||||||
|
|
||||||
|
// Pflichtfelder prüfen
|
||||||
|
$required = ['msg', 'subject', 'x_conet_src', 'from_descr', 'from_email', 'to_descr', 'to_email', 'reply_mail'];
|
||||||
|
foreach ($required as $field) {
|
||||||
|
if (!isset($data[$field])) {
|
||||||
|
http_response_code(400);
|
||||||
|
echo json_encode(["error" => "Feld fehlt: $field"]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Einfügen
|
||||||
|
try {
|
||||||
|
$sql = "INSERT INTO message (
|
||||||
|
msg, subject, x_conet_src,
|
||||||
|
from_descr, from_email,
|
||||||
|
to_descr, to_email, reply_mail
|
||||||
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
|
||||||
|
$stmt = $pdo->prepare($sql);
|
||||||
|
$stmt->execute([
|
||||||
|
$data['msg'],
|
||||||
|
$data['subject'],
|
||||||
|
$data['x_conet_src'],
|
||||||
|
$data['from_descr'],
|
||||||
|
$data['from_email'],
|
||||||
|
$data['to_descr'],
|
||||||
|
$data['to_email'],
|
||||||
|
$data['reply_mail']
|
||||||
|
]);
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
"success" => true,
|
||||||
|
"inserted_id" => $pdo->lastInsertId()
|
||||||
|
]);
|
||||||
|
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode(["error" => $e->getMessage()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
} elseif ($method == 'GET') {
|
||||||
|
// Alle Nachrichten abfragen
|
||||||
|
try {
|
||||||
|
$stmt = $pdo->query("SELECT * FROM message");
|
||||||
|
$messages = $stmt->fetchAll();
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
"success" => true,
|
||||||
|
"messages" => $messages
|
||||||
|
]);
|
||||||
|
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode(["error" => $e->getMessage()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Nicht unterstützte HTTP-Methode
|
||||||
|
http_response_code(405);
|
||||||
|
echo json_encode(["error" => "Methode nicht erlaubt."]);
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
########################################################################################## send_pending_messages.pl
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use DBI;
|
||||||
|
use Mail::Sender;
|
||||||
|
|
||||||
|
# Datenbankverbindung
|
||||||
|
my $dsn = "DBI:mysql:deine_datenbank:localhost";
|
||||||
|
my $user = "dein_user";
|
||||||
|
my $pass = "dein_passwort";
|
||||||
|
my $dbh = DBI->connect($dsn, $user, $pass, { RaiseError => 1, AutoCommit => 1 })
|
||||||
|
or die "Verbindung zur Datenbank fehlgeschlagen: $DBI::errstr";
|
||||||
|
|
||||||
|
# Nachrichten mit sent = 0 abfragen
|
||||||
|
my $sth = $dbh->prepare("SELECT * FROM message WHERE sent = 0");
|
||||||
|
$sth->execute();
|
||||||
|
|
||||||
|
# SMTP-Konfiguration
|
||||||
|
my $smtp_server = 'smtp.example.com';
|
||||||
|
my $default_from = 'noreply@example.com';
|
||||||
|
|
||||||
|
while (my $row = $sth->fetchrow_hashref) {
|
||||||
|
my $to = $row->{to_email};
|
||||||
|
my $subject = $row->{subject};
|
||||||
|
my $body = $row->{msg};
|
||||||
|
my $from = $row->{from_email} || $default_from;
|
||||||
|
my $reply = $row->{reply_mail};
|
||||||
|
my $x_src = $row->{x_conet_src} || 'undefined';
|
||||||
|
|
||||||
|
# E-Mail senden
|
||||||
|
my $sender = Mail::Sender->new({
|
||||||
|
smtp => $smtp_server,
|
||||||
|
from => $from,
|
||||||
|
});
|
||||||
|
|
||||||
|
my $result = $sender->MailMsg({
|
||||||
|
to => $to,
|
||||||
|
subject => $subject,
|
||||||
|
msg => $body,
|
||||||
|
headers => {
|
||||||
|
'Reply-To' => $reply,
|
||||||
|
'X-Conet-Src' => $x_src,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($result) {
|
||||||
|
print "E-Mail an $to gesendet.\n";
|
||||||
|
$dbh->do("UPDATE message SET sent = 1 WHERE id = ?", undef, $row->{id});
|
||||||
|
} else {
|
||||||
|
print "Fehler beim Senden der E-Mail an $to.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$sth->finish();
|
||||||
|
$dbh->disconnect();
|
||||||
|
|
||||||
|
########################################################################################## send_pending_messages.php
|
||||||
|
|
||||||
|
<?php
|
||||||
|
$host = 'localhost';
|
||||||
|
$db = 'deine_datenbank';
|
||||||
|
$user = 'dein_user';
|
||||||
|
$pass = 'dein_passwort';
|
||||||
|
$charset = 'utf8mb4';
|
||||||
|
|
||||||
|
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
|
||||||
|
$options = [
|
||||||
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||||
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||||
|
];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$pdo = new PDO($dsn, $user, $pass, $options);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
echo "Verbindung fehlgeschlagen: " . $e->getMessage();
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = "SELECT * FROM message WHERE sent = 0";
|
||||||
|
$stmt = $pdo->query($sql);
|
||||||
|
$messages = $stmt->fetchAll();
|
||||||
|
|
||||||
|
foreach ($messages as $message) {
|
||||||
|
$to = $message['to_email'];
|
||||||
|
$subject = $message['subject'];
|
||||||
|
$body = $message['msg'];
|
||||||
|
$from = $message['from_email'];
|
||||||
|
$reply = $message['reply_mail'];
|
||||||
|
$x_src = $message['x_conet_src'] ?? 'undefined';
|
||||||
|
|
||||||
|
$headers = "From: $from\r\n";
|
||||||
|
$headers .= "Reply-To: $reply\r\n";
|
||||||
|
$headers .= "X-Conet-Src: $x_src\r\n";
|
||||||
|
$headers .= "Content-Type: text/plain; charset=UTF-8\r\n";
|
||||||
|
|
||||||
|
if (mail($to, $subject, $body, $headers)) {
|
||||||
|
$update = $pdo->prepare("UPDATE message SET sent = 1 WHERE id = ?");
|
||||||
|
$update->execute([$message['id']]);
|
||||||
|
echo "E-Mail an $to gesendet.\n";
|
||||||
|
} else {
|
||||||
|
echo "Fehler beim Senden der E-Mail an $to.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################################## check_and_send_emails.sh
|
||||||
|
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# PHP-Skript ausführen
|
||||||
|
php /path/to/send_pending_messages.php
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################################## /etc/systemd/system/email_sender.service
|
||||||
|
[Unit]
|
||||||
|
Description=Send Pending Emails
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStart=/path/to/check_and_send_emails.sh
|
||||||
|
User=www-data
|
||||||
|
Group=www-data
|
||||||
|
Environment=PATH=/usr/bin:/usr/local/bin
|
||||||
|
WorkingDirectory=/path/to/directory
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
|
||||||
|
########################################################################################## /etc/systemd/system/email_sender.timer
|
||||||
|
[Unit]
|
||||||
|
Description=Run Email Sender every 5 minutes
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnUnitActiveSec=5min
|
||||||
|
Unit=email_sender.service
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
|
|
||||||
|
##########################################################################################
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl enable email_sender.service
|
||||||
|
sudo systemctl enable email_sender.timer
|
||||||
|
|
||||||
|
sudo systemctl start email_sender.timer
|
||||||
|
|
||||||
|
sudo systemctl status email_sender.timer
|
||||||
|
sudo journalctl -u email_sender.service
|
||||||
|
|
||||||
|
########################################################################################## GET-Anfrage zum Abrufen aller Nachrichten
|
||||||
|
curl -X GET http://yourserver.com/api/message.php
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################################## view_messages.php
|
||||||
|
<?php
|
||||||
|
// DB-Zugangsdaten
|
||||||
|
$host = 'localhost';
|
||||||
|
$db = 'deine_datenbank';
|
||||||
|
$user = 'dein_user';
|
||||||
|
$pass = 'dein_passwort';
|
||||||
|
$charset = 'utf8mb4';
|
||||||
|
|
||||||
|
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
|
||||||
|
$options = [
|
||||||
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||||
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||||
|
];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$pdo = new PDO($dsn, $user, $pass, $options);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
die("Datenbankverbindung fehlgeschlagen: " . $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter/Suchparameter
|
||||||
|
$search = $_GET['search'] ?? '';
|
||||||
|
$sent = isset($_GET['sent']) ? (int) $_GET['sent'] : null;
|
||||||
|
$sort = in_array($_GET['sort'] ?? '', ['id', 'subject', 'in_time', 'sent']) ? $_GET['sort'] : 'in_time';
|
||||||
|
$order = ($_GET['order'] ?? '') === 'asc' ? 'ASC' : 'DESC';
|
||||||
|
|
||||||
|
// SQL-Query dynamisch bauen
|
||||||
|
$sql = "SELECT * FROM message WHERE 1";
|
||||||
|
$params = [];
|
||||||
|
|
||||||
|
if (in_array($range, ['7', '30', '180'])) {
|
||||||
|
$sql .= " AND in_time >= DATE_SUB(NOW(), INTERVAL :range DAY)";
|
||||||
|
$params['range'] = (int)$range;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ($search !== '') {
|
||||||
|
$sql .= " AND (subject LIKE :search OR msg LIKE :search OR from_email LIKE :search)";
|
||||||
|
$params['search'] = "%$search%";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($sent !== null && in_array($sent, [0, 1])) {
|
||||||
|
$sql .= " AND sent = :sent";
|
||||||
|
$params['sent'] = $sent;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql .= " ORDER BY $sort $order";
|
||||||
|
$stmt = $pdo->prepare($sql);
|
||||||
|
$stmt->execute($params);
|
||||||
|
$messages = $stmt->fetchAll();
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Nachrichtenübersicht</title>
|
||||||
|
<style>
|
||||||
|
body { font-family: sans-serif; margin: 2em; }
|
||||||
|
table { border-collapse: collapse; width: 100%; }
|
||||||
|
th, td { padding: 0.5em; border: 1px solid #ccc; text-align: left; }
|
||||||
|
th a { text-decoration: none; color: #000; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>Nachrichtenübersicht</h1>
|
||||||
|
|
||||||
|
<form method="get" style="margin-bottom: 1em;">
|
||||||
|
<input type="text" name="search" placeholder="Suche..." value="<?= htmlspecialchars($search) ?>">
|
||||||
|
<select name="sent">
|
||||||
|
<option value="">-- gesendet? --</option>
|
||||||
|
<option value="0" <?= $sent === 0 ? 'selected' : '' ?>>nicht gesendet</option>
|
||||||
|
<option value="1" <?= $sent === 1 ? 'selected' : '' ?>>gesendet</option>
|
||||||
|
</select>
|
||||||
|
<select name="range">
|
||||||
|
<option value="">Alle</option>
|
||||||
|
<option value="7" <?= $range === '7' ? 'selected' : '' ?>>Letzte 7 Tage</option>
|
||||||
|
<option value="30" <?= $range === '30' ? 'selected' : '' ?>>Letzte 30 Tage</option>
|
||||||
|
<option value="180" <?= $range === '180' ? 'selected' : '' ?>>Letzte 180 Tage</option>
|
||||||
|
</select>
|
||||||
|
<button type="submit">Filtern</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<?php
|
||||||
|
$cols = ['id' => 'ID', 'subject' => 'Betreff', 'in_time' => 'Eingang', 'sent' => 'Gesendet'];
|
||||||
|
foreach ($cols as $key => $label):
|
||||||
|
$next_order = ($sort === $key && $order === 'ASC') ? 'desc' : 'asc';
|
||||||
|
$link = "?search=" . urlencode($search) . "&sent=" . urlencode($sent ?? '') . "&sort=$key&order=$next_order";
|
||||||
|
echo "<th><a href=\"$link\">$label</a></th>";
|
||||||
|
endforeach;
|
||||||
|
?>
|
||||||
|
<th>Von</th>
|
||||||
|
<th>An</th>
|
||||||
|
<th>X-Conet-Src</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php foreach ($messages as $msg): ?>
|
||||||
|
<tr>
|
||||||
|
<td><?= htmlspecialchars($msg['id']) ?></td>
|
||||||
|
<td><?= htmlspecialchars($msg['subject']) ?></td>
|
||||||
|
<td><?= htmlspecialchars($msg['in_time']) ?></td>
|
||||||
|
<td><?= $msg['sent'] ? '✅' : '❌' ?></td>
|
||||||
|
<td><?= htmlspecialchars($msg['from_email']) ?></td>
|
||||||
|
<td><?= htmlspecialchars($msg['to_email']) ?></td>
|
||||||
|
<td><?= htmlspecialchars($msg['x_conet_src']) ?></td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
3
json_msg_2_mail/db_connect
Normal file
3
json_msg_2_mail/db_connect
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
DB andregeissler_msg
|
||||||
|
USR andregeissler_msg
|
||||||
|
PW G0H1yrhEtQ
|
||||||
9
owi pdfs nach ods/README.md
Normal file
9
owi pdfs nach ods/README.md
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Nimmt das Suchergebnis von
|
||||||
|
|
||||||
|
find . -name "*.pdf" -exec pdfgrep "Tattag|Tatzeit|Fahrzeug Kennzeichen|Marke|Tatort" {} > /home/andre/Dokumente/pdfs.txt +
|
||||||
|
|
||||||
|
in "pdfs.txt"
|
||||||
|
|
||||||
|
und erstellt daraus "anzeigen.csv" und "anzeigen.xlsx"
|
||||||
|
|
||||||
|
Liefert der find nur Inhalte von neuen Dateien und ist anzeigen.csv vorhanden, wird zunächst die csv eingelesen und um die neuen Einträge ergänzt. Doppplungen und Verluste gibt es damit nicht
|
||||||
4470
owi pdfs nach ods/anzeigen.csv
Normal file
4470
owi pdfs nach ods/anzeigen.csv
Normal file
File diff suppressed because it is too large
Load Diff
BIN
owi pdfs nach ods/anzeigen.xlsx
Normal file
BIN
owi pdfs nach ods/anzeigen.xlsx
Normal file
Binary file not shown.
22312
owi pdfs nach ods/pdfs.txt
Normal file
22312
owi pdfs nach ods/pdfs.txt
Normal file
File diff suppressed because it is too large
Load Diff
182
owi pdfs nach ods/process-owi2.pl
Normal file
182
owi pdfs nach ods/process-owi2.pl
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use utf8;
|
||||||
|
use open qw(:std :utf8);
|
||||||
|
use Excel::Writer::XLSX;
|
||||||
|
|
||||||
|
my $input = 'pdfs.txt';
|
||||||
|
my $csv_out = 'anzeigen.csv';
|
||||||
|
my $xlsx_out = 'anzeigen.xlsx';
|
||||||
|
my $sep = ';';
|
||||||
|
|
||||||
|
# Hilfsfunktion: trim
|
||||||
|
sub trim { my $s = shift; $s =~ s/^\s+|\s+$//g; return $s // '' }
|
||||||
|
|
||||||
|
# --- Bestehende CSV einlesen (falls vorhanden) ---
|
||||||
|
my %entries;
|
||||||
|
if (-e $csv_out) {
|
||||||
|
open(my $old, '<:encoding(UTF-8)', $csv_out) or die "Kann $csv_out nicht lesen: $!";
|
||||||
|
my $hdr = <$old>; # Kopfzeile überspringen
|
||||||
|
while (<$old>) {
|
||||||
|
chomp;
|
||||||
|
next unless length($_);
|
||||||
|
my @cols = split /$sep/, $_;
|
||||||
|
# trim alle Felder
|
||||||
|
@cols = map { trim($_) } @cols;
|
||||||
|
my ($datum, $start, $ende, $tatort, $kennz, $marke, $file) = @cols;
|
||||||
|
$entries{$file} = {
|
||||||
|
Datum => $datum // '',
|
||||||
|
'Tatzeit(Anfang)' => $start // '',
|
||||||
|
'Tatzeit(Ende)' => $ende // '',
|
||||||
|
Tatort => $tatort // '',
|
||||||
|
Kennzeichen => $kennz // '',
|
||||||
|
Marke => $marke // '',
|
||||||
|
Datei => $file // ''
|
||||||
|
};
|
||||||
|
}
|
||||||
|
close $old;
|
||||||
|
print "📂 Bestehende CSV geladen: " . scalar(keys %entries) . " Einträge\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Neue Daten aus pdfs.txt einlesen ---
|
||||||
|
open(my $in, '<:encoding(UTF-8)', $input) or die "Kann $input nicht öffnen: $!";
|
||||||
|
while (<$in>) {
|
||||||
|
chomp;
|
||||||
|
next unless /:/;
|
||||||
|
my ($file, $content) = split(/:/, $_, 2);
|
||||||
|
$file = trim($file);
|
||||||
|
$content = trim($content);
|
||||||
|
|
||||||
|
# initialisieren falls neu
|
||||||
|
$entries{$file} //= {
|
||||||
|
Datum => '',
|
||||||
|
'Tatzeit(Anfang)' => '',
|
||||||
|
'Tatzeit(Ende)' => '',
|
||||||
|
Tatort => '',
|
||||||
|
Kennzeichen => '',
|
||||||
|
Marke => '',
|
||||||
|
Datei => $file
|
||||||
|
};
|
||||||
|
|
||||||
|
# Kennzeichen
|
||||||
|
if ($content =~ /Fahrzeug Kennzeichen\s+(.+)/i) {
|
||||||
|
$entries{$file}->{Kennzeichen} = trim($1);
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
# Marke
|
||||||
|
if ($content =~ /Marke des Fahrzeuges\s+(.+)/i) {
|
||||||
|
$entries{$file}->{Marke} = trim($1);
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
# Tatort
|
||||||
|
if ($content =~ /Tatort\s+(.+)/i) {
|
||||||
|
$entries{$file}->{Tatort} = trim($1);
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
# Datum in der Form DD.MM.YYYY auf derselben Zeile
|
||||||
|
if ($content =~ /Tattag\s*\(Datum\)\s*([0-3]?\d\.[01]?\d\.\d{4})/) {
|
||||||
|
my $d = $1;
|
||||||
|
if ($d =~ /(\d{2})\.(\d{2})\.(\d{4})/) {
|
||||||
|
$entries{$file}->{Datum} = sprintf("%04d-%02d-%02d", $3, $2, $1);
|
||||||
|
}
|
||||||
|
# es könnten zusätzlich Zeiten auf dieser Zeile sein -> weiter prüfen unten
|
||||||
|
}
|
||||||
|
# Falls die Zeile "Tattag (Datum) (Tatzeit – Bis)" ohne Datum, wir lassen Datum unverändert (nicht überschreiben)
|
||||||
|
|
||||||
|
# Zeiten: überall nach HH:MM suchen (erkennt auch "17:30- 17:49", "11:35 - 11:40 Uhr", "21:13" etc.)
|
||||||
|
if ($content =~ /Tatzeit|Tatzeit|Tatzeit.*|Tattag.*Tatzeit/i or $content =~ /(\d{1,2}:\d{2})/) {
|
||||||
|
my @times = ($content =~ /(\d{1,2}:\d{2})/g);
|
||||||
|
# Falls Zeiten gefunden wurden, setzen (überschreiben)
|
||||||
|
if (@times) {
|
||||||
|
$entries{$file}->{'Tatzeit(Anfang)'} = $times[0];
|
||||||
|
$entries{$file}->{'Tatzeit(Ende)'} = $times[1] // ''; # falls keine Endzeit, leer lassen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Manchmal steht das Datum ohne Label (seltener), versuchen wir ein generelles Datumsmuster in content
|
||||||
|
if (!$entries{$file}->{Datum} && $content =~ /(\d{2}\.\d{2}\.\d{4})/) {
|
||||||
|
my $d = $1;
|
||||||
|
if ($d =~ /(\d{2})\.(\d{2})\.(\d{4})/) {
|
||||||
|
$entries{$file}->{Datum} = sprintf("%04d-%02d-%02d", $3, $2, $1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close $in;
|
||||||
|
|
||||||
|
# --- Sortieren: neueste zuerst; falls Datum leer, ans Ende ---
|
||||||
|
my @sorted = sort {
|
||||||
|
my $da = $entries{$a}->{Datum} // '';
|
||||||
|
my $db = $entries{$b}->{Datum} // '';
|
||||||
|
# leere Datum nach unten
|
||||||
|
return $da cmp $db if $da eq '' || $db eq '';
|
||||||
|
($db cmp $da) || ( ($entries{$b}->{'Tatzeit(Anfang)'} // '') cmp ($entries{$a}->{'Tatzeit(Anfang)'} // '') )
|
||||||
|
} keys %entries;
|
||||||
|
|
||||||
|
# --- CSV schreiben (gewünschte Reihenfolge) ---
|
||||||
|
open(my $csv, '>:encoding(UTF-8)', $csv_out) or die "Kann $csv_out nicht schreiben: $!";
|
||||||
|
print $csv "Datum${sep}Tatzeit(Anfang)${sep}Tatzeit(Ende)${sep}Tatort${sep}Kennzeichen${sep}Marke${sep}Datei\n";
|
||||||
|
for my $e (@sorted) {
|
||||||
|
my $row = join($sep, map { $entries{$e}->{$_} // '' } qw(Datum Tatzeit(Anfang) Tatzeit(Ende) Tatort Kennzeichen Marke Datei));
|
||||||
|
print $csv "$row\n";
|
||||||
|
}
|
||||||
|
close $csv;
|
||||||
|
print "✅ CSV-Datei '$csv_out' erstellt.\n";
|
||||||
|
|
||||||
|
# --- XLSX erzeugen ---
|
||||||
|
my $workbook = Excel::Writer::XLSX->new( $xlsx_out );
|
||||||
|
my $worksheet = $workbook->add_worksheet();
|
||||||
|
|
||||||
|
# Formatierungen
|
||||||
|
my $bold_format = $workbook->add_format( bold => 1, bg_color => '#D9D9D9' );
|
||||||
|
my $date_format = $workbook->add_format( num_format => 'yyyy-mm-dd' );
|
||||||
|
my $time_format = $workbook->add_format( num_format => 'hh:mm' );
|
||||||
|
|
||||||
|
# Kopfzeile
|
||||||
|
my @header = qw(Datum Tatzeit(Anfang) Tatzeit(Ende) Tatort Kennzeichen Marke Datei);
|
||||||
|
$worksheet->write_row( 'A1', \@header, $bold_format );
|
||||||
|
|
||||||
|
# Datenzeilen
|
||||||
|
my $row_index = 1;
|
||||||
|
for my $e (@sorted) {
|
||||||
|
my @row_data = (
|
||||||
|
$entries{$e}->{Datum} // '',
|
||||||
|
$entries{$e}->{'Tatzeit(Anfang)'} // '',
|
||||||
|
$entries{$e}->{'Tatzeit(Ende)'} // '',
|
||||||
|
$entries{$e}->{Tatort} // '',
|
||||||
|
$entries{$e}->{Kennzeichen} // '',
|
||||||
|
$entries{$e}->{Marke} // '',
|
||||||
|
$entries{$e}->{Datei} // '',
|
||||||
|
);
|
||||||
|
|
||||||
|
for my $col (0..$#row_data) {
|
||||||
|
my $value = $row_data[$col];
|
||||||
|
|
||||||
|
# Datum als echtes Excel-Datum (ISO + T)
|
||||||
|
if ($col == 0 && $value =~ /^(\d{4})-(\d{2})-(\d{2})$/) {
|
||||||
|
my $iso = sprintf("%04d-%02d-%02dT00:00:00", $1, $2, $3);
|
||||||
|
$worksheet->write_date_time($row_index, $col, $iso, $date_format);
|
||||||
|
}
|
||||||
|
# Zeit als echte Excel-Zeit (Bruchteil eines Tages)
|
||||||
|
elsif (($col == 1 || $col == 2) && $value =~ /^(\d{1,2}):(\d{2})$/) {
|
||||||
|
my ($h,$m) = ($1,$2);
|
||||||
|
my $time_fraction = ($h*3600 + $m*60)/86400;
|
||||||
|
$worksheet->write_number($row_index, $col, $time_fraction, $time_format);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# Text (leer als leere Zelle)
|
||||||
|
$worksheet->write_string($row_index, $col, $value // '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$row_index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Optional: Autofit (nur grobe Breiten setzen)
|
||||||
|
$worksheet->set_column(0, 0, 12); # Datum
|
||||||
|
$worksheet->set_column(1, 2, 10); # Zeiten
|
||||||
|
$worksheet->set_column(3, 3, 30); # Tatort
|
||||||
|
$worksheet->set_column(4, 5, 15); # Kennzeichen, Marke
|
||||||
|
$worksheet->set_column(6, 6, 60); # Datei
|
||||||
|
|
||||||
|
$workbook->close;
|
||||||
|
print "📊 XLSX-Datei '$xlsx_out' erstellt – alle Daten sichtbar und formatiert.\n";
|
||||||
Reference in New Issue
Block a user