Some checks are pending
NordaBiz Tests / Unit & Integration Tests (push) Waiting to run
NordaBiz Tests / E2E Tests (Playwright) (push) Blocked by required conditions
NordaBiz Tests / Smoke Tests (Production) (push) Blocked by required conditions
NordaBiz Tests / Send Failure Notification (push) Blocked by required conditions
- Replace textarea with Quill editor in new/edit classified forms - Sanitize HTML with sanitize_html() on save (XSS prevention) - Render HTML in classified detail view, strip tags in list view - New script: classified_expiry_notifier.py sends email 3 days before expiry with link to extend. Run daily via cron at 8:00. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
110 lines
3.9 KiB
Python
110 lines
3.9 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Classified Expiry Notifier
|
|
==========================
|
|
|
|
Sends email notifications to classified authors 3 days before expiry.
|
|
Run daily via cron: 0 8 * * * cd /var/www/nordabiznes && venv/bin/python3 scripts/classified_expiry_notifier.py
|
|
|
|
Author: Maciej Pienczyn, InPi sp. z o.o.
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
|
|
# Add project root to path
|
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
|
|
from datetime import datetime, timedelta
|
|
from database import SessionLocal, Classified, User
|
|
|
|
|
|
def main():
|
|
# Initialize email service
|
|
from dotenv import load_dotenv
|
|
load_dotenv()
|
|
|
|
from email_service import init_email_service, send_email
|
|
init_email_service()
|
|
|
|
db = SessionLocal()
|
|
try:
|
|
# Find classifieds expiring in exactly 3 days
|
|
target_date = datetime.now().date() + timedelta(days=3)
|
|
next_day = target_date + timedelta(days=1)
|
|
|
|
expiring = db.query(Classified).filter(
|
|
Classified.is_active == True,
|
|
Classified.expires_at >= datetime.combine(target_date, datetime.min.time()),
|
|
Classified.expires_at < datetime.combine(next_day, datetime.min.time())
|
|
).all()
|
|
|
|
if not expiring:
|
|
print(f"[{datetime.now()}] Brak ogłoszeń wygasających {target_date}")
|
|
return
|
|
|
|
print(f"[{datetime.now()}] Znaleziono {len(expiring)} ogłoszeń wygasających {target_date}")
|
|
|
|
for classified in expiring:
|
|
author = db.query(User).filter(User.id == classified.author_id).first()
|
|
if not author or not author.email:
|
|
continue
|
|
|
|
author_name = author.name or author.email.split('@')[0]
|
|
expire_date = classified.expires_at.strftime('%d.%m.%Y')
|
|
extend_url = f"https://nordabiznes.pl/tablica/{classified.id}"
|
|
|
|
subject = f"Twoje ogłoszenie wygasa za 3 dni: {classified.title}"
|
|
|
|
body_text = f"""Cześć {author_name},
|
|
|
|
Twoje ogłoszenie na portalu NordaBiznes.pl wygasa {expire_date}:
|
|
|
|
„{classified.title}"
|
|
|
|
Jeśli chcesz je przedłużyć o kolejne 30 dni, wejdź na stronę ogłoszenia i kliknij przycisk „Przedłuż o 30 dni":
|
|
{extend_url}
|
|
|
|
Jeśli ogłoszenie jest już nieaktualne, nie musisz nic robić — wygaśnie automatycznie.
|
|
|
|
Pozdrawiam,
|
|
Portal NordaBiznes.pl"""
|
|
|
|
body_html = f"""
|
|
<div style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; max-width: 600px; margin: 0 auto;">
|
|
<p>Cześć {author_name},</p>
|
|
<p>Twoje ogłoszenie na portalu NordaBiznes.pl wygasa <strong>{expire_date}</strong>:</p>
|
|
<div style="background: #f8fafc; border-left: 4px solid #2E4872; padding: 16px; margin: 16px 0; border-radius: 4px;">
|
|
<strong>{classified.title}</strong>
|
|
</div>
|
|
<p>Jeśli chcesz je przedłużyć o kolejne 30 dni, kliknij poniższy przycisk:</p>
|
|
<p style="text-align: center; margin: 24px 0;">
|
|
<a href="{extend_url}" style="background: #2E4872; color: white; padding: 12px 24px; border-radius: 6px; text-decoration: none; font-weight: 600;">
|
|
Przedłuż ogłoszenie
|
|
</a>
|
|
</p>
|
|
<p style="color: #64748b; font-size: 14px;">Jeśli ogłoszenie jest już nieaktualne, nie musisz nic robić — wygaśnie automatycznie.</p>
|
|
<hr style="border: none; border-top: 1px solid #e2e8f0; margin: 24px 0;">
|
|
<p style="color: #94a3b8; font-size: 12px;">Portal NordaBiznes.pl — Izba Gospodarcza Norda Biznes</p>
|
|
</div>"""
|
|
|
|
success = send_email(
|
|
to=[author.email],
|
|
subject=subject,
|
|
body_text=body_text,
|
|
body_html=body_html,
|
|
email_type='classified_expiry',
|
|
user_id=author.id,
|
|
recipient_name=author_name
|
|
)
|
|
|
|
status = "wysłano" if success else "BŁĄD"
|
|
print(f" [{status}] {classified.title} -> {author.email} (wygasa {expire_date})")
|
|
|
|
finally:
|
|
db.close()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|