nowy mail i funkcja

This commit is contained in:
Mateusz Gruszczyński
2025-05-18 23:09:38 +02:00
parent 77f5001593
commit eeadd80347
2 changed files with 94 additions and 16 deletions

59
app.py
View File

@ -21,6 +21,7 @@ import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import time
from datetime import datetime, timedelta
# Redis - baza 5
@ -79,7 +80,6 @@ def is_temp_email(email):
except Exception:
return False
def export_to_csv(users):
now = datetime.datetime.now().strftime("%Y-%m-%d_%H%M")
filename = f"user_cleanup_results_{now}.csv"
@ -167,7 +167,7 @@ def get_smtp_config():
return config
def send_email_batch(users, smtp_config, mails_per_pack=100, time_per_pack=60, dry_run=False):
def send_email_batch(users, smtp_config, mails_per_pack=100, time_per_pack=60, dry_run=False, inactive_range=None):
import os
template_path = "mail_template.html"
@ -182,6 +182,19 @@ def send_email_batch(users, smtp_config, mails_per_pack=100, time_per_pack=60, d
print(f"❌ Błąd podczas odczytu szablonu HTML: {e}")
return
# Filtrowanie użytkowników według zakresu nieaktywności
if inactive_range:
min_days, max_days = inactive_range
now_ts = int(datetime.datetime.now().timestamp())
filtered_users = []
for user in users:
last_access = user['access'] or 0
days_inactive = (now_ts - last_access) / 86400
if min_days <= days_inactive <= max_days:
filtered_users.append(user)
users = filtered_users
print(f"📨 Wysyłka maili tylko dla użytkowników nieaktywnych od {min_days} do {max_days} dni ({len(users)} osób)")
try:
smtp = smtplib.SMTP(smtp_config["host"], int(smtp_config["port"]))
smtp.ehlo()
@ -213,8 +226,11 @@ def send_email_batch(users, smtp_config, mails_per_pack=100, time_per_pack=60, d
msg['To'] = user['mail']
msg['Subject'] = "Twoje konto w unitraklub.pl"
body = template.replace("@user", user['name']).replace(
"@rejestracja", datetime.datetime.fromtimestamp(user['created']).strftime('%Y-%m-%d'))
# Generowanie treści maila z uwzględnieniem ostatniego logowania
body = template.replace("@user", user['name']) \
.replace("@rejestracja", datetime.datetime.fromtimestamp(user['created']).strftime('%Y-%m-%d')) \
.replace("@ostatnie_logowanie", datetime.datetime.fromtimestamp(user['access']).strftime('%Y-%m-%d') if user['access'] else 'nigdy')
msg.attach(MIMEText(body, 'html'))
smtp.send_message(msg)
@ -263,6 +279,9 @@ def main():
# Czyszczenie cache DNS w Redisie
/root/user_manager/venv/bin/python3 app.py --flush-cache
# Wyślij maile tylko do użytkowników nieaktywnych od 1 do 5 lat
/root/user_manager/venv/bin/python3 app.py --send-mails --inactive-since 365-1825
""",
formatter_class=argparse.RawDescriptionHelpFormatter
)
@ -320,9 +339,25 @@ def main():
parser.add_argument('--only-invalid-emails', action='store_true',
help='Usuń tylko użytkowników z nieprawidłowymi lub tymczasowymi adresami e-mail (bez sprawdzania aktywności)')
# NEW: dodano argument --inactive-since
parser.add_argument(
"--inactive-since",
type=str,
help="Zakres dni nieaktywności w formacie min-max, np. 360-1825 (tylko dla wysyłki maili)"
)
args = parser.parse_args()
# NEW: przetwarzanie parametru --inactive-since
inactive_range = None
if args.inactive_since:
try:
min_days, max_days = map(int, args.inactive_since.split('-'))
inactive_range = (min_days, max_days)
except Exception as e:
print(f"Błąd parsowania zakresu dni w --inactive-since: {e}")
exit(1)
if args.send_test:
test_user = {
'name': 'Testowy Użytkownik',
@ -334,7 +369,6 @@ def main():
send_email_batch([test_user], smtp_config, mails_per_pack=1, time_per_pack=0, dry_run=False)
return
if not args.drupal_path:
args.drupal_path = os.getenv("DRUPAL_PATH")
@ -406,7 +440,6 @@ def main():
# Redundant safety filter to exclude any with points
final_candidates = [u for u in final_candidates if (u.get('points') or 0) == 0]
if args.report_domains:
domain_report(final_candidates)
@ -424,19 +457,26 @@ def main():
export_to_csv(final_candidates)
if args.export_excel:
export_to_excel(final_candidates)
if args.send_mails:
send_email_batch(final_candidates, smtp_config, args.mails_per_pack, args.time_per_pack)
send_email_batch(
final_candidates,
smtp_config,
args.mails_per_pack,
args.time_per_pack,
inactive_range=inactive_range # NEW: przekazanie zakresu nieaktywności
)
print("\n📋 Parametry filtrowania:")
if args.days_inactive:
print(f"- Nieaktywni: brak logowania przez ≥ {args.days_inactive} dni (~{days_to_years(args.days_inactive)} lat)")
print(f"- Weterani: konta zarejestrowane w roku ≤ {args.veteran_year}")
print(f"- Pominięci weterani: logowanie w ciągu ostatnich ≤ {args.recent_login_days} dni (~{days_to_years(args.recent_login_days)} lat)")
if args.inactive_since: # NEW: wyświetlanie zakresu nieaktywności
min_days, max_days = map(int, args.inactive_since.split('-'))
print(f"- Wysyłka maili tylko dla nieaktywnych od {min_days} do {max_days} dni (~{days_to_years(min_days)}-{days_to_years(max_days)} lat)")
print("\n📊 Podsumowanie:")
print(f"- Całkowita liczba użytkowników w bazie: {len(users)}")
@ -459,6 +499,5 @@ def main():
delete_user_via_php(u['uid'], args.drupal_path)
print(f"✅ Usunięto {len(final_candidates)} użytkowników przez delete_user.php")
if __name__ == '__main__':
main()

View File

@ -25,6 +25,11 @@
font-size: 22px;
color: #222222;
}
h2 {
font-size: 18px;
color: #222222;
margin-top: 25px;
}
p {
font-size: 16px;
line-height: 1.6;
@ -42,6 +47,28 @@
margin: 20px 0;
font-weight: bold;
}
.details {
background-color: #f8f9fa;
padding: 12px;
border-left: 4px solid #3498db;
margin: 20px 0;
}
.details-item {
margin-bottom: 8px;
}
.benefits {
background-color: #e8f4fd;
padding: 12px;
border-left: 4px solid #2980b9;
margin: 20px 0;
}
.benefits ul {
padding-left: 20px;
margin: 10px 0;
}
.benefits li {
margin-bottom: 8px;
}
</style>
</head>
<body>
@ -52,14 +79,26 @@
Kontaktujemy się z Tobą w sprawie Twojego konta w serwisie <strong>unitraklub.pl</strong>.
</p>
<p>
Zarejestrowałeś/aś konto dnia <strong>@rejestracja</strong>. Niestety, od momentu rejestracji nie wykazało ono żadnej aktywności.
</p>
<div class="details">
<div class="details-item"><strong>Data rejestracji:</strong> @rejestracja</div>
<div class="details-item"><strong>Ostatnie logowanie:</strong> @ostatnie_logowanie</div>
</div>
<div class="highlight">
Jeśli nie zalogujesz się w najbliższym czasie, konto zostanie zablokowane i następnie usunięte.
</div>
<h2>Dlaczego warto zachować obecne konto?</h2>
<div class="benefits">
<p>Od pewnego czasu wprowadziliśmy nowe zasady dostępu do cennych zasobów:</p>
<ul>
<li>Aby korzystać z działu <strong>download</strong>, gdzie znajdziesz schematy, instrukcje serwisowe i inne cenne materiały, wymagany jest minimalny staż w serwisie</li>
<li>Twoje obecne konto ma już historię, którą stracisz jeśli zostanie usunięte</li>
<li>Długoletnie konta mają pierwszeństwo dostępu do specjalnych zasobów</li>
</ul>
</div>
<p>
Jeśli nadal chcesz korzystać z serwisu, wystarczy się zalogować to wszystko!
</p>